in src/org/apache/xpath/axes/WalkerFactory.java [1623:1719]
private static boolean isNaturalDocOrder(
Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
throws javax.xml.transform.TransformerException
{
if(canCrissCross(analysis))
return false;
// Namespaces can present some problems, so just punt if we're looking for
// these.
if(isSet(analysis, BIT_NAMESPACE))
return false;
// The following, preceding, following-sibling, and preceding sibling can
// be found in doc order if we get to this point, but if they occur
// together, they produce
// duplicates, so it's better for us to eliminate this case so we don't
// have to check for duplicates during runtime if we're using a
// WalkingIterator.
if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) &&
isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING))
return false;
// OK, now we have to check for select="@*/axis::*" patterns, which
// can also cause duplicates to happen. But select="axis*/@::*" patterns
// are OK, as are select="@foo/axis::*" patterns.
// Unfortunately, we can't do this just via the analysis bits.
int stepType;
int stepCount = 0;
boolean foundWildAttribute = false;
// Steps that can traverse anything other than down a
// subtree or that can produce duplicates when used in
// combonation are counted with this variable.
int potentialDuplicateMakingStepCount = 0;
while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
{
stepCount++;
switch (stepType)
{
case OpCodes.FROM_ATTRIBUTES :
case OpCodes.MATCH_ATTRIBUTE :
if(foundWildAttribute) // Maybe not needed, but be safe.
return false;
// This doesn't seem to work as a test for wild card. Hmph.
// int nodeTestType = compiler.getStepTestType(stepOpCodePos);
String localName = compiler.getStepLocalName(stepOpCodePos);
// System.err.println("localName: "+localName);
if(localName.equals("*"))
{
foundWildAttribute = true;
}
break;
case OpCodes.FROM_FOLLOWING :
case OpCodes.FROM_FOLLOWING_SIBLINGS :
case OpCodes.FROM_PRECEDING :
case OpCodes.FROM_PRECEDING_SIBLINGS :
case OpCodes.FROM_PARENT :
case OpCodes.OP_VARIABLE :
case OpCodes.OP_EXTFUNCTION :
case OpCodes.OP_FUNCTION :
case OpCodes.OP_GROUP :
case OpCodes.FROM_NAMESPACE :
case OpCodes.FROM_ANCESTORS :
case OpCodes.FROM_ANCESTORS_OR_SELF :
case OpCodes.MATCH_ANY_ANCESTOR :
case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
case OpCodes.FROM_DESCENDANTS_OR_SELF :
case OpCodes.FROM_DESCENDANTS :
if(potentialDuplicateMakingStepCount > 0)
return false;
potentialDuplicateMakingStepCount++;
case OpCodes.FROM_ROOT :
case OpCodes.FROM_CHILDREN :
case OpCodes.FROM_SELF :
if(foundWildAttribute)
return false;
break;
default :
throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
// + stepType);
}
int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
if (nextStepOpCodePos < 0)
break;
stepOpCodePos = nextStepOpCodePos;
}
return true;
}