/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/urm/org/apache/slide/urm/authenticator/userdb/impl/URMGroupAdminImpl.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.userdb.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.apache.slide.urm.URMForbiddenException;
import org.apache.slide.urm.URMNotImplementedException;
import org.apache.slide.urm.authenticator.URMSubject;
import org.apache.slide.urm.authenticator.rolemanager.URMRoleManagerSpi;
import org.apache.slide.urm.authenticator.userdb.URMMetadataPropsSpi;
import org.apache.slide.urm.authenticator.userdb.URMUserDBManagerSpi;
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.URMUpdateException;
import org.apache.slide.urm.utils.messagelogger.MessageLogger;
import org.apache.slide.urm.utils.validatorcache.URMListener;

/**
 * Implementation of the GroupAdmin class.
 *
 * @author eckehard.hermann@softwareag.com
 * @author dieter.kessler@softwareag.com
 * @author zsolt.sasvarie@softwareag.com
 */
public class URMGroupAdminImpl extends URMGroupImpl {

    private static org.apache.log4j.Logger msLogger =
        org.apache.log4j.Logger.getLogger(URMGroupAdminImpl.class.getName());
    
    // get event listeners
    private URMListener aclListenerSet = URMListener.getAclListenerSet();
    
    /*
     * Constructor: create new URMUser instance
     *
     * @param user name
     * @param domain name
     * @param URMUserDBManagerSpi
     * @param URMRoleManagerSpi
     */
    public URMGroupAdminImpl(String groupname, String domain,
                        URMUserDBManagerSpi userDbManagerSpi,
                        URMMetadataPropsSpi metadataPropsSpi,
                        URMRoleManagerSpi roleManagerSpi) {
        super(groupname, domain, userDbManagerSpi, metadataPropsSpi, roleManagerSpi);
    }

    public Set getGroupMembers()
            throws URMNotImplementedException, URMForbiddenException, URMInternalServerException {
        List membernames = mUserDBManagerSpi.getGroupMembers(mGroupName, mDomain);
        HashSet retmembers = new HashSet();
        if (membernames == null)
            return retmembers;
        Iterator iter = membernames.iterator();
        String member = null;
        // groups
        while (iter.hasNext())
            if ((member = (String)iter.next()) != null)
                retmembers.add(new URMGroupAdminImpl(member, mDomain,
                                        mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi));
            else
                break;
        // users
        while (iter.hasNext())
            if ((member = (String)iter.next()) != null)
                retmembers.add(new URMUserAdminImpl(member, mDomain,
                                        mUserDBManagerSpi, mMetadataPropsSpi, mRoleManagerSpi));
        return retmembers;
    }

    public static Set getURMGroupObjectSetFromStringSet(Set groupnames, String domain,
                                                    URMUserDBManagerSpi userDbManagerSpi,
                                                    URMMetadataPropsSpi metadataPropsSpi,
                                                    URMRoleManagerSpi roleManagerSpi) {
        if (groupnames == null)
            return null;
        Iterator iter = groupnames.iterator();
        HashSet retgrps = new HashSet();
        while (iter.hasNext())
            retgrps.add(new URMGroupAdminImpl((String)iter.next(), domain,
                                        userDbManagerSpi, metadataPropsSpi, roleManagerSpi));
        return retgrps;
    }
    
    public static Set getURMGroupObjectSetFromSubjectSet(Set subjects,
                                                    URMUserDBManagerSpi userDbManagerSpi,
                                                    URMMetadataPropsSpi metadataPropsSpi,
                                                    URMRoleManagerSpi roleManagerSpi) {
        if (subjects == null)
            return null;
        Iterator iter = subjects.iterator();
        HashSet retgrps = new HashSet();
        while (iter.hasNext()) {
            URMSubject subj = (URMSubject)iter.next();
            retgrps.add(new URMGroupAdminImpl(subj.getName(), subj.getDomain(),
                                        userDbManagerSpi, metadataPropsSpi, roleManagerSpi));
        }
        return retgrps;
    }
   
    public void addUserToGroup(String user, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMInsertException {
        mUserDBManagerSpi.addUserToGroup(user, mGroupName, domain);
        aclListenerSet.resetEvent();
    }

    public void removeUserFromGroup(String user, String domain)
            throws URMNotImplementedException, URMForbiddenException, URMDeleteException {
        mUserDBManagerSpi.removeUserFromGroup(user, mGroupName, domain);
        aclListenerSet.resetEvent();
    }

    public void addGroupToGroup(String group, String domain) throws URMNotImplementedException, URMForbiddenException, URMInsertException {
        mUserDBManagerSpi.addGroupToGroup(group, mGroupName, domain);
        aclListenerSet.resetEvent();
    }

    public void removeGroupFromGroup(String group, String domain) throws URMNotImplementedException, URMForbiddenException, URMDeleteException {
        mUserDBManagerSpi.removeGroupFromGroup(group, mGroupName, domain);
        aclListenerSet.resetEvent();
    }

    public void linkToRole(String role)
            throws URMNotImplementedException, URMForbiddenException, URMInsertException, URMInternalServerException {
        if (!mRoleManagerSpi.isRole(role))
            throw new URMInternalServerException(MessageLogger.getAndLogMessage(msLogger, "URMCOE0055", role));

        mRoleManagerSpi.addGroupLink(role, mDomain, mGroupName);
        aclListenerSet.resetEvent();
    }

    public void deleteRoleLink(String role)
            throws URMNotImplementedException, URMForbiddenException, URMDeleteException, URMInternalServerException {
        mRoleManagerSpi.deleteGroupLink(role, mGroupName, mDomain);
        aclListenerSet.resetEvent();
    }


    /**
     * Sets new subject specific properties
     *
     * @param key property key
     * @param prop property value
     *
     * @exception URMNotImplementedException if the method is not
     *            implemented by the user database.
     * @exception URMForbiddenException if the user has not the permission
     *            to invoke the method.
     * @exception URMException if an unpredictable internal error occurs
     */
    public void setProperty(String key, Object prop) throws URMNotImplementedException, URMForbiddenException, URMUpdateException, URMDeleteException, URMInternalServerException{
        //Properties props = mUserDBManagerSpi.getGroupProperties(mGroupName, mDomain);
        Properties props = new Properties();
        props.setProperty(key, (String) prop);
        setProperties(props);
                
    }

    public void setProperties(Properties inProps)
            throws URMNotImplementedException, URMForbiddenException, URMUpdateException, URMDeleteException, URMInternalServerException {
        if (inProps == null)
            return;
        if (mMetadataPropsSpi != null) {
            Properties udbprops  = new Properties();
            Properties metaprops = new Properties();
            Set availablemetaprops = mMetadataPropsSpi.getAvailableGroupPropKeys();
            Set writeablemetaprops = mMetadataPropsSpi.getWriteableGroupPropKeys();
            Set availableuserdbprops = mUserDBManagerSpi.getAvailablePropKeys(false);
            Set writeableuserdbprops = mUserDBManagerSpi.getWriteablePropKeys(false);
            for (Iterator keys = inProps.keySet().iterator(); keys.hasNext();) {
                String key = (String)keys.next();
                if (availablemetaprops.contains(key)) {
                    if (writeablemetaprops.contains(key))
                        metaprops.setProperty(key, (String)inProps.getProperty(key));
                    else
                        throw new URMUpdateException(MessageLogger.getAndLogMessage(msLogger, "URMMPE0001", key));
                }
                else
                    if (availableuserdbprops.contains(key)) {
                        if (writeableuserdbprops.contains(key))
                            udbprops.setProperty(key, (String)inProps.getProperty(key));
                        else
                            throw new URMUpdateException(MessageLogger.getAndLogMessage(msLogger, "URMSUE0006", key));
                    }
            }
            if (udbprops.size() > 0)
                mUserDBManagerSpi.setGroupProperties(mGroupName, mDomain, udbprops);
            if (metaprops.size() > 0)
                mMetadataPropsSpi.setProperties(mGroupName, mDomain, metaprops, false);
        }
        else
            mUserDBManagerSpi.setGroupProperties(mGroupName, mDomain, inProps);
    }

}
