1 package org.jaxen; 2 3 /* 4 $Id$ 5 6 Copyright 2003 The Werken Company. All Rights Reserved. 7 8 Redistribution and use in source and binary forms, with or without 9 modification, are permitted provided that the following conditions are 10 met: 11 12 * Redistributions of source code must retain the above copyright 13 notice, this list of conditions and the following disclaimer. 14 15 * Redistributions in binary form must reproduce the above copyright 16 notice, this list of conditions and the following disclaimer in the 17 documentation and/or other materials provided with the distribution. 18 19 * Neither the name of the Jaxen Project nor the names of its 20 contributors may be used to endorse or promote products derived 21 from this software without specific prior written permission. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 24 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 25 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 26 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 27 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 35 */ 36 37 import java.io.Serializable; 38 import java.util.ArrayList; 39 import java.util.Collections; 40 import java.util.List; 41 42 /** Wrapper around implementation-specific objects used 43 * as the context of an expression evaluation. 44 * 45 * <p> 46 * <strong>NOTE:</strong> This class is not typically used directly, 47 * but is exposed for writers of implementation-specific 48 * XPath packages. 49 * </p> 50 * 51 * <p> 52 * The <code>Context</code> bundles utilities together 53 * for evaluation of the expression. It wraps the provided 54 * objects for ease-of-passage through the expression 55 * <acronym title="Abstract Syntax Tree">AST</acronym>. 56 * </p> 57 * 58 * @see ContextSupport 59 * @see BaseXPath 60 * @see org.jaxen.dom4j.Dom4jXPath XPath for dom4j 61 * @see org.jaxen.jdom.JDOMXPath XPath for JDOM 62 * @see org.jaxen.dom.DOMXPath XPath for W3C DOM 63 * 64 * @author <a href="mailto:bob@werken.com">bob mcwhirter</a> 65 */ 66 public class Context implements Serializable { 67 68 /** 69 * 70 */ 71 private static final long serialVersionUID = 2315979994685591055L; 72 73 // ---------------------------------------------------------------------- 74 // Instance members 75 // ---------------------------------------------------------------------- 76 77 /** Context-support */ 78 private ContextSupport contextSupport; 79 80 /** Context node-set */ 81 private List nodeSet; 82 83 /** Current context size */ 84 private int size; 85 86 /** Current context position */ 87 private int position; 88 89 // ---------------------------------------------------------------------- 90 // Constructors 91 // ---------------------------------------------------------------------- 92 93 /** Create a new context. 94 * 95 * @param contextSupport the context-support 96 */ 97 public Context(ContextSupport contextSupport) 98 { 99 this.contextSupport = contextSupport; 100 this.nodeSet = Collections.EMPTY_LIST; 101 this.size = 0; 102 this.position = 0; 103 } 104 105 // ---------------------------------------------------------------------- 106 // Instance methods 107 // ---------------------------------------------------------------------- 108 109 /** 110 * <p> 111 * Set the context node-set, and sets the current context size to the size 112 * of this node-set. </p> 113 * 114 * <p>The actual list is stored in this object. A copy 115 * is not made. This list should not be modified in other code after 116 * calling this method.</p> 117 * 118 * <p> 119 * After invoking this method, the client should immediately call 120 * {@link #setSize(int) setSize} and {@link #setPosition(int) setPosition}. 121 *</p> 122 * 123 * @param nodeSet the context node-set 124 */ 125 public void setNodeSet(List nodeSet) 126 { 127 this.nodeSet = nodeSet; 128 this.size = nodeSet.size(); 129 if (position >= size) this.position = 0; 130 } 131 132 /** Retrieve the context node-set. 133 * This is a live list. It is not a copy. 134 * Do not modify it. 135 * 136 * @return the context node-set 137 */ 138 public List getNodeSet() 139 { 140 return this.nodeSet; 141 } 142 143 /** Set the <code>ContextSupport</code>. 144 * 145 * @param contextSupport the context-support 146 */ 147 public void setContextSupport(ContextSupport contextSupport) 148 { 149 this.contextSupport = contextSupport; 150 } 151 152 /** Retrieve the <code>ContextSupport</code>. 153 * 154 * @return the context-support 155 */ 156 public ContextSupport getContextSupport() 157 { 158 return this.contextSupport; 159 } 160 161 /** Retrieve the current <code>Navigator</code>. 162 * 163 * @return the navigator 164 */ 165 public Navigator getNavigator() 166 { 167 return getContextSupport().getNavigator(); 168 } 169 170 /** Translate a namespace prefix to its URI. 171 * 172 * @param prefix the prefix 173 * 174 * @return the namespace URI mapped to the prefix 175 */ 176 public String translateNamespacePrefixToUri(String prefix) 177 { 178 return getContextSupport().translateNamespacePrefixToUri( prefix ); 179 } 180 181 /** Retrieve a variable value. 182 * 183 * @param namespaceURI the function namespace URI 184 * @param prefix the function prefix 185 * @param localName the function name 186 * 187 * @return the variable value 188 * 189 * @throws UnresolvableException if unable to locate a bound variable 190 */ 191 public Object getVariableValue(String namespaceURI, 192 String prefix, 193 String localName) 194 throws UnresolvableException 195 { 196 return getContextSupport().getVariableValue( namespaceURI, 197 prefix, 198 localName ); 199 } 200 201 /** Retrieve a <code>Function</code>. 202 * 203 * @param namespaceURI the function namespace URI 204 * @param prefix the function prefix 205 * @param localName the function name 206 * 207 * @return the function object 208 * 209 * @throws UnresolvableException if unable to locate a bound function 210 */ 211 public Function getFunction(String namespaceURI, 212 String prefix, 213 String localName) 214 throws UnresolvableException 215 { 216 return getContextSupport().getFunction( namespaceURI, 217 prefix, 218 localName ); 219 } 220 221 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 222 // Properties 223 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 224 225 /** Set the current size in the context node-set. 226 * 227 * @param size the size 228 */ 229 public void setSize(int size) 230 { 231 this.size = size; 232 } 233 234 /** Retrieve the size of the current context node-set. 235 * 236 * @return the size 237 */ 238 public int getSize() 239 { 240 return this.size; 241 } 242 243 /** Set the current position in the context node-set. 244 * 245 * @param position the position 246 */ 247 public void setPosition(int position) 248 { 249 this.position = position; 250 } 251 252 /** Retrieve current position in the context node-set. 253 * 254 * @return the current position 255 */ 256 public int getPosition() 257 { 258 return this.position; 259 } 260 261 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 262 // Helpers 263 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 264 265 /** Create a type-safe shallow copy. 266 * 267 * @return the duplicate 268 */ 269 public Context duplicate() 270 { 271 Context dupe = new Context( getContextSupport() ); 272 273 List thisNodeSet = getNodeSet(); 274 275 if ( thisNodeSet != null ) 276 { 277 List dupeNodeSet = new ArrayList( thisNodeSet.size() ); 278 dupeNodeSet.addAll( thisNodeSet ); 279 dupe.setNodeSet( dupeNodeSet ); 280 dupe.setPosition(this.position); 281 } 282 283 return dupe; 284 } 285 }