001: package net.sf.saxon.expr;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.om.NamePool;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.om.SingletonIterator;
007: import net.sf.saxon.trans.StaticError;
008: import net.sf.saxon.trans.XPathException;
009: import net.sf.saxon.type.ItemType;
010: import net.sf.saxon.type.Type;
011: import net.sf.saxon.type.TypeHierarchy;
012:
013: import java.io.PrintStream;
014:
015: /**
016: * This class represents the expression "(dot)", which always returns the context item.
017: * This may be a AtomicValue or a Node.
018: */
019:
020: public final class ContextItemExpression extends ComputedExpression {
021:
022: ItemType itemType = Type.ITEM_TYPE;
023:
024: public ContextItemExpression() {
025: }
026:
027: /**
028: * Type-check the expression.
029: */
030:
031: public Expression typeCheck(StaticContext env,
032: ItemType contextItemType) throws XPathException {
033: if (contextItemType == null) {
034: StaticError err = new StaticError(
035: "The context item is undefined at this point");
036: err.setErrorCode("XPDY0002");
037: err.setIsTypeError(true);
038: err.setLocator(this );
039: throw err;
040: }
041: itemType = contextItemType;
042: return this ;
043: }
044:
045: /**
046: * Perform optimisation of an expression and its subexpressions.
047: * <p/>
048: * <p>This method is called after all references to functions and variables have been resolved
049: * to the declaration of the function or variable, and after all type checking has been done.</p>
050: *
051: * @param opt the optimizer in use. This provides access to supporting functions; it also allows
052: * different optimization strategies to be used in different circumstances.
053: * @param env the static context of the expression
054: * @param contextItemType the static type of "." at the point where this expression is invoked.
055: * The parameter is set to null if it is known statically that the context item will be undefined.
056: * If the type of the context item is not known statically, the argument is set to
057: * {@link net.sf.saxon.type.Type#ITEM_TYPE}
058: * @return the original expression, rewritten if appropriate to optimize execution
059: * @throws net.sf.saxon.trans.StaticError if an error is discovered during this phase
060: * (typically a type error)
061: */
062:
063: public Expression optimize(Optimizer opt, StaticContext env,
064: ItemType contextItemType) throws XPathException {
065: // In XSLT, we don't catch this error at the typeCheck() phase because it's done one XPath expression
066: // at a time. So we repeat the check here.
067: return typeCheck(env, contextItemType);
068: }
069:
070: /**
071: * Determine the item type
072: * @param th
073: */
074:
075: public ItemType getItemType(TypeHierarchy th) {
076: return itemType;
077: }
078:
079: /**
080: * Get the static cardinality
081: */
082:
083: public int computeCardinality() {
084: return StaticProperty.EXACTLY_ONE;
085: }
086:
087: /**
088: * Determine the special properties of this expression
089: * @return {@link StaticProperty#NON_CREATIVE}
090: */
091:
092: public int computeSpecialProperties() {
093: int p = super .computeSpecialProperties();
094: return p | StaticProperty.NON_CREATIVE;
095: }
096:
097: /**
098: * Is this expression the same as another expression?
099: */
100:
101: public boolean equals(Object other) {
102: return (other instanceof ContextItemExpression);
103: }
104:
105: /**
106: * get HashCode for comparing two expressions
107: */
108:
109: public int hashCode() {
110: return "ContextItemExpression".hashCode();
111: }
112:
113: public int getIntrinsicDependencies() {
114: return StaticProperty.DEPENDS_ON_CONTEXT_ITEM;
115: }
116:
117: /**
118: * Iterate over the value of the expression
119: */
120:
121: public SequenceIterator iterate(XPathContext context)
122: throws XPathException {
123: Item item = context.getContextItem();
124: if (item == null) {
125: dynamicError("The context item is not set", context);
126: }
127: return SingletonIterator.makeIterator(item);
128: }
129:
130: /**
131: * Evaluate the expression
132: */
133:
134: public Item evaluateItem(XPathContext context)
135: throws XPathException {
136: Item item = context.getContextItem();
137: if (item == null) {
138: dynamicError("The context item is not set", "FONC0001",
139: context);
140: }
141: return item;
142: }
143:
144: /**
145: * Diagnostic print of expression structure
146: */
147:
148: public void display(int level, NamePool pool, PrintStream out) {
149: out.println(ExpressionTool.indent(level) + '.');
150: }
151:
152: }
153:
154: //
155: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
156: // you may not use this file except in compliance with the License. You may obtain a copy of the
157: // License at http://www.mozilla.org/MPL/
158: //
159: // Software distributed under the License is distributed on an "AS IS" basis,
160: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
161: // See the License for the specific language governing rights and limitations under the License.
162: //
163: // The Original Code is: all this file.
164: //
165: // The Initial Developer of the Original Code is Michael H. Kay.
166: //
167: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
168: //
169: // Contributor(s): none.
170: //
|