/*
 * 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.utils.sql;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.jxb.sqlwrapper.Property;
import com.queplix.core.jxb.sqlwrapper.Sqlwrapper;
import com.queplix.core.jxb.sqlwrapper.Sqlwrappers;
import com.queplix.core.utils.dao.AbstractPropertyFactory;

import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;

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

public final class SqlWrapperFactory
        extends AbstractPropertyFactory {

    // =============================================================== Constants

    // Single instance.
    private static final SqlWrapperFactory o = new SqlWrapperFactory();

    // Config file name.
    private static final String CONFIG_FILE = "sqlwrapper.xml";

    // =============================================================== Fields

    private final String defaultName;
    private final Map map;

    // =============================================================== Constructor

    private SqlWrapperFactory() {
        try {
            // Init SqlWrapper XML config.
            Sqlwrappers sqlwrappers = (Sqlwrappers) loadSysPropertiesAsObject(
                    CONFIG_FILE, Sqlwrappers.class);

            // Init map of Sqlwrapper objects.
            int count = sqlwrappers.getSqlwrapperCount();
            Map __map = new Hashtable(count); // -- use Hashtable for JD!
            for(int i = 0; i < count; i++) {
                Sqlwrapper sqlwrapper = sqlwrappers.getSqlwrapper(i);
                String name = sqlwrapper.getName();

                // .. remmeber reference
                __map.put(name, sqlwrapper);
            }

            // Init class parameters.
            this.defaultName = sqlwrappers.getDefault();
            this.map = Collections.unmodifiableMap(__map);

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

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

    //
    // Get instance of SqlWrapper by the name.
    //

    private SqlWrapper get(String name) {

        Sqlwrapper sqlwrapper = (Sqlwrapper) map.get(name);
        if(sqlwrapper == null) {
            throw new GenericSystemException("Cannot get SqlWrapper '" + name +
                    "'.\nAvailable names: " + names());
        }

        String className = sqlwrapper.getSqlwrapperclass();
        Property[] properties = sqlwrapper.getProperty();

        /*if( getLogger().isInfoEnabled() ) {
            INFO( "Try to create SqlWrapper: " + name + ", class: " + className );
        }*/

        // .. create new object
        SqlWrapper sqlWrapper;
        try {
            sqlWrapper = (SqlWrapper) Class.forName(className).newInstance();
        } catch (Exception e) {
            ERROR(e);
            throw new GenericSystemException(e);
        }

        // .. set property
        if(properties != null) {
            sqlWrapper.init(properties);
        }

        return sqlWrapper;
    }

    //
    // Get default instance of SqlWrapper.
    //
    private SqlWrapper get() {
        return get(defaultName);
    }

    //
    // Get SqlWrapper's names.
    //
    private Set names() {
        return map.keySet();
    }

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

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

    /**
     * Get collection of SqlWrapper names
     *
     * @return collection
     */
    public static Collection getSqlWrapperNames() {
        return getInstance().names();
    }

    /**
     * Get instance of SqlWrapper.
     *
     * @param name SqlWrapper name
     * @return new SqlWrapper object
     */
    public static SqlWrapper getSqlWrapper(String name) {
        return getInstance().get(name);
    }

    /**
     * Get default instance of SqlWrapper.
     *
     * @return new SqlWrapper object
     */
    public static SqlWrapper getSqlWrapper() {
        return getInstance().get();
    }
}
