1:
31: package ;
32:
33: import ;
34: import ;
35: import ;
36: import ;
37:
38: import ;
39: import ;
40: import ;
41: import ;
42:
43:
48: public class DefaultFunctionRegistry implements FunctionRegistry
49: {
50: private static final String FUNCTIONS_PREFIX = "org.jfree.formula.functions.";
51: private static final String[] EMPTY_ARRAY = new String[0];
52: private static final FunctionCategory[] EMPTY_CATEGORIES = new FunctionCategory[0];
53:
54: private FunctionCategory[] categories;
55: private HashNMap categoryFunctions;
56: private HashMap functions;
57: private HashMap functionMetaData;
58: private HashMap cachedFunctions;
59:
60: public DefaultFunctionRegistry()
61: {
62: cachedFunctions = new HashMap();
63: categoryFunctions = new HashNMap();
64: functionMetaData = new HashMap();
65: functions = new HashMap();
66: categories = EMPTY_CATEGORIES;
67: }
68:
69: public FunctionCategory[] getCategories()
70: {
71: return (FunctionCategory[]) categories.clone();
72: }
73:
74: public Function[] getFunctions()
75: {
76: final String[] fnNames = getFunctionNames();
77: final ArrayList functions = new ArrayList(fnNames.length);
78: for (int i = 0; i < fnNames.length; i++)
79: {
80: final String aName = fnNames[i];
81: final Function function = createFunction(aName);
82: if (function == null)
83: {
84: Log.debug ("There is no such function: " + aName);
85: }
86: else
87: {
88: functions.add(function);
89: }
90: }
91: return (Function[]) functions.toArray(new Function[functions.size()]);
92: }
93:
94: public String[] getFunctionNames()
95: {
96: return (String[]) functions.keySet().toArray(new String[functions.size()]);
97: }
98:
99: public String[] getFunctionNamesByCategory(final FunctionCategory category)
100: {
101: return (String[]) categoryFunctions.toArray(category, EMPTY_ARRAY);
102: }
103:
104: public Function[] getFunctionsByCategory(final FunctionCategory category)
105: {
106: final String[] fnNames = (String[]) categoryFunctions.toArray(category, EMPTY_ARRAY);
107: final ArrayList functions = new ArrayList(fnNames.length);
108: for (int i = 0; i < fnNames.length; i++)
109: {
110: final String aName = fnNames[i];
111: final Function function = createFunction(aName);
112: if (function != null)
113: {
114: functions.add(function);
115: }
116: }
117: return (Function[]) functions.toArray(new Function[functions.size()]);
118: }
119:
120: public Function createFunction(final String name)
121: {
122: if (name == null)
123: {
124: throw new NullPointerException();
125: }
126: final String functionClass = (String) functions.get(name.toUpperCase());
127: final Class cachedClass = (Class) cachedFunctions.get(functionClass);
128: if (cachedClass != null)
129: {
130: try
131: {
132: return (Function) cachedClass.newInstance();
133: }
134: catch (Exception e)
135: {
136: return null;
137: }
138: }
139:
140: final Function function = (Function) ObjectUtilities.loadAndInstantiate
141: (functionClass, DefaultFunctionRegistry.class, Function.class);
142: if (function == null)
143: {
144: Log.debug ("There is no such function: " + name);
145: }
146: else
147: {
148: cachedFunctions.put(functionClass, function.getClass());
149: }
150: return function;
151: }
152:
153: public FunctionDescription getMetaData(final String name)
154: {
155: if (name == null)
156: {
157: throw new NullPointerException();
158: }
159: return (FunctionDescription) functionMetaData.get(name.toUpperCase());
160: }
161:
162: public void initialize(final Configuration configuration)
163: {
164: final Iterator functionKeys =
165: configuration.findPropertyKeys(FUNCTIONS_PREFIX);
166: final HashSet categories = new HashSet();
167:
168:
169: while (functionKeys.hasNext())
170: {
171: final String classKey = (String) functionKeys.next();
172: if (classKey.endsWith(".class") == false)
173: {
174: continue;
175: }
176:
177: final String className = configuration.getConfigProperty(classKey);
178: if (className.length() == 0)
179: {
180: continue;
181: }
182: final Object fn = ObjectUtilities.loadAndInstantiate
183: (className, DefaultFunctionRegistry.class, Function.class);
184: if (fn instanceof Function == false)
185: {
186: continue;
187: }
188:
189: final Function function = (Function) fn;
190:
191: final int endIndex = classKey.length() - ".class".length();
192: final String descrKey = classKey.substring(0, endIndex) + ".description";
193: final String descrClassName = configuration.getConfigProperty(descrKey);
194: final Object descr = ObjectUtilities.loadAndInstantiate
195: (descrClassName, DefaultFunctionRegistry.class, FunctionDescription.class);
196:
197: final FunctionDescription description;
198: if (descr instanceof FunctionDescription == false)
199: {
200: description = new DefaultFunctionDescription(function.getCanonicalName());
201: }
202: else
203: {
204: description = (FunctionDescription) descr;
205: }
206:
207: final FunctionCategory cat = description.getCategory();
208: categoryFunctions.add(cat, function.getCanonicalName());
209: functionMetaData.put (function.getCanonicalName(), description);
210: functions.put(function.getCanonicalName(), className);
211: categories.add(cat);
212: }
213:
214: this.categories = (FunctionCategory[]) categories.toArray(new FunctionCategory[categories.size()]);
215: }
216:
217: }