/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/urm/org/apache/slide/urm/authenticator/impl/URMAdministratorImpl.java,v 1.4 2005/03/02 10:53:34 eckehard Exp $
 * $Revision: 1.4 $
 * $Date: 2005/03/02 10:53:34 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.apache.slide.urm.authenticator.impl;

import java.util.Iterator;
import java.util.Set;

import org.apache.slide.urm.URMForbiddenException;
import org.apache.slide.urm.URMNotImplementedException;
import org.apache.slide.urm.authenticator.URMAdministrator;
import org.apache.slide.urm.authenticator.rolemanager.URMRole;
import org.apache.slide.urm.authenticator.rolemanager.impl.URMRoleAdminImpl;
import org.apache.slide.urm.authenticator.userdb.URMGroup;
import org.apache.slide.urm.authenticator.userdb.URMUser;
import org.apache.slide.urm.authenticator.userdb.URMUserDBManagerSpi;
import org.apache.slide.urm.authenticator.userdb.impl.URMGroupAdminImpl;
import org.apache.slide.urm.authenticator.userdb.impl.URMUserAdminImpl;
import org.apache.slide.urm.common.URMConfigurationException;
import org.apache.slide.urm.common.URMConfigurator;
import org.apache.slide.urm.common.URMConnectionException;
import org.apache.slide.urm.common.URMDeleteException;
import org.apache.slide.urm.common.URMInsertException;
import org.apache.slide.urm.common.URMInternalServerException;
import org.apache.slide.urm.common.URMConstants;
import org.apache.slide.urm.utils.validatorcache.URMListener;
import org.apache.slide.urm.utils.messagelogger.MessageLogger;

/**
 * @author eckehard.hermann@softwareag.com
 * @author dieter.kessler@softwareag.com
 * @author zsolt.sasvarie@softwareag.com
 */
public class URMAdministratorImpl extends URMUserAdministratorImpl {

    private static org.apache.log4j.Logger msLogger =
        org.apache.log4j.Logger.getLogger(URMAdministratorImpl.class.getName());
        
    private URMListener aclListenerSet = URMListener.getAclListenerSet();
    
    public URMAdministratorImpl(URMConfigurator adminConf, Object userDb,
                                String username, char[] password, String domain, Object owner)
            throws URMConfigurationException {
        super(adminConf, userDb, username, password, domain, owner);
        mOwner = owner;
        // Create the RoleManagerSpi
        
        /*URMConfigurator conf = (URMConfigurator)adminConf.getSubProperties().get("RoleManager");
        Properties props = conf.getProperties();
        String class_name = props != null ? (String)props.get(
                                        URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME) : null;
        if (class_name == null)
            throw new URMConfigurationException(
                MessageLogger.getAndLogMessage(msLogger, "URMCOC0002",
                    URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME, "Administrator/RoleManager"));

        Object radmin_params[] = { conf };
        try {
            mRoleManagerSpi = (URMRoleManagerSpi)URMClassInstantiator.newInstance(class_name, radmin_params);
        } catch (URMException e) {
            throw new URMConfigurationException(MessageLogger.getAndLogMessage(msLogger, "F", e));
        }
        
                
        Properties mainprops = adminConf.getSubProperties();
        conf = mainprops != null ? (URMConfigurator)mainprops.get("UserDatabase") : null;


        // Create the UserDBManagerSpi (SSX)

        conf = (URMConfigurator)adminConf.getSubProperties().get("UserDatabase");
        props = conf.getProperties();
        class_name = props != null ? (String)props.get(
                                    URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME) : null;
        if (class_name == null)
            throw new URMConfigurationException(
                MessageLogger.getAndLogMessage(msLogger, "URMCOC0002",
                    URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME, "Administrator/UserDatabase"));

        Object uadmin_params[] = { conf, userDb, username, password, domain };
        try {
            mUserDBManagerSpi = (URMUserDBManagerSpi)URMClassInstantiator.newInstance(class_name, uadmin_params);
        } catch (URMException e) {
            throw new URMConfigurationException(MessageLogger.getAndLogMessage(msLogger, "F", e));
        }*/
    }
    
    public URMAdministratorImpl(URMAdministrator inAdmin, Object owner) throws URMConnectionException {
        super(inAdmin, owner);
        mOwner = owner;
    }
    
    public URMAdministratorImpl(URMConfigurator adminConf, URMUserDBManagerSpi userDbSpi, Object owner) throws URMConfigurationException { 
        super (adminConf, userDbSpi, owner);
    }
    
    /**
     * creates a new URMAdministrator which just contains a RoleManager and no UserDB.
     * Just for URMGuest user
     */
    /*public URMAdministratorImpl(URMConfigurator adminConf)
            throws URMConfigurationException {
        
        // Create the RoleManagerSpi
        
        URMConfigurator conf = (URMConfigurator)adminConf.getSubProperties().get("RoleManager");
        Properties props = conf.getProperties();
        String class_name = props != null ? (String)props.get(
                                        URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME) : null;
        if (class_name == null)
            throw new URMConfigurationException(
                MessageLogger.getAndLogMessage(msLogger, "URMCOC0002",
                    URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME, "Administrator/RoleManager"));

        Object radmin_params[] = { conf };
        try {
            mRoleManagerSpi = (URMRoleManagerSpi)URMClassInstantiator.newInstance(class_name, radmin_params);
        } catch (URMException e) {
            throw new URMConfigurationException(MessageLogger.getAndLogMessage(msLogger, "F", e));
        }
    }*/
    /******************* Role Manager *****************************/


    /*public boolean isRole(String role)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        return mRoleManagerSpi.isRole(role);
    }*/

    public URMRole createRole(String role)
            throws URMNotImplementedException, URMForbiddenException, URMInsertException, URMInternalServerException {
        mRoleManagerSpi.createRole(role);
        return new URMRoleAdminImpl(role, mRoleManagerSpi, mUserDBManagerSpi, mMetadataPropsSpi);
    }

    public void deleteRole(String role)
            throws URMNotImplementedException, URMInternalServerException,
                   URMForbiddenException, URMDeleteException {
        if (role.equals(URMConstants.URM_GUEST_ROLE) || role.equals(URMConstants.URM_ADMIN_ROLE) || role.equals(URMConstants.URM_ROOT_ROLE))
            throw new URMForbiddenException(MessageLogger.getAndLogMessage(msLogger, "URMCOE0049"));
        /*if (mRoleManagerSpi.hasACEsOfSubject(role, null, URMConstants.ROLE))
            throw new URMDeleteException(MessageLogger.getAndLogMessage(msLogger, "URMTRE0010", role));*/
        mRoleManagerSpi.deleteRole(role);
        //aclListenerSet.resetEvent();
    }

    public URMRole getRole(String role)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        if (isRole(role))
            return new URMRoleAdminImpl(role,
                                        mRoleManagerSpi,
                                        mUserDBManagerSpi,
                                        mMetadataPropsSpi);
        else
            return null;
    }

    public Set getAllRoles()
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        return URMRoleAdminImpl.getURMRoleObjectSetFromSubjectSet(
                        mRoleManagerSpi.getAllRoles(), mRoleManagerSpi, mUserDBManagerSpi, mMetadataPropsSpi);
    }
    /******************* Role Manager end *************************/

    /******************* UserDB Manager ***************************/
    
    public Set getAllGroups(String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        return URMGroupAdminImpl.getURMGroupObjectSetFromStringSet(
                        mUserDBManagerSpi.getAllGroups(domain), domain,
                        mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi);
    }

    public Set getAllUsers(String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        return URMUserAdminImpl.getURMUserObjectSetFromStringSet(
                        mUserDBManagerSpi.getAllUsers(domain), domain,
                        mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi);
    }

    public void createUser(String user, char[] password, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInsertException {
        mUserDBManagerSpi.createUser(user, password, domain);
    }

    public void createGroup(String group, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInsertException {
        mUserDBManagerSpi.createGroup(group, domain);
    }

    public void deleteUser(String user, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMDeleteException, URMInternalServerException {
        /*if (mRoleManagerSpi.hasACEsOfSubject(user, domain, URMConstants.USER))
            throw new URMDeleteException(MessageLogger.getAndLogMessage(
                            msLogger, "URMTRE0010", domain != null ? (domain + "/") : "" + user));*/
        mRoleManagerSpi.deleteRoleMappingAndACEsOfUserGroupSubject(user, domain, true);
        mMetadataPropsSpi.deleteProperiesOfUser(user, domain);
        mUserDBManagerSpi.deleteUser(user, domain);
    }

    public void deleteGroup(String group, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMDeleteException, URMInternalServerException {
        /*if (mRoleManagerSpi.hasACEsOfSubject(group, domain, URMConstants.GROUP))
            throw new URMDeleteException(MessageLogger.getAndLogMessage(
                        msLogger, "URMTRE0010", domain != null ? (domain + "/") : "" + group));*/
        mRoleManagerSpi.deleteRoleMappingAndACEsOfUserGroupSubject(group, domain, false);
        mMetadataPropsSpi.deleteProperiesOfGroup(group, domain);
        mUserDBManagerSpi.deleteGroup(group, domain);
    }

    /*public boolean isUser(String user, String domain)
        throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        if (mUserDBManagerSpi == null) return false;
        return mUserDBManagerSpi.isUser(user, domain);
    }*/

    /*public boolean isGroup(String group, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        return mUserDBManagerSpi.isGroup(group, domain);
    }*/

    public URMUser getUser(String user, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        if (mUserDBManagerSpi.isUser(user, domain))
            return new URMUserAdminImpl(user, domain, mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi);
        else
            return null;
    }

    public URMGroup getGroup(String group, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        if (mUserDBManagerSpi.isGroup(group, domain))
            return new URMGroupAdminImpl(group, domain, mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi);
        else
            return null;
    }

    /******************* UserDB Manager end ***********************/
    
    public void synchronizeUsersGroupsRoles()
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException, URMDeleteException {
        mUserDBManagerSpi.clearCaches(); // to reread all users
        // remove metaproperties of needless users and group
        Set dmns = mMetadataPropsSpi.getAvailableDomains();
        for (Iterator iter = dmns.iterator(); iter.hasNext();) {
            String dmn = (String)iter.next();
            mMetadataPropsSpi.syncronizeUsersGroupsRoles(dmn,
                            mUserDBManagerSpi.getAllUsers(dmn),
                            mUserDBManagerSpi.getAllGroups(dmn));
        }
        // remove needless AccessControlElement and UserRoleMapping entries
        dmns = mRoleManagerSpi.getAvailableDomains();
        for (Iterator iter = dmns.iterator(); iter.hasNext();) {
            String dmn = (String)iter.next();
            mRoleManagerSpi.synchronizeUsersGroupsRoles(dmn,
                            mUserDBManagerSpi.getAllUsers(dmn),
                            mUserDBManagerSpi.getAllGroups(dmn));
        }
    }
}


