/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

package com.queplix.core.modules.eql.parser;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.modules.eql.EQLReqSubOpMemberFunc;
import com.queplix.core.utils.dao.AbstractPropertyFactory;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;

/**
 * <p>Function manager</p>
 *
 * @author Baranov Andrey [ALB]
 * @version $Revision: 1.2 $ $Date: 2005/10/26 14:03:51 $
 */

public final class EQLFuncManager {

// --------------- STATIC CONSTANTS ------------------------

    private static final Class CLASS = EQLFuncManager.class;
    private static final String FILE_NAME = "eql.func.properties";

    private static final HashMap functions = new HashMap();

    // function loading...
    static {
        try {
            Properties props = AbstractPropertyFactory.loadSysProperties(CLASS, FILE_NAME);
            for (Object obj : props.keySet()) {
                String name = (String) obj;
                String className = props.getProperty(name);
                registerFunction(name, className);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new GenericSystemException();
        }
    }

// ------------- PUBLIC STATIC METHODS ---------------------

    /**
     * Register new function
     *
     * @param name          function name
     * @param funcClazzName function class name
     */
    public static synchronized void registerFunction(String name,
                                                     String funcClazzName) {

        try {
            Class funcClazz = Class.forName(funcClazzName);
            functions.put(name.toUpperCase(), funcClazz);

        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
            throw new GenericSystemException(ex);
        }
    }

    /**
     * Get new instance of function
     *
     * @param name   function name
     * @param eqlInt EQLInterpreter object
     * @return function instance
     */
    public static EQLReqSubOpMemberFunc getFunction(String name,
                                                    EQLInterpreter eqlInt) {

        Class funcClazz = (Class) functions.get(name.toUpperCase());
        if (funcClazz == null) {
            throw new GenericSystemException(
                    "Can't get function '" + name + "'");
        }

        EQLReqSubOpMemberFunc func = null;
        try {
            func = (EQLReqSubOpMemberFunc) funcClazz.newInstance();
        } catch (Exception ex) {
            throw new GenericSystemException(
                    "Can't instantiate function '" + name + "'", ex);
        }

        // set EQLInterpreter mediator
        func.setEQLInt(eqlInt);

        return func;
    }

// --------------- PRIVATE METHODS -------------------------

    /**
     * Constructor
     */
    private EQLFuncManager() {
    }
}
