package net.xoetrope.xui;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.xui.evaluator.XDefaultAttributeEvaluator;
import net.xoetrope.xui.helper.XuiUtilities;
/**
* <p>A class used by XPage to implement its evaluation of paths
* </p>
* <p>Copyright (c) Xoetrope Ltd., 2002-2004</p>
* <p>License: see license.txt</p>
* $Revision: 1.1 $
*/
public class XPathEvaluator
{
/**
* The default attribute expression evaluator
*/
protected XDefaultAttributeEvaluator evaluator;
/**
* The enclosing context
*/
protected PageSupport ownerPage;
/**
* The project to which this object belongs
*/
protected XProject currentProject;
/**
* Creates a new instance of XPathEvaluator
* @param project the owner project
* @param page the enclosing context
*/
public XPathEvaluator( XProject project, PageSupport page )
{
currentProject = project;
ownerPage = page;
}
/**
* Evaluates an attribute value. An attribute may be a value or a method call.
* If brackets are part of the value it is assumed that a method call is
* intended. The method call is indicated by the '$' symbol e.g. ${myMethod()}
* @param attribValue the raw attribute value
* @return the evaluated attribute
*/
public Object evaluateAttribute( String attribValue )
{
if ( evaluator == null ) {
evaluator = ( XDefaultAttributeEvaluator )currentProject.getObject( "DefaultAttributeEvaluator" );
if ( evaluator == null ) {
evaluator = new XDefaultAttributeEvaluator( currentProject );
evaluator.setCurrentProject( currentProject );
currentProject.setObject( "DefaultAttributeEvaluator", evaluator );
}
}
return evaluator.evaluateAttribute( ownerPage, attribValue );
}
/**
* Evaluates a path (potentially) containing a method call
* @param path the raw path
* @return the evaluated path
*/
public String evaluatePath( String path )
{
try {
// path: /applicant/${userId()}/address
int pos = path.indexOf( "${" );
if ( pos < 0 )
return path;
int endPos = XuiUtilities.indexOfMatchingEnding( path, '{', '}', pos + 2 );
String evaluatedPath = null;
if ( endPos > 0 )
evaluatedPath = (String)evaluateAttribute( path.substring( pos, endPos + 1 ));
else
return path;
// evaluatedPath: u1234
if ( evaluatedPath != null ) {
String newPath = evaluatedPath + path.substring( endPos + 1 );
if ( pos > 0 )
newPath = path.substring( 0, pos ) + newPath;
// newPath: /applicant/u1234/address
return evaluatePath( newPath );
}
else
return null;
}
catch ( Exception ex ) {
if ( BuildProperties.DEBUG )
DebugLogger.logWarning( "Unable to evaluate path with the method call(?): " + path );
}
return path;
}
/**
* Remove the attribute paths from a path e.g. remove @value=ignore
* @param path the path to strip
* @return the stripped path
*/
public String stripAttributeValues( String path )
{
String newPath = path;
int pos = newPath.indexOf( '@' );
while ( pos > 0 ) {
// Check for the escape sequence
int endPos = newPath.indexOf( '[' );
if ( endPos > 0 ) {
endPos = XuiUtilities.indexOfMatchingEnding( newPath, '[', ']', endPos );
endPos++;
}
else
endPos = newPath.indexOf( '/', pos );
String remainder = newPath.substring( endPos );
newPath = newPath.substring( 0, pos ) + remainder;
pos = newPath.indexOf( '@' );
}
return newPath;
}
}