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,v 1.10 2007/05/07 22:47:59 mimil Exp $
  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: 
  52:   private FunctionCategory[] categories;
  53:   private HashNMap categoryFunctions;
  54:   private HashMap functions;
  55:   private HashMap functionMetaData;
  56: 
  57:   public DefaultFunctionRegistry()
  58:   {
  59:     categoryFunctions = new HashNMap();
  60:     functionMetaData = new HashMap();
  61:     functions = new HashMap();
  62:     categories = new FunctionCategory[0];
  63:   }
  64: 
  65:   public FunctionCategory[] getCategories()
  66:   {
  67:     return (FunctionCategory[]) categories.clone();
  68:   }
  69: 
  70:   public Function[] getFunctions()
  71:   {
  72:     final String[] fnClasses = (String[]) functions.values().toArray
  73:         (new String[functions.size()]);
  74:     final ArrayList functions = new ArrayList(fnClasses.length);
  75:     for (int i = 0; i < fnClasses.length; i++)
  76:     {
  77:       final String aClass = fnClasses[i];
  78:       final Function function = (Function) ObjectUtilities.loadAndInstantiate
  79:           (aClass, DefaultFunctionRegistry.class, Function.class);
  80:       if (function == null)
  81:       {
  82:         Log.debug ("There is no such function: " + aClass);
  83:       }
  84:       else
  85:       {
  86:         functions.add(function);
  87:       }
  88:     }
  89:     return (Function[]) functions.toArray(new Function[functions.size()]);
  90:   }
  91: 
  92:   public String[] getFunctionNames()
  93:   {
  94:     return (String[]) functions.keySet().toArray(new String[functions.size()]);
  95:   }
  96: 
  97:   public String[] getFunctionNamesByCategory(FunctionCategory category)
  98:   {
  99:     return (String[]) categoryFunctions.toArray(category, new String[0]);
 100:   }
 101: 
 102:   public Function[] getFunctionsByCategory(FunctionCategory category)
 103:   {
 104:     final String[] fnNames = (String[]) categoryFunctions.toArray
 105:         (category, new String[0]);
 106:     final ArrayList functions = new ArrayList(fnNames.length);
 107:     for (int i = 0; i < fnNames.length; i++)
 108:     {
 109:       final String aName = fnNames[i];
 110:       final Function function = createFunction(aName);
 111:       if (function != null)
 112:       {
 113:         functions.add(function);
 114:       }
 115:     }
 116:     return (Function[]) functions.toArray(new Function[functions.size()]);
 117:   }
 118: 
 119:   public Function createFunction(String name)
 120:   {
 121:     if (name == null)
 122:     {
 123:       throw new NullPointerException();
 124:     }
 125:     final String functionClass = (String) functions.get(name.toUpperCase());
 126:     final Function function = (Function) ObjectUtilities.loadAndInstantiate
 127:         (functionClass, DefaultFunctionRegistry.class, Function.class);
 128:     if (function == null)
 129:     {
 130:       Log.debug ("There is no such function: " + name);
 131:     }
 132:     return function;
 133:   }
 134: 
 135:   public FunctionDescription getMetaData(String name)
 136:   {
 137:     if (name == null)
 138:     {
 139:       throw new NullPointerException();
 140:     }
 141:     return (FunctionDescription) functionMetaData.get(name.toUpperCase());
 142:   }
 143: 
 144:   public void initialize(final Configuration configuration)
 145:   {
 146:     final Iterator functionKeys =
 147:         configuration.findPropertyKeys(FUNCTIONS_PREFIX);
 148:     final HashSet categories = new HashSet();
 149: 
 150: 
 151:     while (functionKeys.hasNext())
 152:     {
 153:       final String classKey = (String) functionKeys.next();
 154:       if (classKey.endsWith(".class") == false)
 155:       {
 156:         continue;
 157:       }
 158: 
 159:       final String className = configuration.getConfigProperty(classKey);
 160:       if (className.length() == 0)
 161:       {
 162:         continue;
 163:       }
 164:       final Object fn = ObjectUtilities.loadAndInstantiate
 165:           (className, DefaultFunctionRegistry.class, Function.class);
 166:       if (fn instanceof Function == false)
 167:       {
 168:         continue;
 169:       }
 170: 
 171:       final Function function = (Function) fn;
 172: 
 173:       final int endIndex = classKey.length() - ".class".length();
 174:       final String descrKey = classKey.substring(0, endIndex) + ".description";
 175:       final String descrClassName = configuration.getConfigProperty(descrKey);
 176:       final Object descr = ObjectUtilities.loadAndInstantiate
 177:           (descrClassName, DefaultFunctionRegistry.class, FunctionDescription.class);
 178: 
 179:       final FunctionDescription description;
 180:       if (descr instanceof FunctionDescription == false)
 181:       {
 182:         description = new DefaultFunctionDescription(function.getCanonicalName());
 183:       }
 184:       else
 185:       {
 186:         description = (FunctionDescription) descr;
 187:       }
 188: 
 189:       final FunctionCategory cat = description.getCategory();
 190:       categoryFunctions.add(cat, function.getCanonicalName());
 191:       functionMetaData.put (function.getCanonicalName(), description);
 192:       functions.put(function.getCanonicalName(), className);
 193:       categories.add(cat);
 194:     }
 195: 
 196:     this.categories = (FunctionCategory[]) categories.toArray
 197:         (new FunctionCategory[categories.size()]);
 198:   }
 199: 
 200: }