/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/security/admin/URMGroupsStore.java,v 1.3 2004/07/30 06:52:01 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:01 $
 *
 * ====================================================================
 *
 * 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.store.tamino.security.admin;
import com.softwareag.common.instrumentation.logging.Level;
import com.softwareag.common.instrumentation.logging.Logger;
import com.softwareag.common.instrumentation.logging.LoggerFactory;
import com.softwareag.common.instrumentation.logging.LoggerUtil;
import java.util.Vector;
import org.apache.slide.common.ServiceAccessException;
import org.apache.slide.common.Uri;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.content.RevisionNotFoundException;
import org.apache.slide.store.tamino.jdomobjects.XFactory;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.structure.SubjectNode;
import org.apache.slide.util.ClassName;


/**
 ** @author    josef.haiduk@softwareag.com
 ** @version   $Revision: 1.3 $
 **
 **/
public class URMGroupsStore extends URMUserDBStore {
    
    private static final String LOGNAME = LoggerUtil.getThisClassName();
    private static final String CLASSNAME = new ClassName(LOGNAME).getPlainName();
    private static Logger logger = LoggerFactory.getLogger(LOGNAME);
    
    /**
     ** Default constructor.
     **/
    public URMGroupsStore() {
        super();
    }
        
    public synchronized ObjectNode retrieveObject(Uri uri)
        throws ServiceAccessException, ObjectNotFoundException {
        
        logEnter("retrieveObject",uri);
        String uriStr = uri.toString();
        Vector children = new Vector(0);
        ObjectNode result = new SubjectNode(uriStr, children, new Vector(0));
        
        if ( getPrincipal() == null )
            return result;
        
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
        // groups/
        if ( urmGroupsGate.isHome() ) {
            urmGroupsGate.enumerateObjects(children);
            return new SubjectNode(uriStr, children ,new Vector(0));
        }
        
        // groups/G1
        if ( urmGroupsGate.objectExists() && urmGroupsGate.isParentHome() ) {
            //urmGroupsGate.enumerateMembers(children);
            return new SubjectNode(uriStr, children ,new Vector(0));
        }
        
        logExit("retrieveObject FAILED", uri.toString()+" ObjectNotFound");
        throw new ObjectNotFoundException(uriStr);
   }
    
    public synchronized void createObject(Uri uri, ObjectNode object)
    throws ServiceAccessException, ObjectAlreadyExistsException {
       
        logEnter("createObject",uri);
        String uriStr = uri.toString();
       
        if ( getPrincipal() == null ) {
            return;
        }
       
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
    
        if ( urmGroupsGate.isParentHome() && urmGroupsGate.objectExists())
           throw new ObjectAlreadyExistsException(uriStr);
        
        if ( urmGroupsGate.isParentHome() && !urmGroupsGate.objectExists()) {
            StoreInfo storeInfo = getStoredInfo();
            storeInfo.storeGroupBeingCreated(urmGroupsGate);
            return;
        }

    }

    public synchronized void storeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException
    {
        logEnter("storeObject",uri);
        String uriStr = uri.toString();
        
        if ( uriStr.equals(groupsPath) )
        {
            StoreInfo storeInfo = getStoredInfo();
            Vector groupsGates = storeInfo.getGroupsBeingCreated();
            storeInfo.clearGroupsBeingCreated();
            for (int i=0; i<groupsGates.size();i++) {
                URMGroupsGate urmGate = (URMGroupsGate)groupsGates.elementAt(i);
                urmGate.createObject();
            }
        }
    }
    
    public synchronized void removeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException
    {
        logEnter("removeObject",uri);
        String uriStr = uri.toString();
        
        if ( getPrincipal() == null ) {
            return;
        }
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
        // groups/G1
        if ( urmGroupsGate.objectExists() && urmGroupsGate.isParentHome() ) {
            urmGroupsGate.deleteObject();
            return;
        }
        
        logExit("removeObject FAILED",uri.toString()+" ObjectNotFound");
        throw new ObjectNotFoundException(uriStr);
    }
    
    
    // inherit docu from RevisionDescriptorStore interface
    public synchronized NodeRevisionDescriptor retrieveRevisionDescriptor
        (Uri uri, NodeRevisionNumber revisionNumber)
    throws ServiceAccessException, RevisionDescriptorNotFoundException {
        
        logEnter("retrieveRevisionDescriptor",uri);
        String uriStr = uri.toString();
        NodeRevisionDescriptor result = XFactory.createNRD(uriStr, COLLECTION);
        
        if ( getPrincipal() == null )
            return result;
        
        if ( uriStr.equals(groupsPath) )  {
            insertDisplayname(result, groupCollection);
            return result;
        }
    
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
        if ( urmGroupsGate.objectExists() && urmGroupsGate.isParentHome() ) {
            result = XFactory.createMemberNRD(uriStr);
            result.setResourceType(PRINCIPAL);
            String group = urmGroupsGate.getId();
            insertPrincipalUrl(result, groupsPath + "/" + group);
            insertAlternateUriSet(result, ""); // TODO: put somesthing senseful here, e.g. an LDAP scheme URL (RFC2255)
            insertDomainname(result);
            urmGroupsGate.insertMappedProperties(result);
            insertGroupmemberShip(result, groupsPath, urmGroupsGate.getParents() );
            insertGroupmemberShip(result, rolesPath, urmGroupsGate.getRoles() );
            insertGroupmemberSet(result, usersPath, urmGroupsGate.getUsers());
            insertGroupmemberSet(result, groupsPath, urmGroupsGate.getGroups());
            insertSubjectProperties(result, urmGroupsGate.getProperties(), urmGroupsGate.getAvailableProperties());
            return result;
        }
             
        logExit("retrieveRevisionDescriptor FAILED",uri.toString()+" RevisionDescriptorNotFound");
        throw new RevisionDescriptorNotFoundException(uriStr);
         
    }
    
    public synchronized void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException, RevisionDescriptorNotFoundException
    {
        
        logEnter("storeRevisionDescriptor",uri);
        String uriStr = uri.toString();
        
        if ( getPrincipal() == null )
            return;
        
        if ( uriStr.equals(groupsPath) )  {
            return;
        }
        
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
        
        if ( !urmGroupsGate.objectExists() ) {
            throw new RevisionDescriptorNotFoundException(uriStr);
        }
        else {
            urmGroupsGate.updateParents(revisionDescriptor);
            urmGroupsGate.updateMembers(revisionDescriptor);
            urmGroupsGate.setProperties(revisionDescriptor);
        }
    }
    
    // inherit docu from securityStore interface
    public synchronized NodeRevisionContent retrieveRevisionContent(
        Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException, RevisionNotFoundException {
        
        logEnter("retrieveRevisionContent",uri);
        String uriStr = uri.toString();
        
        NodeRevisionContent result = new NodeRevisionContent();
        if ( uriStr.equals(groupsPath) )  {
            result.setContent(uriStr.toCharArray());
            return result;
        }
        
        if ( getPrincipal() == null ) {
            result.setContent(uriStr.toCharArray());
            return result;
        }
        
        URMGroupsGate urmGroupsGate = new URMGroupsGate(this, uriStr);
        
        if ( urmGroupsGate.isParentHome() && urmGroupsGate.objectExists() ) {
            result.setContent(urmGroupsGate.getPropertiesAsBytes());
            return result;
        }
        
        
        logExit("retrieveRevisionContent FAILED",uri.toString()+" RevisionNotFound");
        throw new RevisionNotFoundException (uriStr,revisionDescriptor.getRevisionNumber());
    }
        
    private void logEnter(String method)
    {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, method);
    }
    
    private void logEnter(String method, Uri uri)
    {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, method, new Object[] {uri} );
    }
    
    private void logEnter(String method, Uri uri, String s1)
    {
        if( logger.isLoggable(Level.FINE) ) logger.entering( CLASSNAME, method,
            new Object[] {uri, (s1!=null ? s1 : null)} );
        
    }
    
    private void logExit(String method, Object result)
    {
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, method ,result);
    }
}


















