Source for org.jfree.formula.function.DefaultFunctionRegistry

   1: /**
   2:  * =========================================
   3:  * LibFormula : a free Java formula library
   4:  * =========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/libformula/
   7:  *
   8:  * (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  *
  26:  * ------------
  27:  * $Id: DefaultFunctionRegistry.java 3325 2007-09-12 23:57:55Z tmorgner $
  28:  * ------------
  29:  * (C) Copyright 2006-2007, by Pentaho Corporation.
  30:  */
  31: package org.jfree.formula.function;
  32: 
  33: import java.util.ArrayList;
  34: import java.util.HashMap;
  35: import java.util.HashSet;
  36: import java.util.Iterator;
  37: 
  38: import org.jfree.util.Configuration;
  39: import org.jfree.util.HashNMap;
  40: import org.jfree.util.Log;
  41: import org.jfree.util.ObjectUtilities;
  42: 
  43: /**
  44:  * Creation-Date: 02.11.2006, 12:48:32
  45:  *
  46:  * @author Thomas Morgner
  47:  */
  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: }