blob: c952f63aa09b40588cd9f404c40cc47febabf7db [file] [log] [blame]
package org.apache.xpath.parser;
import java.util.Hashtable;
import javax.xml.transform.SourceLocator;
import org.apache.xml.dtm.DTMFilter;
import org.apache.xml.utils.QName;
import org.apache.xpath.Expression;
import org.apache.xpath.ExpressionNode;
import org.apache.xpath.axes.UnionPathIterator;
import org.apache.xpath.axes.WalkerFactory;
import org.apache.xpath.functions.*;
import org.apache.xpath.objects.XDecimal;
import org.apache.xpath.objects.XDouble;
import org.apache.xpath.objects.XInteger;
import org.apache.xpath.operations.Variable;
import org.apache.xpath.patterns.FunctionPattern;
import org.apache.xpath.patterns.StepPattern;
import org.apache.xpath.seqctor.ExprSequence;
import org.apache.xpath.seqctor.FLWRExpr;
import org.apache.xpath.types.InstanceofExpr;
/**
* This is the most generic syntax node, which implements the JJTree
* interface "Node" methods. This class assumes that it's derived
* class is org.apache.xpath.Expression, and so does a fair amount
* of downcasting. The only reason this class exists is to separate
* out the jjXXX methods, to act as a more generic interface to
* the JavaCC/JJTree parser, and also to act as a factory class for
* the concrete implementations of the expressions.
*
* @author sboag
*/
public class SimpleNode implements Node
{
/**
* Construct a new SimpleNode.
* @see java.lang.Object#Object()
*/
public SimpleNode()
{
}
public static Hashtable m_builtInFunctions;
static {
// For user installed functions, can we really have a single static table?
// Answer: no, each parser instance will need to copy the table.
// Then the question is, can all instances of a user Function be shared among
// processes? Answer: I think that would cause regressions.
m_builtInFunctions = new Hashtable();
m_builtInFunctions.put(new QName("current"), new FuncCurrent());
m_builtInFunctions.put(
new QName("last"),
new org.apache.xpath.functions.FuncLast());
m_builtInFunctions.put(
new QName("position"),
new org.apache.xpath.functions.FuncPosition());
m_builtInFunctions.put(new QName("count"), new FuncCount());
m_builtInFunctions.put(new QName("id"), new FuncId());
m_builtInFunctions.put(
new QName("key"),
new org.apache.xalan.templates.FuncKey());
m_builtInFunctions.put(new QName("local-name"), new FuncLocalPart());
m_builtInFunctions.put(new QName("namespace-uri"), new FuncNamespace());
m_builtInFunctions.put(new QName("name"), new FuncQname());
m_builtInFunctions.put(new QName("generate-id"), new FuncGenerateId());
m_builtInFunctions.put(new QName("not"), new FuncNot());
m_builtInFunctions.put(new QName("true"), new FuncTrue());
m_builtInFunctions.put(new QName("false"), new FuncFalse());
m_builtInFunctions.put(new QName("boolean"), new FuncBoolean());
m_builtInFunctions.put(new QName("lang"), new FuncLang());
m_builtInFunctions.put(new QName("number"), new FuncNumber());
m_builtInFunctions.put(new QName("floor"), new FuncFloor());
m_builtInFunctions.put(new QName("ceiling"), new FuncCeiling());
m_builtInFunctions.put(new QName("round"), new FuncRound());
m_builtInFunctions.put(new QName("sum"), new FuncSum());
m_builtInFunctions.put(new QName("string"), new FuncString());
m_builtInFunctions.put(new QName("starts-with"), new FuncStartsWith());
m_builtInFunctions.put(new QName("contains"), new FuncContains());
m_builtInFunctions.put(
new QName("substring-before"),
new FuncSubstringBefore());
m_builtInFunctions.put(
new QName("substring-after"),
new FuncSubstringAfter());
m_builtInFunctions.put(
new QName("normalize-space"),
new FuncNormalizeSpace());
m_builtInFunctions.put(new QName("translate"), new FuncTranslate());
m_builtInFunctions.put(new QName("concat"), new FuncConcat());
m_builtInFunctions.put(
new QName("system-property"),
new FuncSystemProperty());
m_builtInFunctions.put(
new QName("function-available"),
new FuncExtFunctionAvailable());
m_builtInFunctions.put(
new QName("element-available"),
new FuncExtElementAvailable());
m_builtInFunctions.put(new QName("substring"), new FuncSubstring());
m_builtInFunctions.put(new QName("string-length"), new FuncStringLength());
m_builtInFunctions.put(
new QName("unparsed-entity-uri"),
new FuncUnparsedEntityURI());
m_builtInFunctions.put(
new QName("document-location"),
new FuncDoclocation());
// Proprietary
// XPATH2 experimental
m_builtInFunctions.put(
new QName("data"),
new FuncData());
m_builtInFunctions.put(
new QName("current-dateTime"),
new FuncCurrentDateTime());
m_builtInFunctions.put(
new QName("current-date"),
new FuncCurrentDate());
m_builtInFunctions.put(
new QName("dateTime"),
new FuncDateTime());
m_builtInFunctions.put(
new QName("date"),
new FuncDate());
m_builtInFunctions.put(
new QName("duration"),
new FuncDuration());
m_builtInFunctions.put(
new QName("time"),
new FuncTime());
m_builtInFunctions.put(
new QName("yearMonthDuration"),
new FuncYMDuration());
m_builtInFunctions.put(
new QName("yearMonthDuration-from-months"),
new FuncYMDurationFromMonths());
m_builtInFunctions.put(
new QName("dayTimeDuration"),
new FuncDTDuration());
m_builtInFunctions.put(
new QName("dayTimeDuration-from-seconds"),
new FuncDTDurationFromSecs());
m_builtInFunctions.put(
new QName("add-dayTimeDuration"),
new FuncAddDayTimeDuration());
m_builtInFunctions.put(
new QName("subtract-dayTimeDuration"),
new FuncSubDayTimeDuration());
m_builtInFunctions.put(
new QName("multiply-dayTimeDuration"),
new FuncMultDayTimeDuration());
m_builtInFunctions.put(
new QName("divide-dayTimeDuration"),
new FuncDivDayTimeDuration());
m_builtInFunctions.put(
new QName("add-yearMonthDuration"),
new FuncAddYearMonthDuration());
m_builtInFunctions.put(
new QName("subtract-yearMonthDuration"),
new FuncSubYearMonthDuration());
m_builtInFunctions.put(
new QName("multiply-yearMonthDuration"),
new FuncMultYearMonthDuration());
m_builtInFunctions.put(
new QName("divide-yearMonthDuration"),
new FuncDivYearMonthDuration());
m_builtInFunctions.put(
new QName("get-yearMonthDuration"),
new FuncGetYMDuration());
m_builtInFunctions.put(
new QName("get-dayTimeDuration"),
new FuncGetDTDuration());
m_builtInFunctions.put(
new QName("add-yearMonthDurationToDateTime"),
new FuncAddYMDurationToDT());
m_builtInFunctions.put(
new QName("subtract-yearMonthDurationFromDateTime"),
new FuncSubtractYMDurationFromDT());
m_builtInFunctions.put(
new QName("add-yearMonthDurationToDate"),
new FuncAddYMDurationToDate());
m_builtInFunctions.put(
new QName("subtract-yearMonthDurationFromDate"),
new FuncSubtractYMDurationFromDate());
m_builtInFunctions.put(
new QName("add-dayTimeDurationToDateTime"),
new FuncAddDTDurationToDT());
m_builtInFunctions.put(
new QName("subtract-dayTimeDurationFromDateTime"),
new FuncSubtractDTDurationFromDT());
m_builtInFunctions.put(
new QName("add-dayTimeDurationToDate"),
new FuncAddDTDurationToDate());
m_builtInFunctions.put(
new QName("add-dayTimeDurationToTime"),
new FuncAddDTDurationToTime());
m_builtInFunctions.put(
new QName("subtract-dayTimeDurationFromDate"),
new FuncSubtractDTDurationFromDate());
m_builtInFunctions.put(
new QName("subtract-dayTimeDurationFromTime"),
new FuncSubtractDTDurationFromTime());
m_builtInFunctions.put(
new QName("add-days"),
new FuncAddDays());
m_builtInFunctions.put(
new QName("gYearMonth"),
new FuncGYearMonth());
m_builtInFunctions.put(
new QName("gYear"),
new FuncGYear());
m_builtInFunctions.put(
new QName("gMonth"),
new FuncGMonth());
m_builtInFunctions.put(
new QName("gMonthDay"),
new FuncGMonthDay());
m_builtInFunctions.put(
new QName("gDay"),
new FuncGDay());
m_builtInFunctions.put(
new QName("get-day-from-date"),
new FuncGetDFromDate());
m_builtInFunctions.put(
new QName("get-day-from-dateTime"),
new FuncGetDFromDT());
m_builtInFunctions.put(
new QName("get-days-from-dayTimeDuration"),
new FuncGetDFromDTDuration());
m_builtInFunctions.put(
new QName("get-hours-from-dateTime"),
new FuncGetHFromDT());
m_builtInFunctions.put(
new QName("get-hours-from-dayTimeDuration"),
new FuncGetHFromDTDuration());
m_builtInFunctions.put(
new QName("get-hours-from-time"),
new FuncGetHFromTime());
m_builtInFunctions.put(
new QName("get-month-from-date"),
new FuncGetMFromDate());
m_builtInFunctions.put(
new QName("get-month-from-dateTime"),
new FuncGetMFromDT());
m_builtInFunctions.put(
new QName("get-months-from-yearMonthDuration"),
new FuncGetMFromYMDuration());
m_builtInFunctions.put(
new QName("get-minutes-from-dateTime"),
new FuncGetMnFromDT());
m_builtInFunctions.put(
new QName("get-minutes-from-dayTimeDuration"),
new FuncGetMnFromDTDuration());
m_builtInFunctions.put(
new QName("get-minutes-from-time"),
new FuncGetMnFromTime());
m_builtInFunctions.put(
new QName("get-seconds-from-dateTime"),
new FuncGetSFromDT());
m_builtInFunctions.put(
new QName("get-seconds-from-dayTimeDuration"),
new FuncGetSFromDTDuration());
m_builtInFunctions.put(
new QName("get-seconds-from-time"),
new FuncGetSFromTime());
m_builtInFunctions.put(
new QName("get-timezone-from-datetime"),
new FuncGetTZFromDT());
m_builtInFunctions.put(
new QName("get-timezone-from-date"),
new FuncGetTZFromDate());
m_builtInFunctions.put(
new QName("get-timezone-from-time"),
new FuncGetTZFromTime());
m_builtInFunctions.put(
new QName("get-year-from-date"),
new FuncGetYFromDate());
m_builtInFunctions.put(
new QName("get-year-from-dateTime"),
new FuncGetYFromDT());
m_builtInFunctions.put(
new QName("get-years-from-yearMonthDuration"),
new FuncGetYFromYMDuration());
m_builtInFunctions.put(
new QName("duration-equal"),
new FuncDurationEqual());
m_builtInFunctions.put(
new QName("yearMonthDuration-equal"),
new FuncYMDurationEqual());
m_builtInFunctions.put(
new QName("yearMonthDuration-greater-than"),
new FuncYMDurationGT());
m_builtInFunctions.put(
new QName("yearMonthDuration-less-than"),
new FuncYMDurationLT());
m_builtInFunctions.put(
new QName("dayTimeDuration-equal"),
new FuncDTDurationEqual());
m_builtInFunctions.put(
new QName("dayTimeDuration-greater-than"),
new FuncDTDurationGT());
m_builtInFunctions.put(
new QName("dayTimeDuration-less-than"),
new FuncDTDurationLT());
m_builtInFunctions.put(
new QName("dateTime-equal"),
new FuncDateTimeEq());
m_builtInFunctions.put(
new QName("dateTime-less-than"),
new FuncDateTimeLT());
m_builtInFunctions.put(
new QName("dateTime-greater-than"),
new FuncDateTimeGT());
}
/**
* Factory method for creating parse tree nodes, which is called by
* the JJTree created parser.
* @param p The JJTree created XPath parser.
* @param id The ID of the node.
* @return Node The new node, which may not be null.
*/
public static Node jjtCreate(XPath p, int id)
{
SimpleNode newNode = null;
// To be done: If function on stack, assume param.
switch (id)
{
case XPathTreeConstants.JJTXPATH2 :
// When I try to use #void to cancel out this node,
// I get an error. So I guess
// the top of the tree can't be void. So I create a dummy
// node. This makes the called have to call
// ((SimpleNode)tree.jjtGetChild(0)) to get the real root.
newNode = new RootOfRoot(p);
break;
// === MATCH EXPRESSIONS ===
case XPathTreeConstants.JJTMATCHPATTERN :
// See comment above.
// TBD: If the pattern is a MatchPattern, then RootOfRoot should
// rebuild the children according to the structure needed
// by the patterns package.
newNode = new RootOfRootPattern(p);
break;
case XPathTreeConstants.JJTPATTERN :
// This should be optimized away if there is only one pattern
newNode = new org.apache.xpath.patterns.UnionPattern();
break;
case XPathTreeConstants.JJTPATHPATTERN :
// This is a temporary node, for construction purposes only,
// Since the patterns package constructs the StepPatterns as
// a linked list.
newNode = new Pattern(p);
break;
case XPathTreeConstants.JJTPATTERNSTEP :
{
StepPattern spat = new StepPattern();
// At this point, the PatternAxis, NodeTest, and Predicates
// should be already on the stack?
newNode = spat;
}
break;
case XPathTreeConstants.JJTROOT :
{
if (!p.m_isMatchPattern || p.m_predLevel > 0)
{
newNode = new StepExpr(p);
PatternAxis patAxis =
new PatternAxis(org.apache.xml.dtm.Axis.ROOT, p);
patAxis.m_value = "root::"; // for diagnostics
NodeTest nt =
new NodeTest(
org.apache.xml.dtm.DTMFilter.SHOW_DOCUMENT
| org.apache.xml.dtm.DTMFilter.SHOW_DOCUMENT_FRAGMENT,
p);
Predicates preds = new Predicates(p);
newNode.jjtAddChild(patAxis, 0);
newNode.jjtAddChild(nt, 1);
newNode.jjtAddChild(preds, 2);
}
else
{
StepPattern spat = new StepPattern();
spat.setWhatToShow(
DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT);
spat.setAxis(org.apache.xml.dtm.Axis.PARENT);
// spat.setT(org.apache.xpath.patterns.StepPattern.PSEUDONAME_ROOT);
newNode = spat;
}
}
break;
case XPathTreeConstants.JJTROOTDESCENDANTS :
{
if (!p.m_isMatchPattern || p.m_predLevel > 0)
{
newNode = new StepExpr(p);
PatternAxis patAxis =
new PatternAxis(
org.apache.xml.dtm.Axis.DESCENDANTSORSELFFROMROOT,
p);
patAxis.m_value = "descendants-from-root::"; // for diagnostics
NodeTest nt =
new NodeTest(org.apache.xml.dtm.DTMFilter.SHOW_ALL, p);
nt.setTotallyWild(true);
// nt.setLocalName(org.apache.xpath.patterns.StepPattern.PSEUDONAME_ROOT);
Predicates preds = new Predicates(p);
newNode.jjtAddChild(patAxis, 0);
newNode.jjtAddChild(nt, 1);
newNode.jjtAddChild(preds, 2);
}
else
{
// see comment for JJTROOT.
StepPattern spat = new StepPattern();
spat.setWhatToShow(
DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT);
spat.setAxis(org.apache.xml.dtm.Axis.ANCESTOR);
newNode = spat;
}
}
break;
case XPathTreeConstants.JJTSLASH :
newNode = new SlashOrSlashSlash(false, p);
break;
case XPathTreeConstants.JJTSLASHSLASH :
newNode = new SlashOrSlashSlash(true, p);
break;
// === NODE TESTS ===
case XPathTreeConstants.JJTNODETEST :
newNode = new NodeTest(p);
break;
case XPathTreeConstants.JJTNAMETEST :
newNode = new NameTest(p);
break;
case XPathTreeConstants.JJTQNAME :
newNode = new org.apache.xpath.parser.QName(p);
break;
case XPathTreeConstants.JJTSTAR : // Wildcard
newNode = new Star(p);
break;
case XPathTreeConstants.JJTNCNAMECOLONSTAR :
newNode = new NCNameColonStar(p);
break;
case XPathTreeConstants.JJTSTARCOLONNCNAME :
newNode = new StarColonNCName(p);
break;
case XPathTreeConstants.JJTKINDTEST :
newNode = new KindTest(p);
break;
case XPathTreeConstants.JJTPROCESSINGINSTRUCTIONTEST :
newNode = new ProcessingInstructionTest(p);
break;
case XPathTreeConstants.JJTCOMMENTTEST :
newNode = new CommentTest(p);
break;
case XPathTreeConstants.JJTTEXTTEST :
newNode = new TextTest(p);
break;
case XPathTreeConstants.JJTANYKINDTEST :
newNode = new AnyKindTest(p);
break;
case XPathTreeConstants.JJTLBRACK :
newNode = new LbrackOrRbrack(p);
p.m_predLevel++;
break;
case XPathTreeConstants.JJTRBRACK :
newNode = new LbrackOrRbrack(p);
p.m_predLevel--;
break;
case XPathTreeConstants.JJTPREDICATES :
newNode = new Predicates(p);
break;
// === AXES, ETC. ===
case XPathTreeConstants.JJTAXISDESCENDANT :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.DESCENDANT, p);
break;
case XPathTreeConstants.JJTAXISSELF :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.SELF, p);
break;
case XPathTreeConstants.JJTAXISDESCENDANTORSELF :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.DESCENDANTORSELF, p);
break;
case XPathTreeConstants.JJTAXISFOLLOWINGSIBLING :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.FOLLOWINGSIBLING, p);
break;
case XPathTreeConstants.JJTAXISFOLLOWING :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.FOLLOWING, p);
break;
case XPathTreeConstants.JJTAXISNAMESPACE :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.NAMESPACE, p);
break;
case XPathTreeConstants.JJTAXISPARENT :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.PARENT, p);
break;
case XPathTreeConstants.JJTAXISANCESTOR :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.ANCESTOR, p);
break;
case XPathTreeConstants.JJTAXISPRECEDINGSIBLING :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.PRECEDINGSIBLING, p);
break;
case XPathTreeConstants.JJTAXISPRECEDING :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.PRECEDING, p);
break;
case XPathTreeConstants.JJTAXISANCESTORORSELF :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.ANCESTORORSELF, p);
break;
case XPathTreeConstants.JJTAXISCHILD :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.CHILD, p);
break;
case XPathTreeConstants.JJTAXISATTRIBUTE :
case XPathTreeConstants.JJTAT :
newNode = new PatternAxis(org.apache.xml.dtm.Axis.ATTRIBUTE, p);
break;
case XPathTreeConstants.JJTABBREVIATEDFORWARDSTEP :
{
PatternAxis patAxis =
new PatternAxis(org.apache.xml.dtm.Axis.CHILD, p);
patAxis.m_value = "child::"; // for diagnostics
newNode = patAxis;
}
break;
case XPathTreeConstants.JJTDOT :
{
PatternAxis patAxis =
new PatternAxis(org.apache.xml.dtm.Axis.SELF, p);
patAxis.m_value = "self::"; // for diagnostics
newNode = patAxis;
NodeTest nt = new NodeTest(org.apache.xml.dtm.DTMFilter.SHOW_ALL, p);
newNode.jjtAddChild(nt, 0);
}
break;
case XPathTreeConstants.JJTDOTDOT :
{
PatternAxis patAxis =
new PatternAxis(org.apache.xml.dtm.Axis.PARENT, p);
patAxis.m_value = "parent::"; // for diagnostics
newNode = patAxis;
NodeTest nt = new NodeTest(org.apache.xml.dtm.DTMFilter.SHOW_ALL, p);
newNode.jjtAddChild(nt, 0);
}
break;
// === PATH EXPRESSIONS ===
case XPathTreeConstants.JJTPATHEXPR :
newNode = new PathExpr(p);
break;
case XPathTreeConstants.JJTSTEPEXPR :
newNode = new StepExpr(p);
break;
// === SEQUENCE UNIONS AND INTERSECTIONS ===
case XPathTreeConstants.JJTUNIONEXPR :
newNode = new UnionPathIterator();
break;
case XPathTreeConstants.JJTINTERSECTEXCEPTEXPR :
newNode = new NonExecutableExpression(p, "JJTUNIONEXPR");
break;
// case XPathTreeConstants.JJTUNION:
// newNode = new SimpleNode();
// break;
// case XPathTreeConstants.JJTVBAR:
// newNode = new SimpleNode();
// break;
// case XPathTreeConstants.JJTRELATIVEPATHPATTERN:
// newNode = new SimpleNode();
// break;
// === FUNCTIONS ===
case XPathTreeConstants.JJTIDKEYPATTERN :
{
FunctionPattern fpat = new FunctionPattern();
p.m_matchFunc = fpat; // short lived.
newNode = fpat;
}
break;
case XPathTreeConstants.JJTFUNCTIONCALL :
{
FunctionPattern fpat = new TempFunctionHolder();
p.m_matchFunc = fpat; // short lived.
newNode = fpat;
}
break;
case XPathTreeConstants.JJTQNAMELPAR :
try
{
org.apache.xpath.parser.QName qname =
new org.apache.xpath.parser.QName(p);
if (null != p.m_matchFunc)
{
qname.processToken(p.getToken(0));
QName funcName = qname.getQName();
String ns = funcName.getNamespaceURI();
if (null != ns && ns.length() > 0)
{
String uniqueKey =
String.valueOf(
((SourceLocator) p.m_prefixResolver).getLineNumber())
+ String.valueOf(funcName.hashCode())
+ String.valueOf(System.currentTimeMillis());
Function extension =
new FuncExtFunction(ns, funcName.getLocalPart(), uniqueKey);
p.m_matchFunc.setFunctionExpression(extension);
p.m_matchFunc = null;
}
else
{
Expression exp = (Expression) m_builtInFunctions.get(funcName);
if (null != exp)
{
exp = (Expression) exp.getClass().newInstance();
p.m_matchFunc.setFunctionExpression(exp);
p.m_matchFunc = null;
}
else
{
// TBD: a proper error throw. -sb
throw new RuntimeException(
"Function not found: " + funcName + "!");
}
}
}
newNode = qname;
}
catch (InstantiationException iae)
{
throw new org.apache.xml.utils.WrappedRuntimeException(iae);
}
catch (IllegalAccessException iae)
{
throw new org.apache.xml.utils.WrappedRuntimeException(iae);
}
break;
// === BINARY OPERATORS ===
case XPathTreeConstants.JJTOREXPR :
newNode = new org.apache.xpath.operations.Or();
break;
case XPathTreeConstants.JJTANDEXPR :
newNode = new org.apache.xpath.operations.And();
break;
case XPathTreeConstants.JJTCOMPARISONEXPR :
{
Token operator = (Token) p.binaryTokenStack.peek();
switch (operator.kind)
{
case XPathConstants.Equals :
newNode = new org.apache.xpath.operations.Equals();
break;
case XPathConstants.NotEquals :
newNode = new org.apache.xpath.operations.NotEquals();
;
break;
case XPathConstants.Lt :
newNode = new org.apache.xpath.operations.Lt();
break;
case XPathConstants.LtEquals :
newNode = new org.apache.xpath.operations.Lte();
break;
case XPathConstants.Gt :
newNode = new org.apache.xpath.operations.Gt();
break;
case XPathConstants.GtEquals :
newNode = new org.apache.xpath.operations.Gte();
break;
case XPathConstants.FortranEq :
newNode = new org.apache.xpath.operations.FortranEq();
break;
case XPathConstants.FortranNe :
newNode = new org.apache.xpath.operations.FortranNe();
break;
case XPathConstants.FortranLt :
newNode = new org.apache.xpath.operations.FortranLt();
break;
case XPathConstants.FortranLe :
newNode = new org.apache.xpath.operations.FortranLe();
break;
case XPathConstants.FortranGt :
newNode = new org.apache.xpath.operations.FortranGt();
break;
case XPathConstants.FortranGe :
newNode = new org.apache.xpath.operations.FortranGe();
break;
case XPathConstants.Is :
newNode = new org.apache.xpath.operations.Is();
break;
case XPathConstants.IsNot :
newNode = new org.apache.xpath.operations.IsNot();
break;
case XPathConstants.LtLt :
newNode = new org.apache.xpath.operations.LtLt();
break;
case XPathConstants.GtGt :
newNode = new org.apache.xpath.operations.GtGt();
break;
case XPathConstants.Precedes :
newNode = new org.apache.xpath.operations.Precedes();
break;
case XPathConstants.Follows :
newNode = new org.apache.xpath.operations.Follows();
break;
}
}
break;
case XPathTreeConstants.JJTRANGEEXPR :
newNode = new org.apache.xpath.seqctor.RangeExpr();
break;
case XPathTreeConstants.JJTADDITIVEEXPR :
{
Token operator = (Token) p.binaryTokenStack.peek();
switch (operator.kind)
{
case XPathConstants.Plus :
newNode = new org.apache.xpath.operations.Add();
break;
case XPathConstants.Minus :
newNode = new org.apache.xpath.operations.Subtract();
;
break;
}
}
break;
case XPathTreeConstants.JJTMULTIPLICATIVEEXPR :
{
Token operator = (Token) p.binaryTokenStack.peek();
switch (operator.kind)
{
case XPathConstants.Multiply :
newNode = new org.apache.xpath.operations.Mult();
break;
case XPathConstants.Div :
newNode = new org.apache.xpath.operations.Div();
;
break;
case XPathConstants.Idiv :
newNode = new org.apache.xpath.operations.Idiv();
break;
case XPathConstants.Mod :
newNode = new org.apache.xpath.operations.Mod();
;
break;
}
}
break;
// === UNARY OPERATORS ===
case XPathTreeConstants.JJTUNARYEXPR :
newNode = new UnaryExpr(p);
break;
case XPathTreeConstants.JJTPLUS :
newNode = new org.apache.xpath.operations.Pos();
break;
case XPathTreeConstants.JJTMINUS :
newNode = new org.apache.xpath.operations.Neg();
break;
// === VARIABLES ===
case XPathTreeConstants.JJTVARNAME :
{
// We'll have to check to make sure the node is
// really on the stack.
Variable var = new Variable();
Token varToken = p.getToken(0);
String varName = varToken.image;
QName varQName = new QName(varName, p.m_prefixResolver);
var.setQName(varQName);
newNode = var;
}
break;
// === LITERALS ===
case XPathTreeConstants.JJTSTRINGLITERAL :
newNode = new org.apache.xpath.objects.XString();
break;
case XPathTreeConstants.JJTINTEGERLITERAL :
if(p.getVersion() >= 2.0)
newNode = new XInteger();
else
newNode = new XDouble();
break;
case XPathTreeConstants.JJTDECIMALLITERAL :
newNode = new XDecimal();
break;
case XPathTreeConstants.JJTDOUBLELITERAL :
newNode = new XDouble();
break;
// === SEQUENCE CONSTRUCTION ===
case XPathTreeConstants.JJTEXPRSEQUENCE :
newNode = new ExprSequence();
break;
// === QUANTIFIED EXPRESSIONS ===
case XPathTreeConstants.JJTQUANTIFIEDEXPR :
newNode = new QuantifiedExpr(p);
break;
case XPathTreeConstants.JJTSOME :
newNode = new org.apache.xpath.quantified.Some();
break;
case XPathTreeConstants.JJTEVERY :
newNode = new org.apache.xpath.quantified.Every();
break;
case XPathTreeConstants.JJTSATISFIES :
newNode = new org.apache.xpath.quantified.Satisfies();
break;
case XPathTreeConstants.JJTIN : // Both for ForClause and Quantified.
newNode = new In(p);
break;
// === CONDITIONAL EXPRESSIONS ===
case XPathTreeConstants.JJTIFEXPR :
newNode = new IfExpr(p);
break;
case XPathTreeConstants.JJTIFLPAR :
newNode = new org.apache.xpath.conditional.If();
break;
case XPathTreeConstants.JJTTHEN :
newNode = new org.apache.xpath.conditional.Then();
break;
case XPathTreeConstants.JJTELSE :
newNode = new org.apache.xpath.conditional.Else();
break;
// === ITTERATION ===
case XPathTreeConstants.JJTFLWREXPR :
newNode = new FLWRExpr();
break;
case XPathTreeConstants.JJTFORCLAUSE :
newNode = new org.apache.xpath.parser.ForClause(p);
break;
case XPathTreeConstants.JJTRETURN :
newNode = new org.apache.xpath.parser.Return(p);
break;
// === TYPE HANDLING ===
case XPathTreeConstants.JJTINSTANCEOFEXPR :
newNode = new InstanceofExpr();
break;
case XPathTreeConstants.JJTINSTANCEOF :
newNode = new Instanceof(p);
break;
case XPathTreeConstants.JJTVALIDATEEXPR :
newNode = new NonExecutableExpression(p, "JJTVALIDATEEXPR");
break;
case XPathTreeConstants.JJTVALIDATE :
newNode = new NonExecutableExpression(p, "JJTVALIDATE");
break;
case XPathTreeConstants.JJTLBRACE :
newNode = new NonExecutableExpression(p, "JJTLBRACE");
break;
case XPathTreeConstants.JJTRBRACE :
newNode = new NonExecutableExpression(p, "JJTRBRACE");
break;
case XPathTreeConstants.JJTCASTEXPR :
newNode = new NonExecutableExpression(p, "JJTCASTEXPR");
break;
case XPathTreeConstants.JJTCASTAS :
newNode = new NonExecutableExpression(p, "JJTCASTAS");
break;
case XPathTreeConstants.JJTTREATAS :
newNode = new NonExecutableExpression(p, "JJTTREATAS");
break;
case XPathTreeConstants.JJTSCHEMACONTEXT :
newNode = new SchemaContext(p, "JJTSCHEMACONTEXT");
break;
case XPathTreeConstants.JJTSCHEMAGLOBALCONTEXT :
newNode = new SchemaGlobalContext(p, "JJTSCHEMAGLOBALCONTEXT");
break;
case XPathTreeConstants.JJTTYPE :
newNode = new NonExecutableExpression(p, "JJTTYPE");
break;
case XPathTreeConstants.JJTSCHEMACONTEXTSTEP :
newNode = new SchemaContextStep(p);
break;
case XPathTreeConstants.JJTSEQUENCETYPE :
newNode = new SequenceType(p, "JJTSEQUENCETYPE");
break;
case XPathTreeConstants.JJTEMPTY :
newNode = new Empty(p, "JJTEMPTY");
break;
case XPathTreeConstants.JJTITEMTYPE :
newNode = new ItemType(p, "JJTITEMTYPE");
break;
case XPathTreeConstants.JJTELEMENTTYPE :
newNode = new NodeTestType(p, DTMFilter.SHOW_ELEMENT);
break;
case XPathTreeConstants.JJTATTRIBUTETYPE :
newNode = new NodeTestType(p, DTMFilter.SHOW_ATTRIBUTE);
break;
case XPathTreeConstants.JJTNODE :
newNode = new NodeTestType(p, DTMFilter.SHOW_ALL);
break;
case XPathTreeConstants.JJTPROCESSINGINSTRUCTION :
newNode = new NodeTestType(p, DTMFilter.SHOW_PROCESSING_INSTRUCTION);
break;
case XPathTreeConstants.JJTCOMMENT :
newNode = new NodeTestType(p, DTMFilter.SHOW_COMMENT);
break;
case XPathTreeConstants.JJTTEXT :
newNode = new NodeTestType(p, DTMFilter.SHOW_TEXT);
break;
case XPathTreeConstants.JJTDOCUMENT :
newNode = new NodeTestType(p, DTMFilter.SHOW_DOCUMENT);
break;
case XPathTreeConstants.JJTITEM :
newNode = new NodeTestType(p, DTMFilter.SHOW_ITEM);
break;
case XPathTreeConstants.JJTUNTYPED :
newNode = new NodeTestType(p, DTMFilter.SHOW_UNTYPED);
break;
// case XPathTreeConstants.JJTATOMICVALUE :
// newNode = new AtomicType(p);
// break;
case XPathTreeConstants.JJTELEMORATTRTYPE :
newNode = new ElemOrAttrType(p, "JJTELEMORATTRTYPE");
break;
case XPathTreeConstants.JJTSCHEMATYPE :
newNode = new SchemaType(p);
break;
case XPathTreeConstants.JJTOFTYPE :
newNode = new OfType(p, "JJTOFTYPE");
break;
case XPathTreeConstants.JJTATOMICTYPE :
newNode = new AtomicType(p, "JJTATOMICTYPE");
break;
case XPathTreeConstants.JJTOCCURRENCEINDICATOR :
newNode = new OccurrenceIndicator(p, "JJTOCCURRENCEINDICATOR");
break;
case XPathTreeConstants.JJTMULTIPLY :
// Leave as NEE
newNode = new NonExecutableExpression(p, "JJTMULTIPLY");
break;
case XPathTreeConstants.JJTQMARK :
// Leave as NEE
newNode = new NonExecutableExpression(p, "JJTQMARK");
break;
default :
newNode = new NonExecutableExpression(p, "(case default: " + id + ")");
}
return newNode;
}
/**
* Tell if this node is part of a PathExpr chain. For instance:
* <pre>
* |UnaryExpr
* | PathExpr
* | StepExpr
* | AxisChild child::
* | NodeTest
* | NameTest
* | QName foo
* | Predicates *
* </pre><br/>
* In this example, UnaryExpr, PathExpr, and StepExpr should all return true.
*/
public boolean isPathExpr()
{
return false;
}
/**
* Tell if this node should have it's PathExpr ancestory reduced.
*/
public boolean isPathExprReduced()
{
return false;
}
/**
* Tell if this node should have it's parent reduced.
*/
public boolean shouldReduceIfOneChild()
{
return false;
}
/**
* This function checks the integrity of the tree, after it has been fully built and
* is ready for execution.
* @return boolean true if the tree has integrity, false otherwise.
*/
public boolean checkTreeIntegrity()
{
return checkTreeIntegrity(0, 0, true);
}
/**
* Tell the user there is a problem with the tree.
* @param s The string to show the user.
* @return boolean false always.
*/
protected boolean flagProblem(String s)
{
// System.err.println("checkTreeIntegrity failed: " + s);
throw new RuntimeException("checkTreeIntegrity failed: " + s);
// return false;
}
/**
* This function checks the integrity of the tree, after it has been fully built and
* is ready for execution. Derived classes can overload this function to check
* their own assumptions.
*
* @param levelCount The current tree level.
* @param childNumber The current child index.
* @param parentOK The parent's integrity flag.
* @return boolean true the node does not have integrity, otherwise
* return the parentOK value.
*/
public boolean checkTreeIntegrity(
int levelCount,
int childNumber,
boolean parentOK)
{
boolean isOK;
// try
{
isOK = parentOK;
if (levelCount == 0)
{
if (!(null == jjtGetParent()))
isOK =
flagProblem("The root node has a parent?? parent: " + jjtGetParent());
}
else
{
Node parent = jjtGetParent();
if (null == parent)
isOK =
flagProblem(
toString() + " has a null parent and is not the root node! "+
this.getClass().getName());
else
{
if ( (childNumber >= parent.jjtGetNumChildren())
|| (parent.jjtGetChild(childNumber) != this))
{
isOK =
flagProblem(
toString() + " has a parent that it is not a child of!");
}
}
}
if (this instanceof NonExecutableExpression)
isOK = flagProblem(toString() + " is a NonExecutableExpression!");
int childCount = jjtGetNumChildren();
for (int i = 0; i < childCount; i++)
{
Node child = jjtGetChild(i);
if(null == child)
isOK = flagProblem(toString() + " has a null child!");
else
isOK = ((SimpleNode) child).checkTreeIntegrity(levelCount + 1, i, isOK);
}
}
// catch (RuntimeException e)
// {
// isOK = flagProblem(toString() + e.getMessage());
// e.printStackTrace();
// }
return isOK;
}
/**
* This ugly little function strips the extranious PathExpr/RelativePathExpr/StepExpr
* from XObjects, recursively calling the node's child at index zero, if
* the node is a path expression. It should be called from
* jjtAddChild functions.
*
* @param n The node to fix up.
* @return Node The fixed up node that should be added as a child, which
* may well not be the same node that was passed in.
*/
protected org.apache.xpath.parser.Node fixupPrimaryRecursive(
org.apache.xpath.parser.Node n)
{
if (((SimpleNode) n).isPathExpr() && n.jjtGetNumChildren() > 0)
{
SimpleNode newRoot = (SimpleNode) fixupPrimaryRecursive(n.jjtGetChild(0));
if (newRoot.isPathExprReduced() && !newRoot.isPathExpr())
{
return newRoot;
}
}
return n;
}
/**
* Set this to false if you don't want the PathExprs rewritten to LocationPaths.
* For Diagnostic purposes.
*/
public static boolean m_rewritePathExprs = true;
/**
* This ugly little function strips the extranious PathExpr/RelativePathExpr/StepExpr
* from XObjects. I'm not sure what I'm going to do with the predicates of
* these expressions, or with variables, yet. It should be called from
* jjtAddChild functions.
*
* @param n The node to fix up.
* @return Node The fixed up node that should be added as a child, which
* may well not be the same node that was passed in.
*/
protected org.apache.xpath.parser.Node fixupPrimarys(
org.apache.xpath.parser.Node n)
{
if (((SimpleNode) n).shouldReduceIfOneChild())
{
n = n.jjtGetChild(0);
n.jjtSetParent(this);
return n;
}
Node orig = n;
if ((n instanceof NonExecutableExpression) && n.jjtGetNumChildren() > 0)
{
n = fixupPrimaryRecursive(n);
}
if (n instanceof PathExpr)
{
Node mightBeStepExprOrSomethingElse = n.jjtGetChild(0);
if (!(mightBeStepExprOrSomethingElse instanceof StepExpr))
n = mightBeStepExprOrSomethingElse; // is something else, so reduce
}
if (m_rewritePathExprs && n instanceof PathExpr)
{
boolean isTopLevel = (((PathExpr) n).m_parser.m_predLevel == 0);
try
{
n = (Node) WalkerFactory.newDTMIterator((PathExpr) n, isTopLevel);
}
catch (javax.xml.transform.TransformerException te)
{
throw new org.apache.xml.utils.WrappedRuntimeException(te);
}
}
if (n != orig)
n.jjtSetParent(this); // because jjtree can't!
return n;
}
/**
* @see org.apache.xpath.parser.Node#jjtOpen()
*/
public void jjtOpen()
{
}
/**
* @see org.apache.xpath.parser.Node#jjtClose()
*/
public void jjtClose()
{
}
/**
* @see org.apache.xpath.parser.Node#jjtSetParent(Node)
*/
public void jjtSetParent(Node n)
{
((Expression) this).exprSetParent((ExpressionNode) n);
}
/**
* @see org.apache.xpath.parser.Node#jjtGetParent()
*/
public Node jjtGetParent()
{
return (Node) ((Expression) this).exprGetParent();
}
/**
* @see org.apache.xpath.parser.Node#jjtAddChild(Node, int)
*/
public void jjtAddChild(Node n, int i)
{
n = fixupPrimarys(n);
((Expression) this).exprAddChild((ExpressionNode) n, i);
}
/**
* @see org.apache.xpath.parser.Node#jjtGetChild(int)
*/
public Node jjtGetChild(int i)
{
return (Node) ((Expression) this).exprGetChild(i);
}
/**
* @see org.apache.xpath.parser.Node#jjtGetNumChildren()
*/
public int jjtGetNumChildren()
{
return ((Expression) this).exprGetNumChildren();
}
/**
* @see org.apache.xpath.parser.Node#jjtAccept(XPathVisitor, Object)
*/
public Object jjtAccept(XPathVisitor visitor, Object data)
{
return visitor.visit(this, data);
}
/**
* Call jjtAccept for each child of the node.
* @param visitor The visitor that will visit the child node.
* @param data A data object to be handed to that visitor.
* @return Object The data object handed in, possibly
* modified by jjtAccept.
*/
public Object childrenAccept(XPathVisitor visitor, Object data)
{
int nChildren = jjtGetNumChildren();
for (int i = 0; i < nChildren; ++i)
{
jjtGetChild(i).jjtAccept(visitor, data);
}
return data;
}
/**
* @see java.lang.Object#toString()
*/
public String toString()
{
return this.getClass().getName();
}
/**
* Method toString.
* @param prefix
* @return String
*/
public String toString(String prefix)
{
return prefix + toString();
}
public void processToken(Token t)
{
// abstract
}
/**
* Dump a diagnostic representation of the node to System.out.
* @param prefix The prefix string to be added before the
* to each line of output.
*/
public void dump(String prefix)
{
dump(prefix, System.out);
}
/**
* Method for subclasses to override to print the diagnostic
* <i>value</i> of the node.
* @param ps The PrintStream to write the value to.
*/
public void printValue(java.io.PrintStream ps)
{
}
/**
* Dump a diagnostic representation of the node to a PrintStream.
*
* @param prefix The prefix string to be added before the
* to each line of output.
* @param ps The PrintStream where the representation will
* be written.
*/
public void dump(String prefix, java.io.PrintStream ps)
{
ps.print(toString(prefix));
printValue(ps);
ps.println();
int nChildren = jjtGetNumChildren();
for (int i = 0; i < nChildren; ++i)
{
SimpleNode n = (SimpleNode) jjtGetChild(i);
if (n != null)
{
n.dump(prefix + " ", ps);
}
}
}
}