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

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.modules.security.jxb.Property;
import com.queplix.core.modules.security.jxb.LoginConfig;
import com.queplix.core.modules.security.jxb.Loginmodule;
import com.queplix.core.utils.StringHelper;
import com.queplix.core.utils.dao.AbstractPropertyFactory;

import java.util.HashMap;
import java.util.Map;
import org.xml.sax.SAXParseException; 

/**
 * <p>Factory class for instantiating appropriate login modules</p>
 *
 * @author [AZ] Andrei Zudin
 * @version $Revision: 1.1 $ $Date: 2007/04/12 14:03:51 $
 */

public class LoginModuleFactory extends AbstractPropertyFactory {
    /**
     * Single instance.
     */
    private static final LoginModuleFactory o = new LoginModuleFactory();

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

    /**
     * Login Modules instances
     */
    private Map loginModules = new HashMap();
    
    /**
     * XML login config
     */
    private LoginConfig loginConfig;

    private LoginModuleFactory() {
        try {

            // Init LoginConfig XML config.
            loginConfig = (LoginConfig) loadSysPropertiesAsObject(CONFIG_FILE,
                    LoginConfig.class);

            //
            // Initialization
            //
            
            // Init map of EntitySchema objects.
            for(int i = 0; i < loginConfig.getLoginmoduleCount(); i++) {
                Loginmodule loginModuleConfig = loginConfig.getLoginmodule(i);

                String className = loginModuleConfig.getLoginmoduleclass();
                
                Class loginModuleClass = null;
                if(className != null && !StringHelper.isEmpty(className)) {
                    loginModuleClass = initClass(className);
                } else {
                    throw new NullPointerException(
                        "LoginModuleFactory: 'Login Module Classname' is NULL for usertype = " 
                        + loginModuleConfig.getUsertype());
                }
                
                // Instantiating LoginModule.
                try {
                    LoginModule loginModule = (LoginModule) loginModuleClass.newInstance();
                    
                    Property[] properties = loginModuleConfig.getProperty();;

                    // ... set property
                    if(properties != null) {
                        loginModule.init(properties);
                    }
                    
                    // .. remember reference
                    loginModules.put(loginModuleConfig.getUsertype(), loginModule);
                    
                } catch (Exception ex) {
                    ERROR(ex);
                    throw new GenericSystemException(
                            "Cannot instantiate LoginModule. " +
                                    "Class: " + loginModuleClass.getName(), ex);
                }               
            }
        } catch (Exception e) {
            ERROR(e);
            throw new GenericSystemException(
                    "Cannot init Login Module: " + e.getMessage(), e);
        }
    }

    /**
     * Login Module instance getter.
     *
     * @return LoginModule object
     */
    public LoginModule getLoginModule(String loginModuleType) {
        return (LoginModule) loginModules.get(loginModuleType);
    }

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