1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jxpath;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Set;
23
24 /***
25 * An object that aggregates Functions objects into a group Functions object.
26 * Since JXPathContext can only register a single Functions object,
27 * FunctionLibrary should always be used to group all Functions objects
28 * that need to be registered.
29 *
30 * @author Dmitri Plotnikov
31 * @version $Revision: 1.5 $ $Date: 2004/02/29 14:17:42 $
32 */
33 public class FunctionLibrary implements Functions {
34 private List allFunctions = new ArrayList();
35 private HashMap byNamespace = null;
36
37 /***
38 * Add functions to the library
39 */
40 public void addFunctions(Functions functions) {
41 allFunctions.add(functions);
42 byNamespace = null;
43 }
44
45 /***
46 * Remove functions from the library.
47 */
48 public void removeFunctions(Functions functions) {
49 allFunctions.remove(functions);
50 byNamespace = null;
51 }
52
53 /***
54 * Returns a set containing all namespaces used by the aggregated
55 * Functions.
56 */
57 public Set getUsedNamespaces() {
58 if (byNamespace == null) {
59 prepareCache();
60 }
61 return byNamespace.keySet();
62 }
63
64 /***
65 * Returns a Function, if any, for the specified namespace,
66 * name and parameter types.
67 */
68 public Function getFunction(
69 String namespace,
70 String name,
71 Object[] parameters)
72 {
73 if (byNamespace == null) {
74 prepareCache();
75 }
76 Object candidates = byNamespace.get(namespace);
77 if (candidates instanceof Functions) {
78 return ((Functions) candidates).getFunction(
79 namespace,
80 name,
81 parameters);
82 }
83 else if (candidates instanceof List) {
84 List list = (List) candidates;
85 int count = list.size();
86 for (int i = 0; i < count; i++) {
87 Function function =
88 ((Functions) list.get(i)).getFunction(
89 namespace,
90 name,
91 parameters);
92 if (function != null) {
93 return function;
94 }
95 }
96 }
97 return null;
98 }
99
100 private void prepareCache() {
101 byNamespace = new HashMap();
102 int count = allFunctions.size();
103 for (int i = 0; i < count; i++) {
104 Functions funcs = (Functions) allFunctions.get(i);
105 Set namespaces = funcs.getUsedNamespaces();
106 for (Iterator it = namespaces.iterator(); it.hasNext();) {
107 String ns = (String) it.next();
108 Object candidates = byNamespace.get(ns);
109 if (candidates == null) {
110 byNamespace.put(ns, funcs);
111 }
112 else if (candidates instanceof Functions) {
113 List lst = new ArrayList();
114 lst.add(candidates);
115 lst.add(funcs);
116 byNamespace.put(ns, lst);
117 }
118 else {
119 ((List) candidates).add(funcs);
120 }
121 }
122 }
123 }
124 }