KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > expr > ItemChecker


1 package net.sf.saxon.expr;
2 import net.sf.saxon.om.Item;
3 import net.sf.saxon.om.NamePool;
4 import net.sf.saxon.om.SequenceIterator;
5 import net.sf.saxon.trans.StaticError;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.type.AnyItemType;
8 import net.sf.saxon.type.ItemType;
9 import net.sf.saxon.type.Type;
10 import net.sf.saxon.value.Value;
11 import net.sf.saxon.value.Cardinality;
12 import net.sf.saxon.event.SequenceReceiver;
13 import net.sf.saxon.event.TypeCheckingFilter;
14 import net.sf.saxon.pattern.DocumentNodeTest;
15
16 /**
17 * A ItemChecker implements the item type checking of "treat as": that is,
18 * it returns the supplied sequence, checking that all its items are of the correct type
19 */

20
21 public final class ItemChecker extends UnaryExpression {
22
23     private ItemType requiredItemType;
24     private RoleLocator role;
25
26     /**
27     * Constructor
28     */

29
30     public ItemChecker(Expression sequence, ItemType itemType, RoleLocator role) {
31         super(sequence);
32         this.requiredItemType = itemType;
33         this.role = role;
34         adoptChildExpression(sequence);
35     }
36
37     /**
38      * Get the required type
39      */

40
41     public ItemType getRequiredType() {
42         return requiredItemType;
43     }
44
45     /**
46     * Simplify an expression
47     */

48
49      public Expression simplify(StaticContext env) throws XPathException {
50         operand = operand.simplify(env);
51         if (requiredItemType instanceof AnyItemType) {
52             return operand;
53         }
54         return this;
55     }
56
57     /**
58     * Type-check the expression
59     */

60
61     public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
62         operand = operand.typeCheck(env, contextItemType);
63         // When analyze is called a second time, we might have more information...
64

65         ItemType supplied = operand.getItemType();
66         int relation = Type.relationship(requiredItemType, supplied);
67         if (relation == Type.SAME_TYPE || relation == Type.SUBSUMES) {
68             return operand;
69         }
70         if (relation == Type.DISJOINT) {
71 // String message = "Required type of " + role.getMessage() +
72
// " is " + requiredItemType.toString(env.getNamePool()) +
73
// "; supplied value has type " +
74
// operand.getItemType().toString(env.getNamePool());
75
String JavaDoc message = role.composeErrorMessage(requiredItemType, operand.getItemType(), env.getNamePool());
76             StaticError err = new StaticError(message);
77             err.setErrorCode(role.getErrorCode());
78             err.setLocator(this);
79             err.setIsTypeError(true);
80             throw err;
81         }
82         return this;
83     }
84
85     /**
86      * An implementation of Expression must provide at least one of the methods evaluateItem(), iterate(), or process().
87      * This method indicates which of these methods is provided. This implementation provides both iterate() and
88      * process() methods natively.
89      */

90
91     public int getImplementationMethod() {
92         int m = ITERATE_METHOD | PROCESS_METHOD;
93         if (!Cardinality.allowsMany(getCardinality())) {
94             m |= EVALUATE_METHOD;
95         }
96         return m;
97     }
98
99
100     /**
101     * Iterate over the sequence of values
102     */

103
104     public SequenceIterator iterate(XPathContext context) throws XPathException {
105         SequenceIterator base = operand.iterate(context);
106         ItemCheckMappingFunction map = new ItemCheckMappingFunction();
107         map.externalContext = context;
108         return new MappingIterator(base, map, null);
109     }
110
111     /**
112     * Mapping function: this is used only if the expression does not allow a sequence of more than
113     * one item.
114     */

115     private class ItemCheckMappingFunction implements MappingFunction {
116         public XPathContext externalContext;
117         public Object JavaDoc map(Item item, XPathContext nullcontext) throws XPathException {
118             testConformance(item, externalContext);
119             return item;
120         }
121     }
122
123     /**
124     * Evaluate as an Item.
125     */

126
127     public Item evaluateItem(XPathContext context) throws XPathException {
128         Item item = operand.evaluateItem(context);
129         if (item==null) return null;
130         testConformance(item, context);
131         return item;
132     }
133
134     /**
135      * Process the instruction, without returning any tail calls
136      *
137      * @param context The dynamic context, giving access to the current node,
138      * the current variables, etc.
139      */

140
141     public void process(XPathContext context) throws XPathException {
142         Expression next = operand;
143         int card = StaticProperty.ALLOWS_ZERO_OR_MORE;
144         if (next instanceof CardinalityChecker) {
145             card = ((CardinalityChecker)next).getRequiredCardinality();
146             next = ((CardinalityChecker)next).getBaseExpression();
147         }
148         if ((next.getImplementationMethod() & PROCESS_METHOD) != 0 && !(requiredItemType instanceof DocumentNodeTest)) {
149             SequenceReceiver out = context.getReceiver();
150             TypeCheckingFilter filter = new TypeCheckingFilter();
151             filter.setUnderlyingReceiver(out);
152             filter.setPipelineConfiguration(out.getPipelineConfiguration());
153             filter.setRequiredType(requiredItemType, card, role);
154             context.setReceiver(filter);
155             next.process(context);
156             filter.close();
157             context.setReceiver(filter);
158         } else {
159             super.process(context);
160         }
161     }
162
163
164
165     private void testConformance(Item item, XPathContext context) throws XPathException {
166         if (!requiredItemType.matchesItem(item)) {
167             String JavaDoc message;
168             if (context == null) {
169                 // no name pool available
170
message = "Supplied value of type " + Type.displayTypeName(item) +
171                         " does not match the required type of " + role.getMessage();
172             } else {
173                 NamePool pool = context.getController().getNamePool();
174                 message = role.composeErrorMessage(requiredItemType, Value.asValue(item).getItemType(), pool);
175 // message = "Required type of " + role.getMessage() +
176
// " is " + requiredItemType.toString(pool) +
177
// "; supplied value has type " + Type.displayTypeName(item);
178
}
179             String JavaDoc errorCode = role.getErrorCode();
180             if ("XPDY0050".equals(errorCode)) {
181                 // error in "treat as" assertion
182
dynamicError(message, errorCode, context);
183             } else {
184                 typeError(message, errorCode, context);
185             }
186         }
187     }
188
189     /**
190     * Determine the data type of the items returned by the expression
191     */

192
193     public ItemType getItemType() {
194         // TODO: take the intersection of the required type with the static type of the operand
195
return requiredItemType;
196     }
197
198     /**
199      * Is this expression the same as another expression?
200      */

201
202     public boolean equals(Object JavaDoc other) {
203         return super.equals(other) &&
204                 requiredItemType == ((ItemChecker)other).requiredItemType;
205     }
206
207     /**
208      * Give a string representation of the operator for use in diagnostics
209      * @return the operator, as a string
210      */

211
212     protected String JavaDoc displayOperator(NamePool pool) {
213         return "treat as " + requiredItemType.toString(pool);
214     }
215
216 }
217
218
219
220 //
221
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
222
// you may not use this file except in compliance with the License. You may obtain a copy of the
223
// License at http://www.mozilla.org/MPL/
224
//
225
// Software distributed under the License is distributed on an "AS IS" basis,
226
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
227
// See the License for the specific language governing rights and limitations under the License.
228
//
229
// The Original Code is: all this file.
230
//
231
// The Initial Developer of the Original Code is Michael H. Kay
232
//
233
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
234
//
235
// Contributor(s): none.
236
//
237
Popular Tags