Source Code Cross Referenced for ComputedExpression.java in  » XML » XPath-Saxon » net » sf » saxon » expr » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » XPath Saxon » net.sf.saxon.expr 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.saxon.expr;
002:
003:        import net.sf.saxon.event.LocationProvider;
004:        import net.sf.saxon.instruct.Executable;
005:        import net.sf.saxon.instruct.Instruction;
006:        import net.sf.saxon.instruct.InstructionDetails;
007:        import net.sf.saxon.om.Item;
008:        import net.sf.saxon.om.SequenceIterator;
009:        import net.sf.saxon.om.SingletonIterator;
010:        import net.sf.saxon.trace.InstructionInfo;
011:        import net.sf.saxon.trace.InstructionInfoProvider;
012:        import net.sf.saxon.trace.Location;
013:        import net.sf.saxon.trans.DynamicError;
014:        import net.sf.saxon.trans.XPathException;
015:        import net.sf.saxon.type.SchemaType;
016:        import net.sf.saxon.value.AtomicValue;
017:        import net.sf.saxon.value.Cardinality;
018:        import net.sf.saxon.value.StringValue;
019:        import net.sf.saxon.sort.IntHashSet;
020:        import net.sf.saxon.sort.IntIterator;
021:
022:        import javax.xml.transform.SourceLocator;
023:        import java.io.Serializable;
024:        import java.util.*;
025:
026:        /**
027:         * <p>This class is an abstract superclass for different kinds of expression. This includes
028:         * XSLT instructions, which are treated just like XPath expressions.
029:         * Every expression is either a constant Value, or a ComputedExpression.</p>
030:         *
031:         * <p>There are three principal methods for evaluating an expression: iterate(), which
032:         * an iterator over the result of the expression as a sequence; evaluateItem(), which returns an
033:         * object that is an instance of net.sf.saxon.om.Item; and process(), which pushes the results of
034:         * the expression to a Receiver. All three methods take an
035:         * XPathContext object to supply the evaluation context; for an expression that is
036:         * a Value, this argument is ignored and may be null. This root class provides an implementation
037:         * of iterate() in terms of evaluateItem() that works only for singleton expressions, and an implementation
038:         * of evaluateItem() in terms of iterate() that works only for non-singleton expressions. Subclasses
039:         * of expression must therefore provide either iterate() or evaluateItem() or process(): they do not have to provide
040:         * all three.</p>
041:         *
042:         * <p>Note that the methods that take an XPathContext argument are run-time methods.
043:         * The methods without such an argument are compile-time methods. Run-time methods must not
044:         * modify the state of the Expression object.</p>
045:         */
046:
047:        public abstract class ComputedExpression implements  Serializable,
048:                Expression, InstructionInfoProvider, Container {
049:
050:            protected int staticProperties = -1;
051:            protected int locationId = -1;
052:            private Container parentExpression;
053:
054:            // A list of slots containing local variables on which this expression is dependent. Calculated
055:            // on demand (lazily) when the expression is used in a closure.
056:
057:            private int[] slotsUsed;
058:
059:            /**
060:             * Get the expression that immediately contains this expression. This method
061:             * returns null for an outermost expression; it also return null in the case
062:             * of literal values. For an XPath expression occurring within an XSLT stylesheet,
063:             * this method returns the XSLT instruction containing the XPath expression.
064:             * @return the expression that contains this expression, if known; return null
065:             * if there is no containing expression or if the containing expression is unknown.
066:             */
067:
068:            public Container getParentExpression() {
069:                return parentExpression;
070:            }
071:
072:            public void setParentExpression(Container parent) {
073:                if (this  == parent) {
074:                    throw new AssertionError("Incestuous relationship!");
075:                }
076:                parentExpression = parent;
077:            }
078:
079:            public void adoptChildExpression(Expression child) {
080:                if (child instanceof  ComputedExpression) {
081:                    ComputedExpression cc = (ComputedExpression) child;
082:                    if (cc.getParentExpression() == this ) {
083:                        return;
084:                    }
085:                    cc.setParentExpression(this );
086:                    if (this .locationId == -1) {
087:                        ExpressionTool.copyLocationInfo(child, this );
088:                    } else if (((ComputedExpression) child).locationId == -1) {
089:                        ExpressionTool.copyLocationInfo(this , child);
090:                    }
091:                }
092:                if (staticProperties != -1) {
093:                    resetStaticProperties();
094:                }
095:            }
096:
097:            /**
098:             * An implementation of Expression must provide at least one of the methods evaluateItem(), iterate(), or process().
099:             * This method indicates which of these methods is prefered.
100:             */
101:
102:            public int getImplementationMethod() {
103:                if (Cardinality.allowsMany(getCardinality())) {
104:                    return ITERATE_METHOD;
105:                } else {
106:                    return EVALUATE_METHOD;
107:                }
108:            }
109:
110:            /**
111:             * Set the location ID on an expression.
112:             */
113:
114:            public void setLocationId(int id) {
115:                locationId = id;
116:            }
117:
118:            /**
119:             * Get the location ID of the expression
120:             */
121:
122:            public final int getLocationId() {
123:                return locationId;
124:            }
125:
126:            /**
127:             * Get the line number of the expression
128:             */
129:
130:            public int getLineNumber() {
131:                if (locationId == -1) {
132:                    if (parentExpression != null) {
133:                        return parentExpression.getLineNumber();
134:                    } else {
135:                        return -1;
136:                    }
137:                }
138:                return locationId & 0xfffff;
139:            }
140:
141:            /**
142:             * Get the column number of the expression
143:             */
144:
145:            public int getColumnNumber() {
146:                return -1;
147:            }
148:
149:            /**
150:             * Get the systemId of the module containing the expression
151:             */
152:
153:            public String getSystemId() {
154:                if (locationId == -1) {
155:                    if (parentExpression != null) {
156:                        return parentExpression.getSystemId();
157:                    } else {
158:                        return null;
159:                    }
160:                }
161:                Executable exec = getExecutable();
162:                if (exec == null) {
163:                    if (parentExpression == null) {
164:                        return null;
165:                    }
166:                    if (parentExpression instanceof  LocationProvider) {
167:                        return ((LocationProvider) parentExpression)
168:                                .getSystemId(locationId);
169:                    }
170:                    return parentExpression.getSystemId();
171:                }
172:                return exec.getLocationMap().getSystemId(locationId);
173:            }
174:
175:            /**
176:             * Get the publicId of the module containing the expression (to satisfy the SourceLocator interface)
177:             */
178:
179:            public final String getPublicId() {
180:                return null;
181:            }
182:
183:            /**
184:             * Get the executable containing this expression
185:             */
186:
187:            public Executable getExecutable() {
188:                Container container = getParentExpression();
189:                if (container == null) {
190:                    return null;
191:                }
192:                if (container == this ) {
193:                    throw new IllegalStateException(
194:                            "Expression cannot contain itself");
195:                } else {
196:                    return container.getExecutable();
197:                }
198:            }
199:
200:            /**
201:             * Get the LocationProvider allowing location identifiers to be resolved.
202:             */
203:
204:            public LocationProvider getLocationProvider() {
205:                Executable exec = getExecutable();
206:                if (exec != null) {
207:                    return exec.getLocationMap();
208:                } else if (getParentExpression() instanceof  LocationProvider) {
209:                    return ((LocationProvider) getParentExpression());
210:                } else {
211:                    return null;
212:                }
213:            }
214:
215:            /**
216:             * Simplify an expression. This performs any static optimization (by rewriting the expression
217:             * as a different expression). The default implementation does nothing.
218:             *
219:             * @exception XPathException if an error is discovered during expression
220:             *     rewriting
221:             * @return the simplified expression
222:             */
223:
224:            public Expression simplify(StaticContext env) throws XPathException {
225:                return this ;
226:            }
227:
228:            /**
229:             * Offer promotion for this subexpression. The offer will be accepted if the subexpression
230:             * is not dependent on the factors (e.g. the context item) identified in the PromotionOffer.
231:             * By default the offer is not accepted - this is appropriate in the case of simple expressions
232:             * such as constant values and variable references where promotion would give no performance
233:             * advantage. This method is always called at compile time.
234:             *
235:             * @param offer details of the offer, for example the offer to move
236:             *     expressions that don't depend on the context to an outer level in
237:             *     the containing expression
238:             * @exception net.sf.saxon.trans.XPathException if any error is detected
239:             * @return if the offer is not accepted, return this expression unchanged.
240:             *      Otherwise return the result of rewriting the expression to promote
241:             *      this subexpression
242:             */
243:
244:            public Expression promote(PromotionOffer offer)
245:                    throws XPathException {
246:                // The following temporary code checks that this method is implemented for all expressions
247:                // that have subexpressions
248:                //        if (iterateSubExpressions().hasNext()) {
249:                //            throw new UnsupportedOperationException("promote is not implemented for " + this.getClass());
250:                //        }
251:                return this ;
252:            }
253:
254:            /**
255:             * Promote a subexpression if possible, and if the expression was changed, carry out housekeeping
256:             * to reset the static properties and correct the parent pointers in the tree
257:             */
258:
259:            public final Expression doPromotion(Expression subexpression,
260:                    PromotionOffer offer) throws XPathException {
261:                Expression e = subexpression.promote(offer);
262:                if (e != subexpression) {
263:                    adoptChildExpression(e);
264:                    resetStaticProperties();
265:                }
266:                return e;
267:            }
268:
269:            /**
270:             * Get the static properties of this expression (other than its type). The result is
271:             * bit-signficant. These properties are used for optimizations. In general, if
272:             * property bit is set, it is true, but if it is unset, the value is unknown.
273:             *
274:             * @return a set of flags indicating static properties of this expression
275:             */
276:
277:            public final int getSpecialProperties() {
278:                if (staticProperties == -1) {
279:                    computeStaticProperties();
280:                }
281:                return staticProperties & StaticProperty.SPECIAL_PROPERTY_MASK;
282:            }
283:
284:            /**
285:             * Compute the static properties. This should only be done once for each
286:             * expression.
287:             */
288:
289:            public final void computeStaticProperties() {
290:                staticProperties = computeDependencies() | computeCardinality()
291:                        | computeSpecialProperties();
292:            }
293:
294:            /**
295:             * Reset the static properties. This should be done whenever the expression is changed in a way that might
296:             * affect the properties. It causes the properties to be recomputed next time they are needed.
297:             */
298:
299:            public final void resetStaticProperties() {
300:                staticProperties = -1;
301:                if (parentExpression instanceof  ComputedExpression) {
302:                    ((ComputedExpression) parentExpression)
303:                            .resetStaticProperties();
304:                }
305:            }
306:
307:            protected abstract int computeCardinality();
308:
309:            public int computeSpecialProperties() {
310:                return 0;
311:            }
312:
313:            /**
314:             * Determine the static cardinality of the expression. This establishes how many items
315:             * there will be in the result of the expression, at compile time (i.e., without
316:             * actually evaluating the result.
317:             *
318:             * @return one of the values Cardinality.ONE_OR_MORE,
319:             *     Cardinality.ZERO_OR_MORE, Cardinality.EXACTLY_ONE,
320:             *     Cardinality.ZERO_OR_ONE, Cardinality.EMPTY. This default
321:             *     implementation returns ZERO_OR_MORE (which effectively gives no
322:             *     information).
323:             */
324:
325:            public int getCardinality() {
326:                if (staticProperties == -1) {
327:                    computeStaticProperties();
328:                }
329:                return staticProperties & StaticProperty.CARDINALITY_MASK;
330:            }
331:
332:            /**
333:             * Determine which aspects of the context the expression depends on. The result is
334:             * a bitwise-or'ed value composed from constants such as XPathContext.VARIABLES and
335:             * XPathContext.CURRENT_NODE. The default implementation combines the intrinsic
336:             * dependencies of this expression with the dependencies of the subexpressions,
337:             * computed recursively. This is overridden for expressions such as FilterExpression
338:             * where a subexpression's dependencies are not necessarily inherited by the parent
339:             * expression.
340:             *
341:             * @return a set of bit-significant flags identifying the dependencies of
342:             *     the expression
343:             */
344:
345:            public int getDependencies() {
346:                // Implemented as a memo function: we only compute the dependencies
347:                // for each expression once
348:                if (staticProperties == -1) {
349:                    computeStaticProperties();
350:                }
351:                return staticProperties & StaticProperty.DEPENDENCY_MASK;
352:            }
353:
354:            /**
355:             * Compute the dependencies of an expression, as the union of the
356:             * dependencies of its subexpressions. (This is overridden for path expressions
357:             * and filter expressions, where the dependencies of a subexpression are not all
358:             * propogated). This method should be called only once, to compute the dependencies;
359:             * after that, getDependencies should be used.
360:             * @return the depencies, as a bit-mask
361:             */
362:
363:            public int computeDependencies() {
364:                int dependencies = (short) getIntrinsicDependencies();
365:                for (Iterator children = iterateSubExpressions(); children
366:                        .hasNext();) {
367:                    dependencies |= (short) ((Expression) children.next())
368:                            .getDependencies();
369:                }
370:                return dependencies;
371:            }
372:
373:            /**
374:             * Determine the intrinsic dependencies of an expression, that is, those which are not derived
375:             * from the dependencies of its subexpressions. For example, position() has an intrinsic dependency
376:             * on the context position, while (position()+1) does not. The default implementation
377:             * of the method returns 0, indicating "no dependencies".
378:             *
379:             * @return a set of bit-significant flags identifying the "intrinsic"
380:             *     dependencies. The flags are documented in class net.sf.saxon.value.StaticProperty
381:             */
382:
383:            public int getIntrinsicDependencies() {
384:                return 0;
385:            }
386:
387:            /**
388:             * Get the immediate sub-expressions of this expression. Default implementation
389:             * returns a zero-length array, appropriate for an expression that has no
390:             * sub-expressions.
391:             * @return an iterator containing the sub-expressions of this expression
392:             */
393:
394:            public Iterator iterateSubExpressions() {
395:                return Collections.EMPTY_LIST.iterator();
396:            }
397:
398:            /**
399:             * Suppress validation on contained element constructors, on the grounds that the parent element
400:             * is already performing validation. The default implementation does nothing.
401:             */
402:
403:            public void suppressValidation(int validationMode) {
404:                // do nothing
405:            }
406:
407:            /**
408:             * Check that any elements and attributes constructed or returned by this expression are acceptable
409:             * in the content model of a given complex type. It's always OK to say yes, since the check will be
410:             * repeated at run-time. The process of checking element and attribute constructors against the content
411:             * model of a complex type also registers the type of content expected of those constructors, so the
412:             * static validation can continue recursively.
413:             */
414:
415:            public void checkPermittedContents(SchemaType parentType,
416:                    StaticContext env, boolean whole) throws XPathException {
417:                return;
418:            }
419:
420:            /**
421:             * Mark tail-recursive calls on stylesheet functions. For most expressions, this does nothing.
422:             *
423:             * @return true if a tail recursive call was found and if this call
424:             *     accounts for the whole of the value.
425:             */
426:
427:            public boolean markTailFunctionCalls() {
428:                return false;
429:            }
430:
431:            /**
432:             * Get the local variables (identified by their slot numbers) on which this expression depends.
433:             * Should only be called if the caller has established that there is a dependency on local variables.
434:             */
435:
436:            public int[] getSlotsUsed() {
437:                if (slotsUsed != null) {
438:                    return slotsUsed;
439:                }
440:                IntHashSet slots = new IntHashSet(10);
441:                gatherSlotsUsed(this , slots);
442:                slotsUsed = new int[slots.size()];
443:                int i = 0;
444:                IntIterator iter = slots.iterator();
445:                while (iter.hasNext()) {
446:                    slotsUsed[i++] = iter.next();
447:                }
448:                Arrays.sort(slotsUsed);
449:                return slotsUsed;
450:            }
451:
452:            private static void gatherSlotsUsed(Expression exp, IntHashSet slots) {
453:                if (exp instanceof  VariableReference) {
454:                    Binding binding = ((VariableReference) exp).getBinding();
455:                    if (!binding.isGlobal()) {
456:                        int slot = binding.getLocalSlotNumber();
457:                        if (slot != -1) {
458:                            if (!slots.contains(slot)) {
459:                                slots.add(slot);
460:                            }
461:                        }
462:                    }
463:                } else {
464:                    Iterator iter = exp.iterateSubExpressions();
465:                    while (iter.hasNext()) {
466:                        Expression sub = (Expression) iter.next();
467:                        gatherSlotsUsed(sub, slots);
468:                    }
469:                }
470:            }
471:
472:            /**
473:             * Evaluate an expression as a single item. This always returns either a single Item or
474:             * null (denoting the empty sequence). No conversion is done. This method should not be
475:             * used unless the static type of the expression is a subtype of "item" or "item?": that is,
476:             * it should not be called if the expression may return a sequence. There is no guarantee that
477:             * this condition will be detected.
478:             *
479:             * @param context The context in which the expression is to be evaluated
480:             * @exception XPathException if any dynamic error occurs evaluating the
481:             *     expression
482:             * @return the node or atomic value that results from evaluating the
483:             *     expression; or null to indicate that the result is an empty
484:             *     sequence
485:             */
486:
487:            public Item evaluateItem(XPathContext context)
488:                    throws XPathException {
489:                return iterate(context).next();
490:            }
491:
492:            /**
493:             * Evaluate an expression as a String. This function must only be called in contexts
494:             * where it is known that the expression will return a single string (or where an empty sequence
495:             * is to be treated as a zero-length string). Implementations should not attempt to convert
496:             * the result to a string, other than converting () to "". This method is used mainly to
497:             * evaluate expressions produced by compiling an attribute value template.
498:             *
499:             * @exception XPathException if any dynamic error occurs evaluating the
500:             *     expression
501:             * @exception ClassCastException if the result type of the
502:             *     expression is not xs:string?
503:             * @param context The context in which the expression is to be evaluated
504:             * @return the value of the expression, evaluated in the current context.
505:             *     The expression must return a string or (); if the value of the
506:             *     expression is (), this method returns "".
507:             */
508:
509:            public String evaluateAsString(XPathContext context)
510:                    throws XPathException {
511:                Item o = evaluateItem(context);
512:                if (o instanceof  AtomicValue
513:                        && !((AtomicValue) o).hasBuiltInType()) {
514:                    o = ((AtomicValue) o).getPrimitiveValue();
515:                }
516:                StringValue value = (StringValue) o; // the ClassCastException is deliberate
517:                if (value == null)
518:                    return "";
519:                return value.getStringValue();
520:            }
521:
522:            /**
523:             * Return an Iterator to iterate over the values of a sequence. The value of every
524:             * expression can be regarded as a sequence, so this method is supported for all
525:             * expressions. This default implementation handles iteration for expressions that
526:             * return singleton values: for non-singleton expressions, the subclass must
527:             * provide its own implementation.
528:             *
529:             * @exception XPathException if any dynamic error occurs evaluating the
530:             *     expression
531:             * @param context supplies the context for evaluation
532:             * @return a SequenceIterator that can be used to iterate over the result
533:             *     of the expression
534:             */
535:
536:            public SequenceIterator iterate(XPathContext context)
537:                    throws XPathException {
538:                Item value = evaluateItem(context);
539:                return SingletonIterator.makeIterator(value);
540:            }
541:
542:            /**
543:             * Get the effective boolean value of the expression. This returns false if the value
544:             * is the empty sequence, a zero-length string, a number equal to zero, or the boolean
545:             * false. Otherwise it returns true.
546:             *
547:             * @param context The context in which the expression is to be evaluated
548:             * @exception XPathException if any dynamic error occurs evaluating the
549:             *     expression
550:             * @return the effective boolean value
551:             */
552:
553:            public boolean effectiveBooleanValue(XPathContext context)
554:                    throws XPathException {
555:                return ExpressionTool.effectiveBooleanValue(iterate(context));
556:            }
557:
558:            /**
559:             * Process the instruction, without returning any tail calls
560:             * @param context The dynamic context, giving access to the current node,
561:             * the current variables, etc.
562:             */
563:
564:            public void process(XPathContext context) throws XPathException {
565:                int m = getImplementationMethod();
566:
567:                if ((m & EVALUATE_METHOD) != 0) {
568:                    Item item = evaluateItem(context);
569:                    // Need to cater for it being a tailcall returned from a function
570:                    Instruction.appendItem(item, context.getReceiver(),
571:                            locationId);
572:
573:                } else if ((m & ITERATE_METHOD) != 0) {
574:
575:                    SequenceIterator iter = iterate(context);
576:                    try {
577:                        while (true) {
578:                            Item it = iter.next();
579:                            if (it == null)
580:                                break;
581:                            // Need to cater for it being a tailcall returned from a function
582:                            Instruction.appendItem(it, context.getReceiver(),
583:                                    locationId);
584:                        }
585:                    } catch (XPathException e) {
586:                        if (e.getLocator() == null) {
587:                            e.setLocator(this );
588:                        }
589:                        throw e;
590:                    }
591:
592:                } else {
593:                    dynamicError(
594:                            "process() is not implemented in the subclass "
595:                                    + this .getClass(), context);
596:                }
597:            }
598:
599:            /**
600:             * Method used in subclasses to signal a dynamic error
601:             */
602:
603:            protected void dynamicError(String message, XPathContext context)
604:                    throws DynamicError {
605:                DynamicError err = new DynamicError(message, getSourceLocator());
606:                err.setXPathContext(context);
607:                throw err;
608:            }
609:
610:            /**
611:             * Method used in subclasses to signal a dynamic error
612:             */
613:
614:            protected void dynamicError(String message, String code,
615:                    XPathContext context) throws DynamicError {
616:                DynamicError err = new DynamicError(message, getSourceLocator());
617:                err.setXPathContext(context);
618:                err.setErrorCode(code);
619:                throw err;
620:            }
621:
622:            /**
623:             * Method used in subclasses to signal a runtime type error
624:             */
625:
626:            protected void typeError(String message, XPathContext context)
627:                    throws DynamicError {
628:                DynamicError e = new DynamicError(message, getSourceLocator());
629:                e.setIsTypeError(true);
630:                e.setXPathContext(context);
631:                throw e;
632:            }
633:
634:            /**
635:             * Method used in subclasses to signal a runtime type error
636:             */
637:
638:            protected void typeError(String message, String errorCode,
639:                    XPathContext context) throws DynamicError {
640:                DynamicError e = new DynamicError(message, getSourceLocator());
641:                e.setIsTypeError(true);
642:                e.setErrorCode(errorCode);
643:                e.setXPathContext(context);
644:                throw e;
645:            }
646:
647:            /**
648:             * Get a SourceLocator for this expression
649:             */
650:
651:            private SourceLocator getSourceLocator() {
652:                return ExpressionTool.getLocator(this );
653:            }
654:
655:            /**
656:             * Get InstructionInfo for this expression
657:             */
658:
659:            public InstructionInfo getInstructionInfo() {
660:                InstructionDetails details = new InstructionDetails();
661:                details.setConstructType(getConstructType());
662:                details.setProperty("expression", this );
663:                details.setSystemId(getSystemId());
664:                details.setLineNumber(getLineNumber());
665:                details.setColumnNumber(getColumnNumber());
666:                if (this  instanceof  Assignation) {
667:                    details.setObjectNameCode(((Assignation) this )
668:                            .getVariableNameCode());
669:                }
670:                return details;
671:            }
672:
673:            /**
674:             * Get the type of this expression for use in tracing and diagnostics
675:             * @return the type of expression, as enumerated in class {@link Location}
676:             */
677:
678:            protected int getConstructType() {
679:                return Location.XPATH_EXPRESSION;
680:            }
681:
682:            /**
683:             * Diagnostic method: search the tree for an expression whose parent expression is incorrectly set
684:             */
685:
686:            public boolean hasBadParentPointer() {
687:                Iterator iter = iterateSubExpressions();
688:                while (iter.hasNext()) {
689:                    Expression exp = (Expression) iter.next();
690:                    if (exp instanceof  ComputedExpression) {
691:                        if (this  != exp.getParentExpression()) {
692:                            System.err.println("Bad parent pointer to "
693:                                    + exp.getParentExpression() + " found in "
694:                                    + exp);
695:                            return true;
696:                        }
697:                        if (((ComputedExpression) exp).hasBadParentPointer()) {
698:                            System.err.println("Found in " + exp);
699:                            return true;
700:                        }
701:                    }
702:                }
703:                return false;
704:            }
705:
706:        }
707:
708:        //
709:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
710:        // you may not use this file except in compliance with the License. You may obtain a copy of the
711:        // License at http://www.mozilla.org/MPL/
712:        //
713:        // Software distributed under the License is distributed on an "AS IS" basis,
714:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
715:        // See the License for the specific language governing rights and limitations under the License.
716:        //
717:        // The Original Code is: all this file.
718:        //
719:        // The Initial Developer of the Original Code is Michael H. Kay.
720:        //
721:        // Contributor(s): Michael Kay
722:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.