/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): Michel-Ange ANTON
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.jonasadmin.security;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

import javax.management.ObjectName;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionMapping;
import org.ow2.jonas.lib.management.extensions.base.JonasManagementRepr;
import org.ow2.jonas.lib.util.JonasObjectName;
import org.ow2.jonas.webapp.jonasadmin.Jlists;


/**
 *
 */

abstract public class BaseMemoryRealmAction extends BaseSecurityAction {

// --------------------------------------------------------- Public Methods

// --------------------------------------------------------- Protected Methods
    protected MemoryRealmForm getForm(final ActionMapping p_Mapping, final HttpServletRequest p_Request) {
        // Form used
        MemoryRealmForm oForm = null;
        // Memory realm to edit
        String sResource = p_Request.getParameter("resource");

        // Build a new form
        if (sResource != null) {
            oForm = new MemoryRealmForm();
            m_Session.setAttribute("memoryRealmForm", oForm);
            oForm.reset(p_Mapping, p_Request);
            oForm.setResource(sResource);
            // free old items of session
            m_Session.removeAttribute("userMemoryRealmForm");
            m_Session.removeAttribute("roleMemoryRealmForm");
            m_Session.removeAttribute("groupMemoryRealmForm");
            m_Session.removeAttribute("itemsMemoryRealmForm");
        }
        else {
            oForm = (MemoryRealmForm) m_Session.getAttribute("memoryRealmForm");
        }
        return oForm;
    }

    /**
     * Remove of session the <code>ItemsMemoryRealmForm</code> instance
     * if the given type is different of the current type.
     *
     * @param p_Type Current type (user, role, group)
     */
    protected void removeItemsMemoryRealmForm(final String p_Type) {
        ItemsMemoryRealmForm oForm = (ItemsMemoryRealmForm) m_Session.getAttribute(
            "itemsMemoryRealmForm");
        if (oForm != null) {
            if ((oForm.getType() != null) && (oForm.getType().equals(p_Type) == false)) {
                m_Session.removeAttribute("itemsMemoryRealmForm");
            }
        }
    }

    /**
     * Populate the <code>UserMemoryRealmForm</code> with MBeans.
     * If the user name is null, the User MBean is not called to populate the form.
     *
     * @param p_RealmForm Used for the resource name
     * @param p_UserForm Form to populate
     * @param p_UserName The user (Can be null)
     * @throws Exception
     */
    protected void populateUserForm(final MemoryRealmForm p_RealmForm, final UserMemoryRealmForm p_UserForm
        , final String p_UserName, final String domainName, final String jonasServerName)
        throws Exception {

        if (p_UserName != null) {
            // Populate with Mbean 'user'
            ObjectName oObjectName = JonasObjectName.user(domainName, p_RealmForm.getResource(), p_UserName);
            p_UserForm.setUser(getStringAttribute(oObjectName, "Name"));

            p_UserForm.setListGroupsUser(new ArrayList(Arrays.asList((String[]) JonasManagementRepr.
                getAttribute(oObjectName, "ArrayGroups", jonasServerName))));
            p_UserForm.setListGroupsUsed(new ArrayList(p_UserForm.getListGroupsUser()));

            p_UserForm.setListRolesUser(new ArrayList(Arrays.asList((String[]) JonasManagementRepr.
                getAttribute(oObjectName, "ArrayRoles", jonasServerName))));
            p_UserForm.setListRolesUsed(new ArrayList(p_UserForm.getListRolesUser()));
        }
        // Populate with Mbean 'realm'
        ObjectName oObjectName = JonasObjectName.securityMemoryFactory(domainName, p_RealmForm.getResource());
        p_UserForm.setListGroupsRealm(new ArrayList(Arrays.asList((String[]) JonasManagementRepr.
            invoke(oObjectName, "listGroups", null, null, jonasServerName))));
        p_UserForm.setListRolesRealm(new ArrayList(Arrays.asList((String[]) JonasManagementRepr.
            invoke(oObjectName, "listRoles", null, null, jonasServerName))));

        // Calculate Unused
        ArrayList alUnused = new ArrayList(p_UserForm.getListGroupsRealm());
        alUnused.removeAll(p_UserForm.getListGroupsUser());
        Collections.sort(alUnused);
        p_UserForm.setListGroupsNotused(alUnused);

        alUnused = new ArrayList(p_UserForm.getListRolesRealm());
        alUnused.removeAll(p_UserForm.getListRolesUser());
        Collections.sort(alUnused);
        p_UserForm.setListRolesNotused(alUnused);

        // Format list to string
        p_UserForm.setGroupsUsed(Jlists.getString(p_UserForm.getListGroupsUsed(), Jlists.SEPARATOR));
        p_UserForm.setGroupsNotused(Jlists.getString(p_UserForm.getListGroupsNotused()
            , Jlists.SEPARATOR));
        p_UserForm.setRolesUsed(Jlists.getString(p_UserForm.getListRolesUsed(), Jlists.SEPARATOR));
        p_UserForm.setRolesNotused(Jlists.getString(p_UserForm.getListRolesNotused()
            , Jlists.SEPARATOR));
    }

    /**
     * Encrypt a password with MBean security service method.
     * @param domainName domain name
     * @param p_Password Password to encrypt
     * @param p_EncrypMethod MD5 or SHA string
     * @return The encrypted password
     * @throws Exception
     */
    protected String encryptPassword(final String domainName, final String p_Password, final String p_EncrypMethod, final String jonasServerName)
        throws Exception {
        ObjectName onSecurityService = JonasObjectName.securityService(domainName);
        String[] asParam = {
            p_Password, p_EncrypMethod};
        String[] asSignature = {
            "java.lang.String", "java.lang.String"};
        return (String) JonasManagementRepr.invoke(onSecurityService, "encryptPassword", asParam
            , asSignature, jonasServerName);
    }

    /**
     * Populate the <code>RoleMemoryRealmForm</code> with MBeans.
     * If the Role name is null, the Role MBean is not called to populate the form.
     * @param domainName domain name
     * @param p_RealmForm Used for the resource name
     * @param p_RoleForm Form to populate
     * @param p_RoleName The user (Can be null)
     * @throws Exception
     */
    protected void populateRoleForm(final String domainName, final MemoryRealmForm p_RealmForm, final RoleMemoryRealmForm p_RoleForm
        , final String p_RoleName)
        throws Exception {

        if (p_RoleName != null) {
            // Populate with Mbean 'Role'
            ObjectName oObjectName = JonasObjectName.role(domainName, p_RealmForm.getResource(), p_RoleName);
            p_RoleForm.setRole(getStringAttribute(oObjectName, "Name"));
        }
    }

    /**
     * Populate the <code>GroupMemoryRealmForm</code> with MBeans.
     * If the user name is null, the Group MBean is not called to populate the form.
     * @param domainName the domain name
     * @param p_RealmForm Used for the resource name
     * @param p_GroupForm Form to populate
     * @param p_GroupName The user (Can be null)
     * @throws Exception
     */
    protected void populateGroupForm(final String domainName, final MemoryRealmForm p_RealmForm, final GroupMemoryRealmForm p_GroupForm
        , final String p_GroupName, final String jonasServerName)
        throws Exception {

        if (p_GroupName != null) {
            // Populate with Mbean 'group'
            ObjectName oObjectName = JonasObjectName.group(domainName, p_RealmForm.getResource(), p_GroupName);
            p_GroupForm.setGroup(getStringAttribute(oObjectName, "Name"));
            p_GroupForm.setDescription(getStringAttribute(oObjectName, "Description"));

            p_GroupForm.setListRolesGroup(new ArrayList(Arrays.asList((String[])
                JonasManagementRepr.getAttribute(oObjectName, "ArrayRoles", jonasServerName))));
            p_GroupForm.setListRolesUsed(new ArrayList(p_GroupForm.getListRolesGroup()));
        }
        // Populate with Mbean 'realm'
        ObjectName oObjectName = JonasObjectName.securityMemoryFactory(domainName, p_RealmForm.getResource());
        p_GroupForm.setListRolesRealm(new ArrayList(Arrays.asList((String[]) JonasManagementRepr.
            invoke(oObjectName, "listRoles", null, null, jonasServerName))));

        // Calculate Unused
        ArrayList alUnused = new ArrayList(p_GroupForm.getListRolesRealm());
        alUnused.removeAll(p_GroupForm.getListRolesGroup());
        Collections.sort(alUnused);
        p_GroupForm.setListRolesNotused(alUnused);

        // Format list to string
        p_GroupForm.setRolesUsed(Jlists.getString(p_GroupForm.getListRolesUsed(), Jlists.SEPARATOR));
        p_GroupForm.setRolesNotused(Jlists.getString(p_GroupForm.getListRolesNotused()
            , Jlists.SEPARATOR));
    }
}
