View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jxpath.ri.axes;
18  
19  import org.apache.commons.jxpath.Function;
20  import org.apache.commons.jxpath.JXPathContext;
21  import org.apache.commons.jxpath.NodeSet;
22  import org.apache.commons.jxpath.ri.EvalContext;
23  import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
24  import org.apache.commons.jxpath.ri.QName;
25  import org.apache.commons.jxpath.ri.model.NodePointer;
26  
27  /**
28   * EvalContext that is used to hold the root node for the path traversal.
29   *
30   * @author Dmitri Plotnikov
31   * @version $Revision: 652845 $ $Date: 2008-05-02 19:46:46 +0200 (Fr, 02 Mai 2008) $
32   */
33  public class RootContext extends EvalContext {
34      private JXPathContextReferenceImpl jxpathContext;
35      private NodePointer pointer;
36      private Object[] registers;
37      private int availableRegister = 0;
38      public static final Object UNKNOWN_VALUE = new Object();
39      private static final int MAX_REGISTER = 4;
40  
41      /**
42       * Create a new RootContext.
43       * @param jxpathContext context
44       * @param pointer pointer
45       */
46      public RootContext(JXPathContextReferenceImpl jxpathContext,
47              NodePointer pointer) {
48          super(null);
49          this.jxpathContext = jxpathContext;
50          this.pointer = pointer;
51          if (pointer != null) {
52              pointer.setNamespaceResolver(jxpathContext.getNamespaceResolver());
53          }
54      }
55  
56      public JXPathContext getJXPathContext() {
57          return jxpathContext;
58      }
59  
60      public RootContext getRootContext() {
61          return this;
62      }
63  
64      /**
65       * Get absolute root context
66       * @return EvalContext
67       */
68      public EvalContext getAbsoluteRootContext() {
69          return jxpathContext.getAbsoluteRootContext();
70      }
71  
72      public NodePointer getCurrentNodePointer() {
73          return pointer;
74      }
75  
76      public Object getValue() {
77          return pointer;
78      }
79  
80      public int getCurrentPosition() {
81          throw new UnsupportedOperationException();
82      }
83  
84      public boolean nextNode() {
85          throw new UnsupportedOperationException();
86      }
87  
88      public boolean nextSet() {
89          throw new UnsupportedOperationException();
90      }
91  
92      public boolean setPosition(int position) {
93          throw new UnsupportedOperationException();
94      }
95  
96      /**
97       * Get a context that points to the specified object.
98       * @param constant object
99       * @return EvalContext
100      */
101     public EvalContext getConstantContext(Object constant) {
102         if (constant instanceof NodeSet) {
103             return new NodeSetContext(
104                 new RootContext(jxpathContext, null),
105                 (NodeSet) constant);
106         }
107 
108         NodePointer pointer;
109         if (constant instanceof NodePointer) {
110             pointer = (NodePointer) constant;
111         }
112         else {
113             pointer = NodePointer.newNodePointer(
114                     new QName(null, ""),
115                     constant,
116                     null);
117         }
118         return new InitialContext(new RootContext(jxpathContext, pointer));
119     }
120 
121     /**
122      * Get variable context.
123      * @param variableName variable name
124      * @return EvalContext
125      */
126     public EvalContext getVariableContext(QName variableName) {
127         return new InitialContext(
128             new RootContext(
129                 jxpathContext,
130                 jxpathContext.getVariablePointer(variableName)));
131     }
132 
133     /**
134      * Get the specified function from the context.
135      * @param functionName QName
136      * @param parameters Object[]
137      * @return Function
138      */
139     public Function getFunction(QName functionName, Object[] parameters) {
140         return jxpathContext.getFunction(functionName, parameters);
141     }
142 
143     /**
144      * Get a registered value.
145      * @param id int
146      * @return Object
147      */
148     public Object getRegisteredValue(int id) {
149         if (registers == null || id >= MAX_REGISTER || id == -1) {
150             return UNKNOWN_VALUE;
151         }
152         return registers[id];
153     }
154 
155     /**
156      * Set the next registered value.
157      * @param value Object
158      * @return the id that can reclaim value.
159      */
160     public int setRegisteredValue(Object value) {
161         if (registers == null) {
162             registers = new Object[MAX_REGISTER];
163             for (int i = 0; i < MAX_REGISTER; i++) {
164                 registers[i] = UNKNOWN_VALUE;
165             }
166         }
167         if (availableRegister >= MAX_REGISTER) {
168             return -1;
169         }
170         registers[availableRegister] = value;
171         availableRegister++;
172         return availableRegister - 1;
173     }
174 
175     public String toString() {
176         return super.toString() + ":" + pointer.asPath();
177     }
178 }