1 package net.sf.saxon.functions; 2 import net.sf.saxon.expr.*; 3 import net.sf.saxon.instruct.InstructionDetails; 4 import net.sf.saxon.instruct.SlotManager; 5 import net.sf.saxon.om.*; 6 import net.sf.saxon.trace.Location; 7 import net.sf.saxon.trans.DynamicError; 8 import net.sf.saxon.trans.IndependentContext; 9 import net.sf.saxon.trans.Variable; 10 import net.sf.saxon.trans.XPathException; 11 import net.sf.saxon.type.ItemType; 12 import net.sf.saxon.type.Type; 13 import net.sf.saxon.value.*; 14 15 import java.util.Iterator ; 16 import java.io.ObjectOutputStream ; 17 import java.io.IOException ; 18 19 20 24 25 public class Evaluate extends SystemFunction { 26 27 32 IndependentContext staticContext; 33 InstructionDetails details; 37 public static final int EVALUATE = 0; 38 public static final int EXPRESSION = 1; 39 public static final int EVAL = 2; 40 public static final int EVALUATE_NODE = 3; 41 42 45 46 protected SequenceType getRequiredType(int arg) { 47 if (arg==0) { 48 return super.getRequiredType(arg); 49 } else { 50 return SequenceType.ANY_SEQUENCE; 51 } 52 } 53 54 58 59 public void checkArguments(StaticContext env) throws XPathException { 60 if (staticContext == null) { 61 super.checkArguments(env); 63 if (operation == EVALUATE || operation == EXPRESSION) { 64 NamespaceResolver nsContext = env.getNamespaceResolver(); 65 staticContext = new IndependentContext(env.getConfiguration()); 66 staticContext.setBaseURI(env.getBaseURI()); 67 staticContext.setSchemaImporter(env); 68 staticContext.setDefaultFunctionNamespace(env.getDefaultFunctionNamespace()); 69 70 getExecutable().setReasonUnableToCompile( 74 "Cannot compile a stylesheet containing calls on saxon:evaluate() or saxon:expression(), " + 75 "because they require access to the uncompiled stylesheet"); 76 staticContext.setFunctionLibrary(env.getFunctionLibrary()); 77 78 for (Iterator iter = nsContext.iteratePrefixes(); iter.hasNext();) { 79 String prefix = (String )iter.next(); 80 String uri = nsContext.getURIForPrefix(prefix, true); 81 staticContext.declareNamespace(prefix, uri); 82 } 83 details = new InstructionDetails(); 84 details.setConstructType(Location.SAXON_EVALUATE); 85 details.setSystemId(env.getLocationMap().getSystemId(this.locationId)); 86 details.setLineNumber(env.getLocationMap().getLineNumber(this.locationId)); 87 } else if (operation == EVALUATE_NODE) { 88 staticContext = new IndependentContext(env.getConfiguration()); 91 } 92 } 93 } 94 95 101 102 public Expression preEvaluate(StaticContext env) throws XPathException { 103 if (operation == EXPRESSION) { 104 if (argument[0] instanceof StringValue) { 106 PreparedExpression pexpr = new PreparedExpression(); 107 String exprText = ((StringValue)argument[0]).getStringValue(); 109 pexpr.variables = new Variable[10]; 110 for (int i=1; i<10; i++) { 111 QNameValue qname = new QNameValue("", "", "p"+i); 112 pexpr.variables[i-1] = staticContext.declareVariable(qname); 113 } 114 Expression expr = ExpressionTool.make(exprText, staticContext, 0, Token.EOF, 1); 115 116 ItemType contextItemType = Type.ITEM_TYPE; 117 expr = expr.typeCheck(staticContext, contextItemType); 118 pexpr.stackFrameMap = staticContext.getStackFrameMap(); 119 ExpressionTool.allocateSlots(expr, pexpr.stackFrameMap.getNumberOfVariables(), pexpr.stackFrameMap); 120 pexpr.expression = expr; 121 return new ObjectValue(pexpr); 122 } 123 } 124 return this; 126 } 127 128 private PreparedExpression prepareExpression(XPathContext context) throws XPathException { 129 if (operation == EVAL) { 130 Item item = argument[0].evaluateItem(context); 131 if (!(item instanceof ObjectValue)) { 132 dynamicError( 133 "First argument to saxon:eval must be an expression prepared using saxon:expression", context); 134 return null; 135 } 136 ObjectValue obj = (ObjectValue)item; 137 Object v = obj.getObject(); 138 if (!(v instanceof PreparedExpression)) { 139 dynamicError( 140 "First argument to saxon:eval must be an expression prepared using saxon:expression", context); 141 return null; 142 } 143 return (PreparedExpression)v; 144 145 } 146 147 PreparedExpression pexpr = new PreparedExpression(); 148 String exprText; 149 if (operation == EVALUATE_NODE) { 150 NodeInfo node = (NodeInfo)argument[0].evaluateItem(context); 151 IndependentContext env = staticContext.copy(); 152 pexpr.expStaticContext = env; 153 env.setBaseURI(node.getBaseURI()); 154 env.setFunctionLibrary(getExecutable().getFunctionLibrary()); 155 env.setNamespaces(node); 156 exprText = node.getStringValue(); 157 AxisIterator single = SingletonIterator.makeIterator(node); 158 single.next(); 159 context.setCurrentIterator(single); 160 Expression expr; 161 try { 162 expr = ExpressionTool.make(exprText, env, 0, Token.EOF, 1); 163 } catch (XPathException e) { 164 String name = context.getController().getNamePool().getDisplayName(getFunctionNameCode()); 165 DynamicError err = new DynamicError("Static error in XPath expression supplied to " + name + ": " + 166 e.getMessage().trim()); 167 err.setXPathContext(context); 168 throw err; 169 } 170 ItemType contextItemType = Type.ITEM_TYPE; 171 expr = expr.typeCheck(env, contextItemType); 172 pexpr.stackFrameMap = env.getStackFrameMap(); 173 ExpressionTool.allocateSlots(expr, pexpr.stackFrameMap.getNumberOfVariables(), pexpr.stackFrameMap); 174 pexpr.expression = expr; 175 if (expr instanceof ComputedExpression) { 176 ((ComputedExpression)expr).setParentExpression(this); 177 } 178 return pexpr; 179 180 } 181 182 AtomicValue exprSource = (AtomicValue)argument[0].evaluateItem(context); 183 exprText = exprSource.getStringValue(); 184 IndependentContext env = staticContext.copy(); 185 env.setFunctionLibrary(getExecutable().getFunctionLibrary()); 186 pexpr.expStaticContext = env; 187 pexpr.variables = new Variable[10]; 188 for (int i=1; i<10; i++) { 189 QNameValue qname = new QNameValue("", "", "p"+i); 190 pexpr.variables[i-1] = env.declareVariable(qname); 191 } 192 193 Expression expr; 194 try { 195 expr = ExpressionTool.make(exprText, env, 0, Token.EOF, 1); 196 } catch (XPathException e) { 197 String name = context.getController().getNamePool().getDisplayName(getFunctionNameCode()); 198 DynamicError err = new DynamicError("Static error in XPath expression supplied to " + name + ": " + 199 e.getMessage().trim()); 200 err.setXPathContext(context); 201 throw err; 202 } 203 ItemType contextItemType = Type.ITEM_TYPE; 204 expr = expr.typeCheck(env, contextItemType); 205 pexpr.stackFrameMap = env.getStackFrameMap(); 206 ExpressionTool.allocateSlots(expr, pexpr.stackFrameMap.getNumberOfVariables(), pexpr.stackFrameMap); 207 pexpr.expression = expr; 208 209 return pexpr; 210 } 211 212 215 216 public Item evaluateItem(XPathContext c) throws XPathException { 217 if (operation == EXPRESSION) { 218 PreparedExpression pexpr = prepareExpression(c); 219 return new ObjectValue(pexpr); 220 } else if (operation == EVALUATE_NODE) { 221 XPathContextMajor c2 = c.newCleanContext(); 222 PreparedExpression pexpr = prepareExpression(c2); 223 c2.setOrigin(details); 224 c2.openStackFrame(pexpr.stackFrameMap); 225 return pexpr.expression.evaluateItem(c2); 226 } else { 227 PreparedExpression pexpr = prepareExpression(c); 228 for (int i=1; i<argument.length; i++) { 229 pexpr.variables[i-1].setXPathValue(ExpressionTool.eagerEvaluate(argument[i],c)); 230 } 231 XPathContextMajor c2 = c.newCleanContext(); 232 c2.setOrigin(details); 233 c2.openStackFrame(pexpr.stackFrameMap); 234 c2.setCurrentIterator(c.getCurrentIterator()); 235 return pexpr.expression.evaluateItem(c2); 236 } 237 } 238 239 242 243 public SequenceIterator iterate(XPathContext c) throws XPathException { 244 PreparedExpression pexpr = prepareExpression(c); 245 246 if (operation == EXPRESSION) { 247 return SingletonIterator.makeIterator(new ObjectValue(pexpr)); 248 } else { 249 for (int i=1; i<argument.length; i++) { 250 pexpr.variables[i-1].setXPathValue(ExpressionTool.eagerEvaluate(argument[i],c)); 251 } 252 XPathContextMajor c2 = c.newCleanContext(); 253 c2.setOrigin(details); 254 c2.openStackFrame(pexpr.stackFrameMap); 255 c2.setCurrentIterator(c.getCurrentIterator()); 256 return Value.getIterator( 257 ExpressionTool.lazyEvaluate(pexpr.expression, c2, 1)); 258 } 259 } 260 261 264 265 public int getIntrinsicDependencies() { 266 return StaticProperty.DEPENDS_ON_FOCUS; 267 } 268 269 274 275 public static class PreparedExpression { 276 public IndependentContext expStaticContext; 277 public Expression expression; 278 public Variable[] variables; 279 public SlotManager stackFrameMap; 280 } 281 282 285 286 private void writeObject(ObjectOutputStream s) throws IOException { 287 if (operation==EXPRESSION || operation==EVALUATE) { 288 throw new IOException ("Cannot compile a stylesheet containing calls on saxon:evaluate() or saxon:expression(). " + 289 "Consider using saxon:evaluate-node() instead."); 290 } else { 291 s.defaultWriteObject(); 292 } 293 } 294 295 } 296 297 298 299 300 | Popular Tags |