KickJava   Java API By Example, From Geeks To Geeks.

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


1 package net.sf.saxon.functions;
2 import net.sf.saxon.expr.*;
3 import net.sf.saxon.om.NamePool;
4 import net.sf.saxon.om.NamespaceConstant;
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.AtomicType;
9 import net.sf.saxon.type.ItemType;
10 import net.sf.saxon.value.SequenceType;
11
12 import java.io.PrintStream JavaDoc;
13 import java.util.ArrayList JavaDoc;
14
15
16 /**
17 * Abstract superclass for system-defined and user-defined functions
18 */

19
20 public abstract class SystemFunction extends FunctionCall {
21
22     /**
23     * Make a system function (one in the standard function namespace).
24     * @param name The local name of the function. It may also be a lexical QName for
25      * a recognized built-in function, e.g. saxon:evaluate, in which case the prefix is hard-coded.
26     * @return a FunctionCall that implements this function, if it
27     * exists, or null if the function is unknown.
28     */

29
30     public static FunctionCall makeSystemFunction(String JavaDoc name, int arity, NamePool pool) {
31         StandardFunction.Entry entry = StandardFunction.getFunction(name, arity);
32         if (entry==null) {
33             return null;
34         }
35         Class JavaDoc functionClass = entry.implementationClass;
36         try {
37             SystemFunction f = (SystemFunction)functionClass.newInstance();
38             f.setDetails(entry);
39             //if (name.startsWith("saxon")) {
40
// f.setFunctionNameCode(pool.allocate("saxon", NamespaceConstant.SAXON, name.substring(6)));
41
//} else {
42
f.setFunctionNameCode(pool.allocate("", NamespaceConstant.FN, name));
43             //}
44
return f;
45         } catch (IllegalAccessException JavaDoc err) {
46             return null;
47         } catch (InstantiationException JavaDoc err) {
48             return null;
49         }
50     }
51
52     /**
53      *
54      */

55
56     private StandardFunction.Entry details;
57     protected int operation;
58
59     /**
60     * Set the details of this type of function
61     */

62
63     public void setDetails(StandardFunction.Entry entry) {
64         details = entry;
65         operation = details.opcode;
66     }
67
68     /**
69     * Get the details
70     */

71
72     protected StandardFunction.Entry getDetails() {
73         return details;
74     }
75
76     /**
77      * Type-check the expression. This also calls preEvaluate() to evaluate the function
78      * if all the arguments are constant; functions that do not require this behavior
79      * can override the preEvaluate method.
80      */

81
82 // public Expression typeCheck(StaticContext env, ItemType contextItemType) throws XPathException {
83
// return super.typeCheck(env, contextItemType); //To change body of overridden methods use File | Settings | File Templates.
84
// }
85

86     /**
87     * Method called during static type checking
88     */

89
90     public void checkArguments(StaticContext env) throws XPathException {
91         checkArgumentCount(details.minArguments, details.maxArguments, env);
92         for (int i=0; i<argument.length; i++) {
93             checkArgument(i, env);
94         }
95     }
96
97     /**
98     * Perform static type checking on an argument to a function call, and add
99     * type conversion logic where necessary.
100     */

101
102     private void checkArgument(int arg, StaticContext env) throws XPathException {
103         RoleLocator role = new RoleLocator(RoleLocator.FUNCTION, new Integer JavaDoc(getFunctionNameCode()), arg, env.getNamePool());
104         role.setSourceLocator(this);
105         argument[arg] = TypeChecker.staticTypeCheck(
106                                 argument[arg],
107                                 getRequiredType(arg),
108                                 env.isInBackwardsCompatibleMode(),
109                                 role, env);
110         argument[arg] = argument[arg].simplify(env);
111     }
112
113     /**
114     * Get the required type of the nth argument
115     */

116
117     protected SequenceType getRequiredType(int arg) {
118         return details.argumentTypes[arg];
119         // this is overridden for concat()
120
}
121
122     /**
123     * Determine the item type of the value returned by the function
124     */

125
126     public ItemType getItemType() {
127         if (details == null) {
128             // probably an unresolved function call
129
return AnyItemType.getInstance();
130         }
131         ItemType type = details.itemType;
132         if (type == StandardFunction.SAME_AS_FIRST_ARGUMENT) {
133             if (argument.length > 0) {
134                 return argument[0].getItemType();
135             } else {
136                 return AnyItemType.getInstance();
137                 // if there is no first argument, an error will be reported
138
}
139         } else {
140             return type;
141         }
142     }
143
144     /**
145     * Determine the cardinality of the function.
146     */

147
148     public int computeCardinality() {
149         if (details==null) {
150             //System.err.println("**** No details for " + getClass() + " at " + this);
151
return StaticProperty.ALLOWS_ZERO_OR_MORE;
152         }
153         return details.cardinality;
154     }
155
156     /**
157      * Determine the special properties of this expression. The general rule
158      * is that a system function call is non-creative if its return type is
159      * atomic, or if all its arguments are non-creative. This is overridden
160      * for the generate-id() function, which is considered creative if
161      * its operand is creative (because the result depends on the
162      * identity of the operand)
163      */

164
165     public int computeSpecialProperties() {
166         int p = super.computeSpecialProperties();
167         if (getItemType() instanceof AtomicType) {
168             return p | StaticProperty.NON_CREATIVE;
169         }
170         for (int i=0; i<argument.length; i++) {
171             if ((argument[i].getSpecialProperties() & StaticProperty.NON_CREATIVE) != 0) {
172                 // the argument is creative
173
return p;
174             }
175         }
176         return p | StaticProperty.NON_CREATIVE;
177     }
178
179     /**
180     * Set "." as the default value for the first and only argument. Called from subclasses.
181     */

182
183     protected final void useContextItemAsDefault() {
184         if (argument.length==0) {
185             argument = new Expression[1];
186             argument[0] = new ContextItemExpression();
187             ExpressionTool.copyLocationInfo(this, argument[0]);
188             ((ContextItemExpression)argument[0]).setParentExpression(this);
189         }
190         // Note that the extra argument is added before type-checking takes place. The
191
// type-checking will add any necessary checks to ensure that the context item
192
// is a node, in cases where this is required.
193
}
194
195     /**
196     * Add an implicit argument referring to the context document. Called by functions such as
197     * id() and key() that take the context document as an implicit argument
198     */

199
200     protected final void addContextDocumentArgument(int pos, String JavaDoc augmentedName)
201     throws StaticError {
202         if (argument.length > pos) {
203             return;
204             // this can happen during optimization, if the extra argument is already present
205
}
206         if (argument.length != pos) {
207             throw new StaticError("Too few arguments in call to " + augmentedName + "() function");
208         }
209         Expression[] newArgs = new Expression[pos+1];
210         System.arraycopy(argument, 0, newArgs, 0, argument.length);
211         final RootExpression rootExpression = new RootExpression();
212         ExpressionTool.copyLocationInfo(this, newArgs[pos]);
213         rootExpression.setParentExpression(this);
214         newArgs[pos] = rootExpression;
215         argument = newArgs;
216         setDetails(StandardFunction.getFunction(augmentedName, newArgs.length));
217     }
218
219     /**
220     * Diagnostic print of expression structure
221     */

222
223     public void display(int level, NamePool pool, PrintStream JavaDoc out) {
224         out.println(ExpressionTool.indent(level) + "function " + getDisplayName(pool));
225         for (int a=0; a<argument.length; a++) {
226             argument[a].display(level+1, pool, out);
227         }
228     }
229
230     /**
231      * The main() method of this class is not intended to be called, it merely
232      * tells the code inspection tools in IDEA that the constructors of each
233      * function class are actual entry points
234      */

235
236     public static void main(String JavaDoc[] args) throws Exception JavaDoc {
237         ArrayList JavaDoc a = new ArrayList JavaDoc(20);
238         a.add(new Adjust());
239         a.add(new Aggregate());
240         a.add(new Available());
241         a.add(new BaseURI());
242         a.add(new BooleanFn());
243         a.add(new Collection());
244         a.add(new Compare());
245         a.add(new Component());
246         a.add(new Concat());
247         a.add(new Contains());
248         a.add(new Current());
249         a.add(new CurrentDateTime());
250         a.add(new CurrentGroup());
251         a.add(new Data());
252         a.add(new DeepEqual());
253         a.add(new DefaultCollation());
254         a.add(new DistinctValues());
255         a.add(new Doc());
256         a.add(new Document());
257         a.add(new Error JavaDoc());
258         a.add(new EscapeURI());
259         a.add(new Evaluate());
260         a.add(new Existence());
261         a.add(new ForceCase());
262         a.add(new FormatDate());
263         a.add(new FormatNumber2());
264         a.add(new Id());
265         a.add(new Idref());
266         a.add(new IndexOf());
267         a.add(new InScopePrefixes());
268         a.add(new Insert());
269         a.add(new KeyFn());
270         a.add(new Lang());
271         a.add(new Last());
272         a.add(new Matches());
273         a.add(new Minimax());
274         a.add(new NamePart());
275         a.add(new NamespaceForPrefix());
276         a.add(new NormalizeSpace());
277         a.add(new NumberFn());
278         a.add(new Parse());
279         a.add(new Position());
280         a.add(new QNameFn());
281         a.add(new RegexGroup());
282         a.add(new Remove());
283         a.add(new Replace());
284         a.add(new ResolveQName());
285         a.add(new ResolveURI());
286         a.add(new Reverse());
287         a.add(new Root());
288         a.add(new Rounding());
289         a.add(new Serialize());
290         a.add(new StaticBaseURI());
291         a.add(new StringFn());
292         a.add(new StringJoin());
293         a.add(new StringLength());
294         a.add(new Subsequence());
295         a.add(new Substring());
296         a.add(new SystemProperty());
297         a.add(new Tokenize());
298         a.add(new Trace());
299         a.add(new Translate());
300         a.add(new TreatFn());
301         a.add(new Unicode());
302         a.add(new Unordered());
303         a.add(new UnparsedEntity());
304         a.add(new UnparsedText());
305     }
306
307 }
308
309 //
310
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
311
// you may not use this file except in compliance with the License. You may obtain a copy of the
312
// License at http://www.mozilla.org/MPL/
313
//
314
// Software distributed under the License is distributed on an "AS IS" basis,
315
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
316
// See the License for the specific language governing rights and limitations under the License.
317
//
318
// The Original Code is: all this file.
319
//
320
// The Initial Developer of the Original Code is Michael H. Kay.
321
//
322
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
323
//
324
// Contributor(s): none.
325
//
326
Popular Tags