KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > functions > Id


1 package net.sf.saxon.functions;
2 import net.sf.saxon.expr.*;
3 import net.sf.saxon.om.*;
4 import net.sf.saxon.sort.DocumentOrderIterator;
5 import net.sf.saxon.sort.LocalOrderComparer;
6 import net.sf.saxon.trans.XPathException;
7 import net.sf.saxon.value.AtomicValue;
8 import net.sf.saxon.value.Cardinality;
9
10
11 /**
12 * The XPath id() function
13 * XPath 2.0 version: accepts any sequence as the first parameter; each item in the sequence
14 * is taken as an IDREFS value, that is, a space-separated list of ID values.
15  * Also accepts an optional second argument to identify the target document, this
16  * defaults to the context node.
17 */

18
19
20 public class Id extends SystemFunction {
21
22     private boolean isSingletonId = false;
23
24     /**
25     * Simplify: add a second implicit argument, the context document
26     */

27
28      public Expression simplify(StaticContext env) throws XPathException {
29         Id id = (Id)super.simplify(env);
30         if (argument.length == 1) {
31             id.addContextDocumentArgument(1, "id");
32         }
33         return id;
34     }
35
36     /**
37      * Static analysis: prevent sorting of the argument
38      */

39
40     public void checkArguments(StaticContext env) throws XPathException {
41         super.checkArguments(env);
42         Optimizer opt = env.getConfiguration().getOptimizer();
43         argument[0] = ExpressionTool.unsorted(opt, argument[0], false);
44         isSingletonId = !Cardinality.allowsMany(argument[0].getCardinality());
45     }
46
47     /**
48     * preEvaluate: this method suppresses compile-time evaluation by doing nothing
49     */

50
51     public Expression preEvaluate(StaticContext env) {
52         return this;
53     }
54
55     /**
56     * Get the static properties of this expression (other than its type). The result is
57     * bit-signficant. These properties are used for optimizations. In general, if
58     * property bit is set, it is true, but if it is unset, the value is unknown.
59     */

60
61     public int computeSpecialProperties() {
62         int prop = StaticProperty.ORDERED_NODESET |
63                 StaticProperty.SINGLE_DOCUMENT_NODESET |
64                 StaticProperty.NON_CREATIVE;
65         if ((getNumberOfArguments() == 1) ||
66                 (argument[1].getSpecialProperties() & StaticProperty.CONTEXT_DOCUMENT_NODESET) != 0) {
67             prop |= StaticProperty.CONTEXT_DOCUMENT_NODESET;
68         }
69         return prop;
70     }
71
72     /**
73     * Evaluate the function to return an iteration of selected nodes.
74     */

75
76     public SequenceIterator iterate(XPathContext context) throws XPathException {
77
78         NodeInfo arg1 = (NodeInfo)argument[1].evaluateItem(context);
79         arg1 = arg1.getRoot();
80         if (!(arg1 instanceof DocumentInfo)) {
81             dynamicError("In the id() function," +
82                             " the tree being searched must be one whose root is a document node", context);
83             return null;
84         }
85         DocumentInfo doc = (DocumentInfo)arg1;
86
87         if (isSingletonId) {
88             AtomicValue arg = (AtomicValue)argument[0].evaluateItem(context);
89             if (arg==null) {
90                 return EmptyIterator.getInstance();
91             }
92             String JavaDoc idrefs = arg.getStringValue();
93             if (idrefs.indexOf(0x20)>=0 ||
94                     idrefs.indexOf(0x09)>=0 ||
95                     idrefs.indexOf(0x0a)>=0 ||
96                     idrefs.indexOf(0x0d)>=0) {
97                 StringTokenIterator tokens = new StringTokenIterator(idrefs);
98                 IdMappingFunction map = new IdMappingFunction();
99                 map.document = doc;
100                 SequenceIterator result = new MappingIterator(tokens, map, null);
101                 return new DocumentOrderIterator(result, LocalOrderComparer.getInstance());
102             } else {
103                 return SingletonIterator.makeIterator(doc.selectID(idrefs));
104             }
105         } else {
106             SequenceIterator idrefs = argument[0].iterate(context);
107             IdMappingFunction map = new IdMappingFunction();
108             map.document = doc;
109             SequenceIterator result = new MappingIterator(idrefs, map, null);
110             return new DocumentOrderIterator(result, LocalOrderComparer.getInstance());
111         }
112     }
113
114     private static class IdMappingFunction implements MappingFunction {
115
116         public DocumentInfo document;
117
118         /**
119         * Evaluate the function for a single string value
120         * (implements the MappingFunction interface)
121         */

122
123         public Object JavaDoc map(Item item, XPathContext c) throws XPathException {
124
125             String JavaDoc idrefs = item.getStringValue().trim();
126
127             // If this value contains a space, we need to break it up into its
128
// separate tokens; if not, we can process it directly
129

130             if (idrefs.indexOf(0x20)>=0 ||
131                     idrefs.indexOf(0x09)>=0 ||
132                     idrefs.indexOf(0x0a)>=0 ||
133                     idrefs.indexOf(0x0d)>=0) {
134                 StringTokenIterator tokens = new StringTokenIterator(idrefs);
135                 IdMappingFunction submap = new IdMappingFunction();
136                 submap.document = document;
137                 return new MappingIterator(tokens, submap, null);
138
139             } else {
140                 return document.selectID(idrefs);
141             }
142         }
143     }
144
145 }
146
147
148
149
150 //
151
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
152
// you may not use this file except in compliance with the License. You may obtain a copy of the
153
// License at http://www.mozilla.org/MPL/
154
//
155
// Software distributed under the License is distributed on an "AS IS" basis,
156
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
157
// See the License for the specific language governing rights and limitations under the License.
158
//
159
// The Original Code is: all this file.
160
//
161
// The Initial Developer of the Original Code is Michael H. Kay.
162
//
163
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
164
//
165
// Contributor(s): none.
166
//
167
Popular Tags