FunctionTable.java revision 749:c494d4d1c5a1
1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 */
4/**
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 */
22/*
23 * $Id: FunctionTable.java,v 1.3 2005/09/28 13:49:34 pvedula Exp $
24 */
25package com.sun.org.apache.xpath.internal.compiler;
26
27import com.sun.org.apache.xpath.internal.Expression;
28import com.sun.org.apache.xpath.internal.functions.Function;
29import java.util.HashMap;
30import javax.xml.transform.TransformerException;
31
32/**
33 * The function table for XPath.
34 */
35public class FunctionTable
36{
37
38  /** The 'current()' id. */
39  public static final int FUNC_CURRENT = 0;
40
41  /** The 'last()' id. */
42  public static final int FUNC_LAST = 1;
43
44  /** The 'position()' id. */
45  public static final int FUNC_POSITION = 2;
46
47  /** The 'count()' id. */
48  public static final int FUNC_COUNT = 3;
49
50  /** The 'id()' id. */
51  public static final int FUNC_ID = 4;
52
53  /** The 'key()' id (XSLT). */
54  public static final int FUNC_KEY = 5;
55
56  /** The 'local-name()' id. */
57  public static final int FUNC_LOCAL_PART = 7;
58
59  /** The 'namespace-uri()' id. */
60  public static final int FUNC_NAMESPACE = 8;
61
62  /** The 'name()' id. */
63  public static final int FUNC_QNAME = 9;
64
65  /** The 'generate-id()' id. */
66  public static final int FUNC_GENERATE_ID = 10;
67
68  /** The 'not()' id. */
69  public static final int FUNC_NOT = 11;
70
71  /** The 'true()' id. */
72  public static final int FUNC_TRUE = 12;
73
74  /** The 'false()' id. */
75  public static final int FUNC_FALSE = 13;
76
77  /** The 'boolean()' id. */
78  public static final int FUNC_BOOLEAN = 14;
79
80  /** The 'number()' id. */
81  public static final int FUNC_NUMBER = 15;
82
83  /** The 'floor()' id. */
84  public static final int FUNC_FLOOR = 16;
85
86  /** The 'ceiling()' id. */
87  public static final int FUNC_CEILING = 17;
88
89  /** The 'round()' id. */
90  public static final int FUNC_ROUND = 18;
91
92  /** The 'sum()' id. */
93  public static final int FUNC_SUM = 19;
94
95  /** The 'string()' id. */
96  public static final int FUNC_STRING = 20;
97
98  /** The 'starts-with()' id. */
99  public static final int FUNC_STARTS_WITH = 21;
100
101  /** The 'contains()' id. */
102  public static final int FUNC_CONTAINS = 22;
103
104  /** The 'substring-before()' id. */
105  public static final int FUNC_SUBSTRING_BEFORE = 23;
106
107  /** The 'substring-after()' id. */
108  public static final int FUNC_SUBSTRING_AFTER = 24;
109
110  /** The 'normalize-space()' id. */
111  public static final int FUNC_NORMALIZE_SPACE = 25;
112
113  /** The 'translate()' id. */
114  public static final int FUNC_TRANSLATE = 26;
115
116  /** The 'concat()' id. */
117  public static final int FUNC_CONCAT = 27;
118
119  /** The 'substring()' id. */
120  public static final int FUNC_SUBSTRING = 29;
121
122  /** The 'string-length()' id. */
123  public static final int FUNC_STRING_LENGTH = 30;
124
125  /** The 'system-property()' id. */
126  public static final int FUNC_SYSTEM_PROPERTY = 31;
127
128  /** The 'lang()' id. */
129  public static final int FUNC_LANG = 32;
130
131  /** The 'function-available()' id (XSLT). */
132  public static final int FUNC_EXT_FUNCTION_AVAILABLE = 33;
133
134  /** The 'element-available()' id (XSLT). */
135  public static final int FUNC_EXT_ELEM_AVAILABLE = 34;
136
137  /** The 'unparsed-entity-uri()' id (XSLT). */
138  public static final int FUNC_UNPARSED_ENTITY_URI = 36;
139
140  /** The 'here()' id (XML Signature). */
141  public static final int FUNC_HERE = 37;
142
143  // Proprietary
144
145  /** The 'document-location()' id (Proprietary). */
146  public static final int FUNC_DOCLOCATION = 35;
147
148  /**
149   * The function table.
150   */
151  private static Class m_functions[];
152
153  /** Table of function name to function ID associations. */
154  private static HashMap m_functionID = new HashMap();
155
156  /**
157   * The function table contains customized functions
158   */
159  private Class m_functions_customer[] = new Class[NUM_ALLOWABLE_ADDINS];
160
161  /**
162   * Table of function name to function ID associations for customized functions
163   */
164  private HashMap m_functionID_customer = new HashMap();
165
166  /**
167   * Number of built in functions.  Be sure to update this as
168   * built-in functions are added.
169   */
170  private static final int NUM_BUILT_IN_FUNCS = 38;
171
172  /**
173   * Number of built-in functions that may be added.
174   */
175  private static final int NUM_ALLOWABLE_ADDINS = 30;
176
177  /**
178   * The index to the next free function index.
179   */
180  private int m_funcNextFreeIndex = NUM_BUILT_IN_FUNCS;
181
182  static
183  {
184    m_functions = new Class[NUM_BUILT_IN_FUNCS];
185    m_functions[FUNC_CURRENT] = com.sun.org.apache.xpath.internal.functions.FuncCurrent.class;
186    m_functions[FUNC_LAST] = com.sun.org.apache.xpath.internal.functions.FuncLast.class;
187    m_functions[FUNC_POSITION] = com.sun.org.apache.xpath.internal.functions.FuncPosition.class;
188    m_functions[FUNC_COUNT] = com.sun.org.apache.xpath.internal.functions.FuncCount.class;
189    m_functions[FUNC_ID] = com.sun.org.apache.xpath.internal.functions.FuncId.class;
190    // J2SE does not support Xalan interpretive
191    // m_functions[FUNC_KEY] =
192    //   com.sun.org.apache.xalan.internal.templates.FuncKey.class;
193    m_functions[FUNC_LOCAL_PART] =
194      com.sun.org.apache.xpath.internal.functions.FuncLocalPart.class;
195    m_functions[FUNC_NAMESPACE] =
196      com.sun.org.apache.xpath.internal.functions.FuncNamespace.class;
197    m_functions[FUNC_QNAME] = com.sun.org.apache.xpath.internal.functions.FuncQname.class;
198    m_functions[FUNC_GENERATE_ID] =
199      com.sun.org.apache.xpath.internal.functions.FuncGenerateId.class;
200    m_functions[FUNC_NOT] = com.sun.org.apache.xpath.internal.functions.FuncNot.class;
201    m_functions[FUNC_TRUE] = com.sun.org.apache.xpath.internal.functions.FuncTrue.class;
202    m_functions[FUNC_FALSE] = com.sun.org.apache.xpath.internal.functions.FuncFalse.class;
203    m_functions[FUNC_BOOLEAN] = com.sun.org.apache.xpath.internal.functions.FuncBoolean.class;
204    m_functions[FUNC_LANG] = com.sun.org.apache.xpath.internal.functions.FuncLang.class;
205    m_functions[FUNC_NUMBER] = com.sun.org.apache.xpath.internal.functions.FuncNumber.class;
206    m_functions[FUNC_FLOOR] = com.sun.org.apache.xpath.internal.functions.FuncFloor.class;
207    m_functions[FUNC_CEILING] = com.sun.org.apache.xpath.internal.functions.FuncCeiling.class;
208    m_functions[FUNC_ROUND] = com.sun.org.apache.xpath.internal.functions.FuncRound.class;
209    m_functions[FUNC_SUM] = com.sun.org.apache.xpath.internal.functions.FuncSum.class;
210    m_functions[FUNC_STRING] = com.sun.org.apache.xpath.internal.functions.FuncString.class;
211    m_functions[FUNC_STARTS_WITH] =
212      com.sun.org.apache.xpath.internal.functions.FuncStartsWith.class;
213    m_functions[FUNC_CONTAINS] = com.sun.org.apache.xpath.internal.functions.FuncContains.class;
214    m_functions[FUNC_SUBSTRING_BEFORE] =
215      com.sun.org.apache.xpath.internal.functions.FuncSubstringBefore.class;
216    m_functions[FUNC_SUBSTRING_AFTER] =
217      com.sun.org.apache.xpath.internal.functions.FuncSubstringAfter.class;
218    m_functions[FUNC_NORMALIZE_SPACE] =
219      com.sun.org.apache.xpath.internal.functions.FuncNormalizeSpace.class;
220    m_functions[FUNC_TRANSLATE] =
221      com.sun.org.apache.xpath.internal.functions.FuncTranslate.class;
222    m_functions[FUNC_CONCAT] = com.sun.org.apache.xpath.internal.functions.FuncConcat.class;
223    m_functions[FUNC_SYSTEM_PROPERTY] =
224      com.sun.org.apache.xpath.internal.functions.FuncSystemProperty.class;
225    m_functions[FUNC_EXT_FUNCTION_AVAILABLE] =
226      com.sun.org.apache.xpath.internal.functions.FuncExtFunctionAvailable.class;
227    m_functions[FUNC_EXT_ELEM_AVAILABLE] =
228      com.sun.org.apache.xpath.internal.functions.FuncExtElementAvailable.class;
229    m_functions[FUNC_SUBSTRING] =
230      com.sun.org.apache.xpath.internal.functions.FuncSubstring.class;
231    m_functions[FUNC_STRING_LENGTH] =
232      com.sun.org.apache.xpath.internal.functions.FuncStringLength.class;
233    m_functions[FUNC_DOCLOCATION] =
234      com.sun.org.apache.xpath.internal.functions.FuncDoclocation.class;
235    m_functions[FUNC_UNPARSED_ENTITY_URI] =
236      com.sun.org.apache.xpath.internal.functions.FuncUnparsedEntityURI.class;
237    m_functions[FUNC_HERE] =
238      com.sun.org.apache.xpath.internal.functions.FuncHere.class;
239  }
240
241  static{
242          m_functionID.put(Keywords.FUNC_CURRENT_STRING,
243                          new Integer(FunctionTable.FUNC_CURRENT));
244          m_functionID.put(Keywords.FUNC_LAST_STRING,
245                          new Integer(FunctionTable.FUNC_LAST));
246          m_functionID.put(Keywords.FUNC_POSITION_STRING,
247                          new Integer(FunctionTable.FUNC_POSITION));
248          m_functionID.put(Keywords.FUNC_COUNT_STRING,
249                          new Integer(FunctionTable.FUNC_COUNT));
250          m_functionID.put(Keywords.FUNC_ID_STRING,
251                          new Integer(FunctionTable.FUNC_ID));
252          m_functionID.put(Keywords.FUNC_KEY_STRING,
253                          new Integer(FunctionTable.FUNC_KEY));
254          m_functionID.put(Keywords.FUNC_LOCAL_PART_STRING,
255                          new Integer(FunctionTable.FUNC_LOCAL_PART));
256          m_functionID.put(Keywords.FUNC_NAMESPACE_STRING,
257                          new Integer(FunctionTable.FUNC_NAMESPACE));
258          m_functionID.put(Keywords.FUNC_NAME_STRING,
259                          new Integer(FunctionTable.FUNC_QNAME));
260          m_functionID.put(Keywords.FUNC_GENERATE_ID_STRING,
261                          new Integer(FunctionTable.FUNC_GENERATE_ID));
262          m_functionID.put(Keywords.FUNC_NOT_STRING,
263                          new Integer(FunctionTable.FUNC_NOT));
264          m_functionID.put(Keywords.FUNC_TRUE_STRING,
265                          new Integer(FunctionTable.FUNC_TRUE));
266          m_functionID.put(Keywords.FUNC_FALSE_STRING,
267                          new Integer(FunctionTable.FUNC_FALSE));
268          m_functionID.put(Keywords.FUNC_BOOLEAN_STRING,
269                          new Integer(FunctionTable.FUNC_BOOLEAN));
270          m_functionID.put(Keywords.FUNC_LANG_STRING,
271                          new Integer(FunctionTable.FUNC_LANG));
272          m_functionID.put(Keywords.FUNC_NUMBER_STRING,
273                          new Integer(FunctionTable.FUNC_NUMBER));
274          m_functionID.put(Keywords.FUNC_FLOOR_STRING,
275                          new Integer(FunctionTable.FUNC_FLOOR));
276          m_functionID.put(Keywords.FUNC_CEILING_STRING,
277                          new Integer(FunctionTable.FUNC_CEILING));
278          m_functionID.put(Keywords.FUNC_ROUND_STRING,
279                          new Integer(FunctionTable.FUNC_ROUND));
280          m_functionID.put(Keywords.FUNC_SUM_STRING,
281                          new Integer(FunctionTable.FUNC_SUM));
282          m_functionID.put(Keywords.FUNC_STRING_STRING,
283                          new Integer(FunctionTable.FUNC_STRING));
284          m_functionID.put(Keywords.FUNC_STARTS_WITH_STRING,
285                          new Integer(FunctionTable.FUNC_STARTS_WITH));
286          m_functionID.put(Keywords.FUNC_CONTAINS_STRING,
287                          new Integer(FunctionTable.FUNC_CONTAINS));
288          m_functionID.put(Keywords.FUNC_SUBSTRING_BEFORE_STRING,
289                          new Integer(FunctionTable.FUNC_SUBSTRING_BEFORE));
290          m_functionID.put(Keywords.FUNC_SUBSTRING_AFTER_STRING,
291                          new Integer(FunctionTable.FUNC_SUBSTRING_AFTER));
292          m_functionID.put(Keywords.FUNC_NORMALIZE_SPACE_STRING,
293                          new Integer(FunctionTable.FUNC_NORMALIZE_SPACE));
294          m_functionID.put(Keywords.FUNC_TRANSLATE_STRING,
295                          new Integer(FunctionTable.FUNC_TRANSLATE));
296          m_functionID.put(Keywords.FUNC_CONCAT_STRING,
297                          new Integer(FunctionTable.FUNC_CONCAT));
298          m_functionID.put(Keywords.FUNC_SYSTEM_PROPERTY_STRING,
299                          new Integer(FunctionTable.FUNC_SYSTEM_PROPERTY));
300          m_functionID.put(Keywords.FUNC_EXT_FUNCTION_AVAILABLE_STRING,
301                        new Integer(FunctionTable.FUNC_EXT_FUNCTION_AVAILABLE));
302          m_functionID.put(Keywords.FUNC_EXT_ELEM_AVAILABLE_STRING,
303                          new Integer(FunctionTable.FUNC_EXT_ELEM_AVAILABLE));
304          m_functionID.put(Keywords.FUNC_SUBSTRING_STRING,
305                          new Integer(FunctionTable.FUNC_SUBSTRING));
306          m_functionID.put(Keywords.FUNC_STRING_LENGTH_STRING,
307                          new Integer(FunctionTable.FUNC_STRING_LENGTH));
308          m_functionID.put(Keywords.FUNC_UNPARSED_ENTITY_URI_STRING,
309                          new Integer(FunctionTable.FUNC_UNPARSED_ENTITY_URI));
310          m_functionID.put(Keywords.FUNC_DOCLOCATION_STRING,
311                          new Integer(FunctionTable.FUNC_DOCLOCATION));
312          m_functionID.put(Keywords.FUNC_HERE_STRING,
313                          new Integer(FunctionTable.FUNC_HERE));
314  }
315
316  public FunctionTable(){
317  }
318
319  /**
320   * Return the name of the a function in the static table. Needed to avoid
321   * making the table publicly available.
322   */
323  String getFunctionName(int funcID) {
324      if (funcID < NUM_BUILT_IN_FUNCS) return m_functions[funcID].getName();
325      else return m_functions_customer[funcID - NUM_BUILT_IN_FUNCS].getName();
326  }
327
328  /**
329   * Obtain a new Function object from a function ID.
330   *
331   * @param which  The function ID, which may correspond to one of the FUNC_XXX
332   *    values found in {@link com.sun.org.apache.xpath.internal.compiler.FunctionTable}, but may
333   *    be a value installed by an external module.
334   *
335   * @return a a new Function instance.
336   *
337   * @throws javax.xml.transform.TransformerException if ClassNotFoundException,
338   *    IllegalAccessException, or InstantiationException is thrown.
339   */
340  Function getFunction(int which)
341          throws javax.xml.transform.TransformerException
342  {
343          try{
344              if (which < NUM_BUILT_IN_FUNCS)
345                  return (Function) m_functions[which].newInstance();
346              else
347                  return (Function) m_functions_customer[
348                      which-NUM_BUILT_IN_FUNCS].newInstance();
349          }catch (IllegalAccessException ex){
350                  throw new TransformerException(ex.getMessage());
351          }catch (InstantiationException ex){
352                  throw new TransformerException(ex.getMessage());
353          }
354  }
355
356  /**
357   * Obtain a function ID from a given function name
358   * @param key the function name in a java.lang.String format.
359   * @return a function ID, which may correspond to one of the FUNC_XXX values
360   * found in {@link com.sun.org.apache.xpath.internal.compiler.FunctionTable}, but may be a
361   * value installed by an external module.
362   */
363  Object getFunctionID(String key){
364          Object id = m_functionID_customer.get(key);
365          if (null == id) id = m_functionID.get(key);
366          return id;
367  }
368
369  /**
370   * Install a built-in function.
371   * @param name The unqualified name of the function, must not be null
372   * @param func A Implementation of an XPath Function object.
373   * @return the position of the function in the internal index.
374   */
375  public int installFunction(String name, Class func)
376  {
377
378    int funcIndex;
379    Object funcIndexObj = getFunctionID(name);
380
381    if (null != funcIndexObj)
382    {
383      funcIndex = ((Integer) funcIndexObj).intValue();
384
385      if (funcIndex < NUM_BUILT_IN_FUNCS){
386              funcIndex = m_funcNextFreeIndex++;
387              m_functionID_customer.put(name, new Integer(funcIndex));
388      }
389      m_functions_customer[funcIndex - NUM_BUILT_IN_FUNCS] = func;
390    }
391    else
392    {
393            funcIndex = m_funcNextFreeIndex++;
394
395            m_functions_customer[funcIndex-NUM_BUILT_IN_FUNCS] = func;
396
397            m_functionID_customer.put(name,
398                new Integer(funcIndex));
399    }
400    return funcIndex;
401  }
402
403  /**
404   * Tell if a built-in, non-namespaced function is available.
405   *
406   * @param methName The local name of the function.
407   *
408   * @return True if the function can be executed.
409   */
410  public boolean functionAvailable(String methName)
411  {
412      Object tblEntry = m_functionID.get(methName);
413      if (null != tblEntry) return true;
414      else{
415              tblEntry = m_functionID_customer.get(methName);
416              return (null != tblEntry)? true : false;
417      }
418  }
419}
420