Break a location step into predicates that can be driven against the MatchParser.

@param selector
@param start
@param stepEnd
@throws InvalidXPathSyntaxException
334203
private void parseLocationStep(String selector,
                                 int start,
                                 int stepEnd)
    throws InvalidXPathSyntaxException
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.entry(cclass,
               "parseLocationStep",
               "selector: " + selector + ", start: " + start + ", end: " + stepEnd);

    int stepStart = start;
    int posOpenBracket = selector.indexOf("[", start);
    if(posOpenBracket > stepEnd || posOpenBracket == -1)
    {
      // Set posOpenBracket to avoid further processing
      posOpenBracket = -1;
      // No brackets so process whole of the location step
      String step = selector.substring(start,stepEnd);
      // Set the full name into the identifier. The full name is used in position assignment when
      // determining uniqueness of names. Only a full name will do.
      String full = selector.substring(0,stepEnd);
      // Add an IdentifierImpl for the location step to the array list
      selOperands.add(createIdentifierForSubExpression(step, full, true, false));      
    }
    
    int posCloseBracket = selector.indexOf("]", start); 
 
    boolean wrapWholeStep = false;
    boolean foundPredicates = false;
    ArrayList tempSelOperands = new ArrayList();
    while (posOpenBracket >= 0)
    {
      foundPredicates = true;
      if(posCloseBracket < posOpenBracket)
      {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          tc.exit(this,cclass, "parseLocationStep", "bracket error"); 
        
        InvalidXPathSyntaxException iex = new InvalidXPathSyntaxException(selector);
        FFDC.processException(cclass,
            "com.ibm.ws.sib.matchspace.selector.impl.XPath10ParserImpl",
            iex,
            "1:372:1.16"); 
        
        throw iex;
      }
      else
      {
        // The full selector path up to this point
        String full = selector.substring(0,posOpenBracket);
        
        // Factor out the location step first but be careful we may have a predicate
        if(start != posOpenBracket)
        {
          // Go ahead and deal with the location step
          String step = selector.substring(start,posOpenBracket);
          // Add an IdentifierImpl for the location step to the array list
          tempSelOperands.add(createIdentifierForSubExpression(step, full, true, false));    
        }
        
        // Now parse the predicate
        String predicate = selector.substring(posOpenBracket + 1,posCloseBracket);
        Selector parsedPredicate = parsePredicate(predicate, full);
        
        // Check whether we were able to parse
        if(parsedPredicate == null)
        {
          // Unable to parse the expression, so we need to wrap the entire step
//          tempSelOperands.add(createIdentifierForSubExpression(predicate, false));
          wrapWholeStep = true;
          break;
        }
        else
        {
          // we were able to parse the expression with the MatchParser
          // Check that the predicate has Simple tests only
          if(!Matching.isSimple(parsedPredicate))
          {
            wrapWholeStep = true;
            break;
          }
          parsedPredicate.setExtended();
          tempSelOperands.add(parsedPredicate);
        }       
      }
        
      // Move to beyond the close bracket
      start = posCloseBracket+1;
      //Are there any more brackets?
      posOpenBracket = selector.indexOf("[", start);
      posCloseBracket = selector.indexOf("]", start); 
      
      // Have we found the last bracket in this location step?
      if(posOpenBracket > stepEnd || posOpenBracket == -1)
      {
        // Set posOpenBracket to avoid further processing
        posOpenBracket = -1; 
      }
    } // eof while
    
    if(foundPredicates)
    {
      // If we determined that we cannot parse this location step, then wrap it
      if(wrapWholeStep)
        wrapLocationStep(selector, stepStart,stepEnd);
      else
      {
        // PostProcessing here
        selOperands.addAll(tempSelOperands);
      }
    }
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.exit(this,cclass, "parseLocationStep");      
  }
1211146
void initWithSingleTokenPath(String path) {
        this.path = path;
        this.index = 0;
        this.offset = 0;
        this.nextSplit = -1;
        this.token = path;
    }
997318
private void parseSelector(String selector) throws InvalidXPathSyntaxException
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.entry(cclass,
               "parseSelector",
               "selector: " + selector);   
    // Set the locationStep to -1
    locationStep = -1;
    int start = 0;
    // find number of path separators

    // Pre-check selector for multi-level wildcards. We can't handle these in
    // the optimised code. Simply wrap the entire expression
    int posWildCard = selector.indexOf("//", start);
    if(posWildCard >= 0)
    {
      // We have a multi-level wildcard, process the whole thing
      locationStep = 0;
      selOperands.add(createIdentifierForWildExpression(selector));
      return;
    }
    
    // Locate the first path separator
    int posSeparator = selector.indexOf("/", start);

    // Handle an initial separator character
    if(posSeparator == 0)
    {
      // An initial slash
      String step = selector.substring(start,start+1);
      // Add an IdentifierImpl for the location step to the array list
      selOperands.add(createIdentifierForSubExpression(step, step, true, false));   
      // Bump the start counter      
      start++;
     }

    // Now iterate over the rest of the selector string attempting to isolate
    // Individual location path steps.
    int stepEnd = 0;
    while (stepEnd >= 0)
    {
      StepProperties stepProperties = new StepProperties();
      
      // Drive the method that isolates the next step
      isolateNextStep(selector,start, stepProperties);

      stepEnd = stepProperties.endOfStep;
      
      // Useful debug
      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
      {
        if(stepEnd < 0)
        {
          tc.debug(this,
                   cclass, 
                   "parsePredicate", 
                   "isolated Step: " + selector.substring(start) +
                   " and wrapStep is " + stepProperties.wrapStep);
        }
        else
        {
          tc.debug(this,
                   cclass, 
                   "parsePredicate", 
                   "isolated Step: " + selector.substring(start,stepEnd) +
                   " and wrapStep is " + stepProperties.wrapStep);
        }
      }
     
      // Should the entire location step be wrapped in an Identifier
      if(stepProperties.wrapStep)
      {
        if(stepEnd <0)
        {
          // Wrap entire location step in an Identifier
          wrapLastLocationStep(selector, start, true);
        }
        else
        {
          // Wrap intermediate location step in an Identifier
          wrapLocationStep(selector, start,stepEnd);          
        }
      }
      else
      {
        // We can attempt to parse the step using the MatchParser
        if(stepEnd <0)
        {
          // This is the final location step
          parseLastLocationStep(selector, start);
        }        
        else
        {
          // An intermediate location step
          parseLocationStep(selector, start, stepEnd);
        }
      }
      
      // Bump the start parameter and then look for next step
      if(stepEnd >= 0)
        start = stepEnd + 1;
    }
    
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.exit(this,cclass, "parseSelector");    
  }
871069
public boolean matches(String target, int start, int end) {
		return this.matches(target, start, end, (Match) null);
	}
496127
private LocationStepQueryNode createLocationStep(SimpleNode node, NAryQueryNode parent) {
        LocationStepQueryNode queryNode = null;
        boolean descendant = false;
        Node p = node.jjtGetParent();
        for (int i = 0; i < p.jjtGetNumChildren(); i++) {
            SimpleNode c = (SimpleNode) p.jjtGetChild(i);
            if (c == node) { // NOSONAR
                queryNode = factory.createLocationStepQueryNode(parent);
                queryNode.setNameTest(null);
                queryNode.setIncludeDescendants(descendant);
                parent.addOperand(queryNode);
                break;
            }
            descendant = (c.getId() == JJTSLASHSLASH
                    || c.getId() == JJTROOTDESCENDANTS);
        }

        node.childrenAccept(this, queryNode);

        return queryNode;
    }
310814
function mergeSelectPath(sSelectPath) {
				if (mAggregatedQueryOptions.$select.indexOf(sSelectPath) < 0) {
					if (bCacheImmutable) {
						return false;
					}
					mAggregatedQueryOptions.$select.push(sSelectPath);
				}
				return true;
			}
829240
public Object visit(QueryRootNode node, Object data) throws RepositoryException {
        StringBuilder sb = (StringBuilder) data;
        try {
            sb.append("SELECT");

            InternalQName[] selectProps = node.getSelectProperties();
            if (selectProps.length == 0) {
                sb.append(" *");
            } else {
                String comma = "";
                for (int i = 0; i < selectProps.length; i++) {
                    sb.append(comma).append(" ");
                    appendName(selectProps[i], resolver, sb);
                    comma = ",";
                }
            }

            sb.append(" FROM");

            // node type restrictions are within predicates of location nodes
            // therefore we write the where clause first to a temp string to
            // collect the node types.
            StringBuilder tmp = new StringBuilder();
            LocationStepQueryNode[] steps = node.getLocationNode().getPathSteps();
            QueryNode[] predicates = steps[steps.length - 1].getPredicates();
            // are there any relevant predicates?
            for (int i = 0; i < predicates.length; i++) {
                if (predicates[i].getType() != QueryNode.TYPE_NODETYPE) {
                    tmp.append(" WHERE ");
                }
            }
            String and = "";
            for (int i = 0; i < predicates.length; i++) {
                if (predicates[i].getType() != QueryNode.TYPE_NODETYPE) {
                    tmp.append(and);
                    and = " AND ";
                }
                predicates[i].accept(this, tmp);
            }

            // node types have been collected by now
            String comma = "";
            int ntCount = 0;
            for (Iterator<InternalQName> it = nodeTypes.iterator(); it.hasNext(); ntCount++) {
               InternalQName nt = it.next();
                sb.append(comma).append(" ");
                appendName(nt, resolver, sb);
                comma = ",";
            }

            if (ntCount == 0) {
                sb.append(" ");
                sb.append(resolver.createJCRName(Constants.NT_BASE).getAsString());
            }

            // append WHERE clause
            sb.append(tmp.toString());

            if (steps.length == 2
                    && steps[1].getIncludeDescendants()
                    && steps[1].getNameTest() == null) {
                // then this query selects all paths
            } else if (steps.length == 1
                    && steps[0].getIncludeDescendants()
                    && steps[0].getNameTest() == null) {
                // then this query selects all paths
            } else {
                if (predicates.length > 0) {
                    sb.append(" AND ");
                } else {
                    sb.append(" WHERE ");
                }
                node.getLocationNode().accept(this, sb);
            }
        } catch (NamespaceException e) {
            exceptions.add(e);
        }

        if (node.getOrderNode() != null) {
            node.getOrderNode().accept(this, sb);
        }

        return sb;
    }
223631
private void parseForwardStep() throws TTXPathException {

        AbsAxis axis;
        AbsFilter filter;
        if (isForwardAxis()) {
            axis = parseForwardAxis();
            filter = parseNodeTest(axis.getClass() == AttributeAxis.class);

            mPipeBuilder.addStep(axis, filter);
        } else {
            axis = parseAbbrevForwardStep();

            mPipeBuilder.addStep(axis);
        }
    }
611154
public void endElement(String namespaceURI, String localName, String qName) throws SAXException
    {
        if (localName.equalsIgnoreCase(TABLE))
        {
            if (startTable)
                if (m_record.getEditMode() == DBConstants.EDIT_ADD)
                {
                    try {
                        m_record.add();
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                }
            startTable = false;
        }
    }
401587
public void startPath(double x, double y) {
		Point2D endPoint = new Point2D();
		endPoint.x = x;
		endPoint.y = y;
		startPath(endPoint);
	}
1256978
public final void entryRuleXTryCatchFinallyExpression() throws RecognitionException {
        try {
            // InternalXbase.g:1459:1: ( ruleXTryCatchFinallyExpression EOF )
            // InternalXbase.g:1460:1: ruleXTryCatchFinallyExpression EOF
            {
            if ( state.backtracking==0 ) {
               before(grammarAccess.getXTryCatchFinallyExpressionRule()); 
            }
            pushFollow(FOLLOW_1);
            ruleXTryCatchFinallyExpression();

            state._fsp--;
            if (state.failed) return ;
            if ( state.backtracking==0 ) {
               after(grammarAccess.getXTryCatchFinallyExpressionRule()); 
            }
            match(input,EOF,FOLLOW_2); if (state.failed) return ;

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
333757
function isPathMatchSelector(path, selector){
  function isMatch(path, selector){
    path = typeof path == 'string' ? parseRole(path) : path || '';
    selector = typeof selector == 'string' ? parseRole(selector) : selector || '';

    return selector.role == path.role &&
           (selector.roleId == '*' || selector.roleId == path.roleId) &&
           selector.subrole == path.subrole;
  }

  var pathIndex = path.length;
  var selectorIndex = selector.length;

  if (!selectorIndex)
    return true;

  if (!isMatch(path[--pathIndex], selector[--selectorIndex]))
    return false;

  while (pathIndex > 0 && selectorIndex > 0)
    if (!isMatch(path[--pathIndex], selector[--selectorIndex]))
      selectorIndex++;

  return selectorIndex === 0;
}
1035259
private void process(ImmutableSetMultimap<Class<? extends Annotation>, Element> validElements) {
    for (ProcessingStep step : steps) {
      ImmutableSetMultimap<Class<? extends Annotation>, Element> stepElements =
          new ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element>()
              .putAll(indexByAnnotation(elementsDeferredBySteps.get(step), step.annotations()))
              .putAll(filterKeys(validElements, Predicates.<Object>in(step.annotations())))
              .build();
      if (stepElements.isEmpty()) {
        elementsDeferredBySteps.removeAll(step);
      } else {
        Set<? extends Element> rejectedElements = step.process(stepElements);
        elementsDeferredBySteps.replaceValues(
            step,
            transform(
                rejectedElements,
                new Function<Element, ElementName>() {
                  @Override
                  public ElementName apply(Element element) {
                    return ElementName.forAnnotatedElement(element);
                  }
                }));
      }
    }
  }
79126
public static boolean nodeMatchesStep(Step s,
				  String uri,
				  String localName,
				  String qName,
				  Attributes a) {
	// if the name doesn't match, then we've got a loser
	if (!s.isMatchingName(uri, localName))
	    return false;

	// it's still in the game; check the predicates
	List l = s.getPredicates();
	for (int i = 0; l != null && i < l.size(); i++) {
	    Predicate p = (Predicate) l.get(i);
	    if (!(p instanceof AttributePredicate))
		throw new UnsupportedOperationException
		    ("only attribute predicates are supported by filter");
	    if (!((AttributePredicate) p).isMatchingAttribute(a))
		return false;		// all predicates must match
	}

	// it's survived
	return true;
    }
560102
private Selector parsePredicate(String predicate, String fullPath) 
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.entry(cclass,
               "parsePredicate",
               "predicate: " + predicate); 

    Selector parsed = null;
    try
    {
      // Preprocess predicate for special characters
      String parserInput = preProcessForSpecials(predicate);
      
      // Attempt to parse predicate with "JMS" parser
      predicateParser =  MatchParserImpl.prime(predicateParser, parserInput, true);     
      parsed = predicateParser.getSelector(parserInput);
      if (parsed.getType() == Selector.INVALID)
      {
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
          tc.debug(this,cclass, "parsePredicate", "Unable to parse predicate");           
        // reset the output to null
        parsed = null;
      }
      else
      {
        postProcessSelectorTree(parsed, fullPath);
      }
    }
    catch (Exception ex)
    {
      // No FFDC Code Needed.
      // In this case we will only trace the exception that we encountered.
      // It could be that the XPath parser is able to process this predicate
      // and that we've encountered a discrepancy between the syntax of an
      // expression supported by JMS and by XPath.
      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        tc.debug(this,cclass, "parsePredicate", ex);   
    }
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      tc.exit(this,cclass, "parsePredicate", parsed);     
    return parsed;
  }
332144
private void parseRangeExpr() throws TTXPathException {

        parseAdditiveExpr();
        if (is("to", true)) {

            mPipeBuilder.addExpressionSingle();

            parseAdditiveExpr();
            mPipeBuilder.addRangeExpr(getTransaction());

        }
    }
703430
private void parsePathExpr() throws TTXPathException {

        if (is(TokenType.SLASH, true)) {
            // path expression starts from the root
            mPipeBuilder.addStep(new DocumentNodeAxis(getTransaction()));
            final TokenType type = mToken.getType();

            if (type != TokenType.END && type != TokenType.COMMA) {
                // all immediately following keywords or '*' are nametests, not
                // operators
                // leading-lone-slash constrain

                parseRelativePathExpr();
            }

        } else if (is(TokenType.DESC_STEP, true)) {
            // path expression starts from the root with a descendant-or-self
            // step
            mPipeBuilder.addStep(new DocumentNodeAxis(getTransaction()));

            final AbsAxis mAxis = new DescendantAxis(getTransaction(), true);

            mPipeBuilder.addStep(mAxis);

            parseRelativePathExpr();
        } else {
            parseRelativePathExpr();
        }
    }