Home | History | Annotate | Download | only in patterns
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: ContextMatchStepPattern.java 468655 2006-10-28 07:12:06Z minchau $
     20  */
     21 package org.apache.xpath.patterns;
     22 
     23 import org.apache.xml.dtm.Axis;
     24 import org.apache.xml.dtm.DTM;
     25 import org.apache.xml.dtm.DTMAxisTraverser;
     26 import org.apache.xml.dtm.DTMFilter;
     27 import org.apache.xpath.XPathContext;
     28 import org.apache.xpath.axes.WalkerFactory;
     29 import org.apache.xpath.objects.XObject;
     30 /**
     31  * Special context node pattern matcher.
     32  */
     33 public class ContextMatchStepPattern extends StepPattern
     34 {
     35     static final long serialVersionUID = -1888092779313211942L;
     36 
     37   /**
     38    * Construct a ContextMatchStepPattern.
     39    *
     40    */
     41   public ContextMatchStepPattern(int axis, int paxis)
     42   {
     43     super(DTMFilter.SHOW_ALL, axis, paxis);
     44   }
     45 
     46   /**
     47    * Execute this pattern step, including predicates.
     48    *
     49    *
     50    * @param xctxt XPath runtime context.
     51    *
     52    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
     53    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
     54    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
     55    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
     56    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
     57    *
     58    * @throws javax.xml.transform.TransformerException
     59    */
     60   public XObject execute(XPathContext xctxt)
     61           throws javax.xml.transform.TransformerException
     62   {
     63 
     64     if (xctxt.getIteratorRoot() == xctxt.getCurrentNode())
     65       return getStaticScore();
     66     else
     67       return this.SCORE_NONE;
     68   }
     69 
     70   /**
     71    * Execute the match pattern step relative to another step.
     72    *
     73    *
     74    * @param xctxt The XPath runtime context.
     75    * NEEDSDOC @param prevStep
     76    *
     77    * @return {@link org.apache.xpath.patterns.NodeTest#SCORE_NODETEST},
     78    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NONE},
     79    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_NSWILD},
     80    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_QNAME}, or
     81    *         {@link org.apache.xpath.patterns.NodeTest#SCORE_OTHER}.
     82    *
     83    * @throws javax.xml.transform.TransformerException
     84    */
     85   public XObject executeRelativePathPattern(
     86           XPathContext xctxt, StepPattern prevStep)
     87             throws javax.xml.transform.TransformerException
     88   {
     89 
     90     XObject score = NodeTest.SCORE_NONE;
     91     int context = xctxt.getCurrentNode();
     92     DTM dtm = xctxt.getDTM(context);
     93 
     94     if (null != dtm)
     95     {
     96       int predContext = xctxt.getCurrentNode();
     97       DTMAxisTraverser traverser;
     98 
     99       int axis = m_axis;
    100 
    101       boolean needToTraverseAttrs = WalkerFactory.isDownwardAxisOfMany(axis);
    102       boolean iterRootIsAttr = (dtm.getNodeType(xctxt.getIteratorRoot())
    103                                  == DTM.ATTRIBUTE_NODE);
    104 
    105       if((Axis.PRECEDING == axis) && iterRootIsAttr)
    106       {
    107         axis = Axis.PRECEDINGANDANCESTOR;
    108       }
    109 
    110       traverser = dtm.getAxisTraverser(axis);
    111 
    112       for (int relative = traverser.first(context); DTM.NULL != relative;
    113               relative = traverser.next(context, relative))
    114       {
    115         try
    116         {
    117           xctxt.pushCurrentNode(relative);
    118 
    119           score = execute(xctxt);
    120 
    121           if (score != NodeTest.SCORE_NONE)
    122           {
    123 	      //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
    124 	      //       predContext, relative);
    125 	      if (executePredicates(xctxt, dtm, context))
    126 		  return score;
    127 
    128 	      score = NodeTest.SCORE_NONE;
    129           }
    130 
    131           if(needToTraverseAttrs && iterRootIsAttr
    132              && (DTM.ELEMENT_NODE == dtm.getNodeType(relative)))
    133           {
    134             int xaxis = Axis.ATTRIBUTE;
    135             for (int i = 0; i < 2; i++)
    136             {
    137               DTMAxisTraverser atraverser = dtm.getAxisTraverser(xaxis);
    138 
    139               for (int arelative = atraverser.first(relative);
    140                       DTM.NULL != arelative;
    141                       arelative = atraverser.next(relative, arelative))
    142               {
    143                 try
    144                 {
    145                   xctxt.pushCurrentNode(arelative);
    146 
    147                   score = execute(xctxt);
    148 
    149                   if (score != NodeTest.SCORE_NONE)
    150                   {
    151 		      //score = executePredicates( xctxt, prevStep, SCORE_OTHER,
    152 		      //       predContext, arelative);
    153 
    154                     if (score != NodeTest.SCORE_NONE)
    155                       return score;
    156                   }
    157                 }
    158                 finally
    159                 {
    160                   xctxt.popCurrentNode();
    161                 }
    162               }
    163               xaxis = Axis.NAMESPACE;
    164             }
    165           }
    166 
    167         }
    168         finally
    169         {
    170           xctxt.popCurrentNode();
    171         }
    172       }
    173 
    174     }
    175 
    176     return score;
    177   }
    178 
    179 }
    180