Package mondrian.olap.fun

Source Code of mondrian.olap.fun.GlobalFunTable

/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/GlobalFunTable.java#1 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2006-2009 Julian Hyde and others
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.olap.fun;

import mondrian.olap.FunTable;
import mondrian.olap.Syntax;
import mondrian.olap.Util;
import mondrian.olap.type.Type;
import mondrian.spi.UserDefinedFunction;
import mondrian.util.ServiceDiscovery;

import java.util.List;

/**
* Global function table contains builtin functions and global user-defined
* functions.
*
* @author Gang Chen
* @version $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/GlobalFunTable.java#1 $
*/
public class GlobalFunTable extends FunTableImpl {

    private static GlobalFunTable instance = new GlobalFunTable();
    static {
        instance.init();
    }

    public static GlobalFunTable instance() {
        return instance;
    }

    private GlobalFunTable() {
    }

    public void defineFunctions(Builder builder) {
        final FunTable builtinFunTable = BuiltinFunTable.instance();
        final List<String> reservedWords = builtinFunTable.getReservedWords();
        for (String reservedWord : reservedWords) {
            builder.defineReserved(reservedWord);
        }
        final List<Resolver> resolvers = builtinFunTable.getResolvers();
        for (Resolver resolver : resolvers) {
            builder.define(resolver);
        }

        for (Class<UserDefinedFunction> udfClass : lookupUdfImplClasses()) {
            defineUdf(builder, udfClass);
        }
    }

    private List<Class<UserDefinedFunction>> lookupUdfImplClasses() {
        final ServiceDiscovery<UserDefinedFunction> serviceDiscovery =
            ServiceDiscovery.forClass(UserDefinedFunction.class);
        return serviceDiscovery.getImplementor();
    }

    /**
     * Defines a user-defined function in this table.
     *
     * <p>If the function is not valid, throws an error.
     *
     * @param builder Builder
     * @param udfClass Class that implements the function
     */
    private void defineUdf(
        Builder builder,
        Class<UserDefinedFunction> udfClass)
    {
        // Instantiate class with default constructor.
        final UserDefinedFunction udf = Util.createUdf(udfClass, null);

        // Validate function.
        validateFunction(udf);

        // Define function.
        builder.define(new UdfResolver(udf));
    }

    /**
     * Throws an error if a user-defined function does not adhere to the
     * API.
     *
     * @param udf User defined function
     */
    private void validateFunction(final UserDefinedFunction udf) {
        // Check that the name is not null or empty.
        final String udfName = udf.getName();
        if (udfName == null || udfName.equals("")) {
            throw Util.newInternal(
                "User-defined function defined by class '"
                + udf.getClass() + "' has empty name");
        }
        // It's OK for the description to be null.
        //final String description = udf.getDescription();

        final Type[] parameterTypes = udf.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            Type parameterType = parameterTypes[i];
            if (parameterType == null) {
                throw Util.newInternal(
                    "Invalid user-defined function '" + udfName
                    + "': parameter type #" + i + " is null");
            }
        }

        // It's OK for the reserved words to be null or empty.
        //final String[] reservedWords = udf.getReservedWords();

        // Test that the function returns a sensible type when given the FORMAL
        // types. It may still fail when we give it the ACTUAL types, but it's
        // impossible to check that now.
        final Type returnType = udf.getReturnType(parameterTypes);
        if (returnType == null) {
            throw Util.newInternal(
                "Invalid user-defined function '" + udfName
                + "': return type is null");
        }
        final Syntax syntax = udf.getSyntax();
        if (syntax == null) {
            throw Util.newInternal(
                "Invalid user-defined function '" + udfName
                + "': syntax is null");
        }
    }


}

// End GlobalFunTable.java
TOP

Related Classes of mondrian.olap.fun.GlobalFunTable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.