/*
 * 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;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.modules.eql.history.HistoryBuilder;
import com.queplix.core.modules.eql.parser.EQLInterpreter;
import com.queplix.core.modules.eql.parser.EQLPluggableModule;
import com.queplix.core.utils.dao.AbstractPropertyFactory;

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

/**
 * EQL factory.
 *
 * @author [ALB] Baranov Andrey
 * @author [ONZ] Oleg N. Zhovtanyuk
 * @version $Revision: 1.2 $ $Date: 2005/10/26 14:03:51 $
 */

public final class EQLFactory
        extends AbstractPropertyFactory {

    // =================================================== Constants and fields

    private static final EQLFactory o = new EQLFactory();
    private static final String FILE_NAME = "eql.properties";

    private static final String EQL_INTERPRETER_CLASS_NAME
            = "interpreter.class";
    private static final String HISTORY_BUILDER_CLASS_NAME
            = "history.builder.class";

    private Class eqlIntClass;
    private Class historyBuilderClass;

    // ========================================================= Initialization

    // Constructor.

    private EQLFactory() {

        InputStream is = loadSysPropertiesAsStream(FILE_NAME);
        Properties props = new Properties();

        try {
            props.load(is);

            String className = props.getProperty(EQL_INTERPRETER_CLASS_NAME);
            eqlIntClass = Class.forName(className);

            className = props.getProperty(HISTORY_BUILDER_CLASS_NAME);
            historyBuilderClass = Class.forName(className);

        } catch (Exception ex) {
            ERROR(ex);
            throw new GenericSystemException(ex);
        }
    }

    // ========================================================= Public methods

    /**
     * EQL Interpreter instance getter.
     *
     * @param session EQL session
     * @return EQL Interpreter object
     */
    public EQLInterpreter getEqlInterpreter(EQLSession session) {
        return (EQLInterpreter) getEqlPluggableModule(eqlIntClass, session);
    }

    /**
     * History Builder instance getter.
     *
     * @param session EQL session
     * @return History Builder object
     */
    public HistoryBuilder getHistoryBuilder(EQLSession session) {
        return (HistoryBuilder) getEqlPluggableModule(historyBuilderClass,
                session);
    }

    // ======================================================== Private methods

    // Instantiates EQL pluggable module.

    private EQLPluggableModule getEqlPluggableModule(Class clazz,
                                                     EQLSession session) {
        if(clazz == null) {
            throw new GenericSystemException("Can't load class '" + clazz +
                    "' from properties file '" + FILE_NAME + "'.");
        }

        try {
            EQLPluggableModule eqlPlugModule = (EQLPluggableModule) clazz
                    .newInstance();
            eqlPlugModule.setSession(session);
            return eqlPlugModule;
        } catch (Exception ex) {
            ERROR(ex);
            throw new GenericSystemException(
                    "Can't instantiate object from class '" +
                            clazz + "'.", ex);
        }
    }

    // =============================================================== Static methods

    /**
     * Get single instance
     *
     * @return EQLFactory object
     */
    public static EQLFactory getInstance() {
        return o;
    }
}
