org.pentaho.reporting.libraries.formula.function.DefaultFunctionRegistry.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.reporting.libraries.formula.function.DefaultFunctionRegistry.java

Source

/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2006 - 2017 Hitachi Vantara and Contributors.  All rights reserved.
*/

package org.pentaho.reporting.libraries.formula.function;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.base.util.HashNMap;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

/**
 * Creation-Date: 02.11.2006, 12:48:32
 *
 * @author Thomas Morgner
 */
public class DefaultFunctionRegistry implements FunctionRegistry {
    private static final Log logger = LogFactory.getLog(DefaultFunctionRegistry.class);

    private static final String FUNCTIONS_PREFIX = "org.pentaho.reporting.libraries.formula.functions.";
    private static final String[] EMPTY_ARRAY = new String[0];
    private static final FunctionCategory[] EMPTY_CATEGORIES = new FunctionCategory[0];

    private FunctionCategory[] categories;
    private HashNMap<FunctionCategory, String> categoryFunctions;
    private HashMap<String, String> functions;
    private HashMap<String, FunctionDescription> functionMetaData;
    private HashMap<String, Class> cachedFunctions;

    public DefaultFunctionRegistry() {
        cachedFunctions = new HashMap<String, Class>();
        categoryFunctions = new HashNMap<FunctionCategory, String>();
        functionMetaData = new HashMap<String, FunctionDescription>();
        functions = new HashMap<String, String>();
        categories = EMPTY_CATEGORIES;
    }

    public FunctionCategory[] getCategories() {
        return categories.clone();
    }

    public Function[] getFunctions() {
        final String[] fnNames = getFunctionNames();
        final ArrayList<Function> functions = new ArrayList<Function>(fnNames.length);
        for (int i = 0; i < fnNames.length; i++) {
            final String aName = fnNames[i];
            final Function function = createFunction(aName);
            if (function == null) {
                logger.debug("There is no such function: " + aName);
            } else {
                functions.add(function);
            }
        }
        return functions.toArray(new Function[functions.size()]);
    }

    public String[] getFunctionNames() {
        return functions.keySet().toArray(new String[functions.size()]);
    }

    public String[] getFunctionNamesByCategory(final FunctionCategory category) {
        return categoryFunctions.toArray(category, EMPTY_ARRAY);
    }

    public Function[] getFunctionsByCategory(final FunctionCategory category) {
        final String[] fnNames = categoryFunctions.toArray(category, EMPTY_ARRAY);
        final ArrayList<Function> functions = new ArrayList<Function>(fnNames.length);
        for (int i = 0; i < fnNames.length; i++) {
            final String aName = fnNames[i];
            final Function function = createFunction(aName);
            if (function != null) {
                functions.add(function);
            }
        }
        return functions.toArray(new Function[functions.size()]);
    }

    public Function createFunction(final String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        final String functionClass = functions.get(name.toUpperCase());
        final Class cachedClass = cachedFunctions.get(functionClass);
        if (cachedClass != null) {
            try {
                return (Function) cachedClass.newInstance();
            } catch (Exception e) {
                return null;
            }
        }

        final Function function = ObjectUtilities.loadAndInstantiate(functionClass, DefaultFunctionRegistry.class,
                Function.class);
        if (function == null) {
            logger.debug("There is no such function: " + name);
        } else {
            cachedFunctions.put(functionClass, function.getClass());
        }
        return function;
    }

    public FunctionDescription getMetaData(final String name) {
        if (name == null) {
            throw new NullPointerException();
        }
        return functionMetaData.get(name.toUpperCase());
    }

    public void initialize(final Configuration configuration) {
        final Iterator functionKeys = configuration.findPropertyKeys(FUNCTIONS_PREFIX);
        final HashSet<FunctionCategory> categories = new HashSet<FunctionCategory>();

        while (functionKeys.hasNext()) {
            final String classKey = (String) functionKeys.next();
            if (classKey.endsWith(".class") == false) {
                continue;
            }

            final String className = configuration.getConfigProperty(classKey);
            if (className.length() == 0) {
                continue;
            }
            final Object fn = ObjectUtilities.loadAndInstantiate(className, DefaultFunctionRegistry.class,
                    Function.class);
            if (fn instanceof Function == false) {
                continue;
            }

            final Function function = (Function) fn;

            final int endIndex = classKey.length() - 6; // 6 = ".class".length();
            final String descrKey = classKey.substring(0, endIndex) + ".description";
            final String descrClassName = configuration.getConfigProperty(descrKey);
            final Object descr = ObjectUtilities.loadAndInstantiate(descrClassName, DefaultFunctionRegistry.class,
                    FunctionDescription.class);

            final FunctionDescription description;
            if (descr instanceof FunctionDescription == false) {
                description = new DefaultFunctionDescription(function.getCanonicalName());
            } else {
                description = (FunctionDescription) descr;
            }

            final FunctionCategory cat = description.getCategory();
            categoryFunctions.add(cat, function.getCanonicalName());
            functionMetaData.put(function.getCanonicalName(), description);
            functions.put(function.getCanonicalName(), className);
            categories.add(cat);
        }

        this.categories = categories.toArray(new FunctionCategory[categories.size()]);
    }

}