/*
 *   Licensed to the Apache Software Foundation (ASF) under one
 *   or more contributor license agreements.  See the NOTICE file
 *   distributed with this work for additional information
 *   regarding copyright ownership.  The ASF licenses this file
 *   to you 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.directory.fortress.rest;

import org.apache.directory.fortress.core.AdminMgr;
import org.apache.directory.fortress.core.AdminMgrFactory;
import org.apache.directory.fortress.core.DelAdminMgr;
import org.apache.directory.fortress.core.DelAdminMgrFactory;
import org.apache.directory.fortress.core.ReviewMgr;
import org.apache.directory.fortress.core.ReviewMgrFactory;
import org.apache.directory.fortress.core.SecurityException;
import org.apache.directory.fortress.core.model.AdminRole;
import org.apache.directory.fortress.core.model.PermGrant;
import org.apache.directory.fortress.core.model.PermObj;
import org.apache.directory.fortress.core.model.Permission;
import org.apache.directory.fortress.core.model.Role;
import org.apache.directory.fortress.core.model.RoleRelationship;
import org.apache.directory.fortress.core.model.SDSet;
import org.apache.directory.fortress.core.model.User;
import org.apache.directory.fortress.core.model.UserRole;
import org.apache.directory.fortress.core.model.FortRequest;
import org.apache.directory.fortress.core.model.FortResponse;
import org.apache.log4j.Logger;

/**
 * Utility for EnMasse Server.  This class is thread safe.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class AdminMgrImpl extends AbstractMgrImpl
{
    /** A logger for this class */
    private static final Logger log = Logger.getLogger( AdminMgrImpl.class.getName() );

    
    /* No qualifier */ FortResponse addUser( FortRequest request )
    {
        FortResponse response = createResponse();
        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User)request.getEntity();
            User outUser = adminMgr.addUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse deleteUser( FortRequest request )
    {
        FortResponse response = createResponse();

        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User)request.getEntity();
            adminMgr.deleteUser( inUser );
            response.setEntity( inUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse disableUser( FortRequest request )
    {
        FortResponse response = createResponse();

        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User)request.getEntity();
            adminMgr.disableUser( inUser );
            response.setEntity( inUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse updateUser( FortRequest request )
    {
        FortResponse response = createResponse();

        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User) request.getEntity();
            User outUser = adminMgr.updateUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse changePassword( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User) request.getEntity();
            adminMgr.changePassword(inUser, inUser.getNewPassword());
            ReviewMgr reviewMgr = ReviewMgrFactory.createInstance( request.getContextId() );
            User outUser = reviewMgr.readUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse lockUserAccount( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User) request.getEntity();
            adminMgr.lockUserAccount( inUser );
            ReviewMgr reviewMgr = ReviewMgrFactory.createInstance( request.getContextId() );
            User outUser = reviewMgr.readUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse unlockUserAccount( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User) request.getEntity();
            adminMgr.unlockUserAccount( inUser );
            ReviewMgr reviewMgr = ReviewMgrFactory.createInstance( request.getContextId() );
            User outUser = reviewMgr.readUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse resetPassword( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            User inUser = (User) request.getEntity();
            adminMgr.resetPassword(inUser, inUser.getNewPassword());
            ReviewMgr reviewMgr = ReviewMgrFactory.createInstance( request.getContextId() );
            User outUser = reviewMgr.readUser( inUser );
            response.setEntity( outUser );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addRole( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Role inRole = (Role) request.getEntity();
            Role outRole = adminMgr.addRole( inRole );
            response.setEntity( outRole );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }
    
    
    /* No qualifier */ FortResponse deleteRole( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Role inRole = (Role) request.getEntity();
            adminMgr.deleteRole( inRole );
            response.setEntity( inRole );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse updateRole( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Role inRole = (Role) request.getEntity();
            Role outRole = adminMgr.updateRole( inRole );
            response.setEntity( outRole );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }
    
    
    /* No qualifier */ FortResponse assignUser( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            UserRole inRole = (UserRole) request.getEntity();
            adminMgr.assignUser( inRole );
            response.setEntity( inRole );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse deassignUser( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            UserRole inRole = (UserRole) request.getEntity();
            adminMgr.deassignUser( inRole );
            response.setEntity( inRole );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addPermission( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Permission inPerm = (Permission) request.getEntity();
            Permission outPerm = adminMgr.addPermission( inPerm );
            response.setEntity( outPerm );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse updatePermission( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Permission inPerm = (Permission) request.getEntity();
            Permission outPerm = adminMgr.updatePermission( inPerm );
            response.setEntity( outPerm );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse deletePermission( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            Permission inPerm = (Permission) request.getEntity();
            adminMgr.deletePermission( inPerm );
            response.setEntity( inPerm );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addPermObj( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            PermObj inObj = (PermObj) request.getEntity();
            PermObj outObj = adminMgr.addPermObj( inObj );
            response.setEntity( outObj );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse updatePermObj( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            PermObj inObj = (PermObj) request.getEntity();
            PermObj outObj = adminMgr.updatePermObj( inObj );
            response.setEntity( outObj );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse deletePermObj( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            PermObj inObj = (PermObj) request.getEntity();
            adminMgr.deletePermObj( inObj );
            response.setEntity( inObj );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    private void grantPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
        adminMgr.setAdmin( request.getSession() );
        Role role = new Role( permGrant.getRoleNm() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( false );
        adminMgr.grantPermission( perm, role );
    }

    
    private void grantAdminPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        DelAdminMgr delegatedAdminMgr = DelAdminMgrFactory.createInstance( request.getContextId() );
        delegatedAdminMgr.setAdmin( request.getSession() );
        AdminRole role = new AdminRole( permGrant.getRoleNm() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( true );
        delegatedAdminMgr.grantPermission( perm, role );
    }

    
    private void revokePerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
        adminMgr.setAdmin( request.getSession() );
        Role role = new Role( permGrant.getRoleNm() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( false );
        adminMgr.revokePermission( perm, role );
    }

    
    private void revokeAdminPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        DelAdminMgr delegatedAdminMgr = DelAdminMgrFactory.createInstance( request.getContextId() );
        delegatedAdminMgr.setAdmin( request.getSession() );
        AdminRole role = new AdminRole( permGrant.getRoleNm() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( true );
        delegatedAdminMgr.revokePermission( perm, role );
    }

    
    private void grantUserPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
        adminMgr.setAdmin( request.getSession() );
        User user = new User( permGrant.getUserId() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( false );
        adminMgr.grantPermission( perm, user );
    }

    
    private void grantAdminUserPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        DelAdminMgr delegatedAdminMgr = DelAdminMgrFactory.createInstance( request.getContextId() );
        delegatedAdminMgr.setAdmin( request.getSession() );
        User user = new User( permGrant.getUserId() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( true );
        delegatedAdminMgr.grantPermission( perm, user );
    }

    
    private void revokeUserPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
        adminMgr.setAdmin( request.getSession() );
        User user = new User( permGrant.getUserId() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( false );
        adminMgr.revokePermission( perm, user );
    }

    
    private void revokeAdminUserPerm( FortRequest request ) throws SecurityException
    {
        PermGrant permGrant = (PermGrant) request.getEntity();
        DelAdminMgr delegatedAdminMgr = DelAdminMgrFactory.createInstance( request.getContextId() );
        delegatedAdminMgr.setAdmin( request.getSession() );
        User user = new User( permGrant.getUserId() );
        Permission perm = new Permission( permGrant.getObjName(), permGrant.getOpName(), permGrant.getObjId() );
        perm.setAdmin( true );
        delegatedAdminMgr.revokePermission( perm, user );
    }

    
    /* No qualifier */ FortResponse grant(FortRequest request, FortressServiceImpl fortressService)
    {
        FortResponse response = createResponse();

        
        try
        {
            PermGrant permGrant = (PermGrant) request.getEntity();
        
            if ( permGrant.isAdmin() )
            {
                grantAdminPerm( request );
            }
            else
            {
                grantPerm( request );
            }
            
            response.setEntity(permGrant);
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse revoke(FortRequest request, FortressServiceImpl fortressService)
    {
        FortResponse response = createResponse();

        
        try
        {
            PermGrant permGrant = (PermGrant) request.getEntity();
            
            if (permGrant.isAdmin())
            {
                revokeAdminPerm( request );
            }
            else
            {
                revokePerm( request );
            }
            response.setEntity( permGrant );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse grantUser(FortRequest request, FortressServiceImpl fortressService)
    {
        FortResponse response = createResponse();

        
        try
        {
            PermGrant permGrant = (PermGrant) request.getEntity();
            
            if ( permGrant.isAdmin() )
            {
                grantAdminUserPerm( request );
            }
            else
            {
                grantUserPerm( request );
            }
            
            response.setEntity( permGrant );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse revokeUser(FortRequest request, FortressServiceImpl fortressService)
    {
        FortResponse response = createResponse();

        
        try
        {
            PermGrant permGrant = (PermGrant) request.getEntity();
            
            if ( permGrant.isAdmin() )
            {
                revokeAdminUserPerm( request );
            }
            else
            {
                revokeUserPerm( request );
            }
            
            response.setEntity( permGrant );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addDescendant( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            RoleRelationship relationship = (RoleRelationship) request.getEntity();
            adminMgr.addDescendant(relationship.getParent(), relationship.getChild());
            response.setEntity( relationship );

        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addAscendant( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            RoleRelationship relationship = (RoleRelationship) request.getEntity();
            adminMgr.addAscendant(relationship.getChild(), relationship.getParent());
            response.setEntity( relationship );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse addInheritance( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            RoleRelationship relationship = (RoleRelationship) request.getEntity();
            adminMgr.addInheritance(relationship.getParent(), relationship.getChild());
            response.setEntity( relationship );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse deleteInheritance( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            RoleRelationship relationship = (RoleRelationship) request.getEntity();
            adminMgr.deleteInheritance( relationship.getParent(), relationship.getChild() );
            response.setEntity( relationship );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse createSsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.createSsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse updateSsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.updateSsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse addSsdRoleMember( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            Role role = new Role( request.getValue() );
            SDSet outSet = adminMgr.addSsdRoleMember( inSet, role );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse deleteSsdRoleMember( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            Role role = new Role( request.getValue() );
            SDSet outSet = adminMgr.deleteSsdRoleMember( inSet, role );
            response.setEntity(outSet);
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse deleteSsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.deleteSsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse setSsdSetCardinality( FortRequest request )
    {
        FortResponse response = createResponse();

        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.setSsdSetCardinality( inSet, inSet.getCardinality() );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse createDsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.createDsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse updateDsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.updateDsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse addDsdRoleMember( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            Role role = new Role(request.getValue());
            SDSet outSet = adminMgr.addDsdRoleMember( inSet, role );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse deleteDsdRoleMember( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            Role role = new Role(request.getValue());
            SDSet outSet = adminMgr.deleteDsdRoleMember( inSet, role );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }

        return response;
    }

    
    /* No qualifier */ FortResponse deleteDsdSet( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.deleteDsdSet( inSet );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }

    
    /* No qualifier */ FortResponse setDsdSetCardinality( FortRequest request )
    {
        FortResponse response = createResponse();

        
        try
        {
            AdminMgr adminMgr = AdminMgrFactory.createInstance( request.getContextId() );
            adminMgr.setAdmin( request.getSession() );
            SDSet inSet = (SDSet) request.getEntity();
            SDSet outSet = adminMgr.setDsdSetCardinality( inSet, inSet.getCardinality() );
            response.setEntity( outSet );
        }
        catch ( SecurityException se )
        {
            createError( response, log, se );
        }
        
        return response;
    }
}