Home | History | Annotate | Download | only in operations
      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: VariableSafeAbsRef.java 468655 2006-10-28 07:12:06Z minchau $
     20  */
     21 package org.apache.xpath.operations;
     22 
     23 import org.apache.xml.dtm.DTMManager;
     24 import org.apache.xpath.Expression;
     25 import org.apache.xpath.XPathContext;
     26 import org.apache.xpath.objects.XNodeSet;
     27 import org.apache.xpath.objects.XObject;
     28 
     29 
     30 /**
     31  * This is a "smart" variable reference that is used in situations where
     32  * an absolute path is optimized into a variable reference, but may
     33  * be used in some situations where the document context may have changed.
     34  * For instance, in select="document(doc/@href)//name[//salary > 7250]", the
     35  * root in the predicate will be different for each node in the set.  While
     36  * this is easy to detect statically in this case, in other cases static
     37  * detection would be very hard or impossible.  So, this class does a dynamic check
     38  * to make sure the document context of the referenced variable is the same as
     39  * the current document context, and, if it is not, execute the referenced variable's
     40  * expression with the current context instead.
     41  */
     42 public class VariableSafeAbsRef extends Variable
     43 {
     44     static final long serialVersionUID = -9174661990819967452L;
     45 
     46   /**
     47    * Dereference the variable, and return the reference value.  Note that lazy
     48    * evaluation will occur.  If a variable within scope is not found, a warning
     49    * will be sent to the error listener, and an empty nodeset will be returned.
     50    *
     51    *
     52    * @param xctxt The runtime execution context.
     53    *
     54    * @return The evaluated variable, or an empty nodeset if not found.
     55    *
     56    * @throws javax.xml.transform.TransformerException
     57    */
     58   public XObject execute(XPathContext xctxt, boolean destructiveOK)
     59   	throws javax.xml.transform.TransformerException
     60   {
     61   	XNodeSet xns = (XNodeSet)super.execute(xctxt, destructiveOK);
     62   	DTMManager dtmMgr = xctxt.getDTMManager();
     63   	int context = xctxt.getContextNode();
     64   	if(dtmMgr.getDTM(xns.getRoot()).getDocument() !=
     65   	   dtmMgr.getDTM(context).getDocument())
     66   	{
     67   		Expression expr = (Expression)xns.getContainedIter();
     68   		xns = (XNodeSet)expr.asIterator(xctxt, context);
     69   	}
     70   	return xns;
     71   }
     72 
     73 }
     74 
     75