/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/store/org/apache/slide/store/tamino/security/admin/URMActionsStore.java,v 1.4 2004/09/15 14:58:25 pnever Exp $
 * $Revision: 1.4 $
 * $Date: 2004/09/15 14:58:25 $
 *
 * ====================================================================
 *
 * 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.NodeProperty;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.content.NodeRevisionNumber;
import org.apache.slide.content.RevisionDescriptorNotFoundException;
import org.apache.slide.macro.ForbiddenException;
import org.apache.slide.store.tamino.common.XForbiddenException;
import org.apache.slide.store.tamino.common.XGlobals;
import org.apache.slide.store.tamino.jdomobjects.XFactory;
import org.apache.slide.store.tamino.tools.stores.ActionDeclaration;
import org.apache.slide.structure.ActionNode;
import org.apache.slide.structure.ObjectAlreadyExistsException;
import org.apache.slide.structure.ObjectNode;
import org.apache.slide.structure.ObjectNotFoundException;
import org.apache.slide.util.ClassName;
import org.apache.slide.util.XMLValue;
import org.apache.slide.util.XUri;
import org.jdom.Element;


/**
 ** @author    josef.haiduk@softwareag.com
 ** @version   $Revision: 1.4 $
 **
 **/
public class URMActionsStore 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);
    static String ACTION = "privilege";
    /**
     ** Default constructor.
     **/
    public URMActionsStore() {
        super();
    }
    
    public synchronized ObjectNode retrieveObject(Uri uri)
        throws ServiceAccessException, ObjectNotFoundException {
        
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            ObjectNode result = super.retrieveObject(uri);
             return result;
        }
        logEnter("retrieveObject",uri);
        String uriStr = uri.toString();
        Vector children = new Vector(0);
        
        URMActionsGate urmGate = null;
        if ( getPrincipal() == null )
            urmGate = new URMActionsGate(this, uriStr, URMGate.getGuest(this));
        else
            urmGate = new URMActionsGate(this, uriStr);
        
        if ( urmGate.isHome() ) {
            urmGate.enumerateActions(children);
            return new ActionNode(uriStr, children ,new Vector(0));
        }
        
        if ( urmGate.objectExists() && urmGate.isParentHome() ) {
            //urmGate.enumerateMembers(children);
            return new ActionNode(uriStr, children ,new Vector(0));
        }
        
        logExit("retrieveObject FAILED", uri);
        throw new ObjectNotFoundException(uriStr);
    }
    
    public synchronized void createObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectAlreadyExistsException {
        
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            super.createObject(uri, object);
            return;
        }
        
        if ( getPrincipal() == null ) {
            return;
        }
        
        logEnter("createObject",uri);
        String uriStr = uri.toString();
        
        URMActionsGate urmGate = new URMActionsGate(this, uriStr);
        if ( urmGate.isParentHome() && urmGate.objectExists())
            throw new ObjectAlreadyExistsException(uriStr);
        
        if ( urmGate.isParentHome() && !urmGate.objectExists()) {
            StoreInfo storeInfo = getStoredInfo();
            storeInfo.storeActionsBeingCreated(urmGate);
            return;
        }
    }
    
    public synchronized void storeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException {
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            super.storeObject(uri, object);
            return;
        }
        logEnter("storeObject",uri);
        String uriStr = uri.toString();
        
        if ( uriStr.equals(ActionDeclaration.SCOPE) ) {
            StoreInfo storeInfo = getStoredInfo();
            Vector gate = storeInfo.getActionsBeingCreated();
            storeInfo.clearActionsBeingCreated();
            for (int i=0; i<gate.size();i++) {
                URMActionsGate urmGate = (URMActionsGate)gate.elementAt(i);
                urmGate.createObject();
            }
            return;
        }
    }
    
    public synchronized void removeObject(Uri uri, ObjectNode object)
        throws ServiceAccessException, ObjectNotFoundException {
        XUri xuri = new XUri(uri.toString());
        if ( ActionDeclaration.lookup(xuri.lastSegment()) != null )
            throw new ServiceAccessException( this,
                                             new ForbiddenException(uri.toString(), new XForbiddenException( "removing of core actions is forbidden" )) );
        
        
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            super.removeObject(uri, object);
            return;
        }
        
        logEnter("removeObject",uri);
        String uriStr = uri.toString();
        
        URMActionsGate urmGate = new URMActionsGate(this, uriStr);
        
        if (!urmGate.objectExists() || !urmGate.isParentHome()) {
            logExit("removeObject FAILED",uri);
            throw new ObjectNotFoundException(uriStr);
        }
        
        urmGate.deleteObject();
        return;
        
    }
    
    
    // inherit docu from RevisionDescriptorStore interface
    public synchronized NodeRevisionDescriptor retrieveRevisionDescriptor
        (Uri uri, NodeRevisionNumber revisionNumber)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
        
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            return super.retrieveRevisionDescriptor(uri, revisionNumber);
        }
        
        logEnter("retrieveRevisionDescriptor",uri);
        String uriStr = uri.toString();
        String path = ActionDeclaration.SCOPE;
        NodeRevisionDescriptor result = XFactory.createNRD(uriStr, COLLECTION);
        
        URMActionsGate urmGate = null;
        if ( getPrincipal() == null )
            urmGate = new URMActionsGate(this, uriStr, URMGate.getGuest(this));
        else
            urmGate = new URMActionsGate(this, uriStr);
        
        if ( urmGate.isHome() )
            return result;
        
        if ( urmGate.objectExists() && urmGate.isParentHome() ) {
            result = XFactory.createMemberNRD(uriStr);
            insertResourceType(result);
            String action = urmGate.getId();
            
            /* test
             HashMap map = new HashMap();
             map.put("Action1",new Boolean(true));
             map.put("Action2",new Boolean(true));
             map.put("Action3",new Boolean(false));
             map.put("Action4",new Boolean(false));
             insertActionmemberSet(result, ActionDeclaration.SCOPE, map);
             */
            insertPrivilegememberSet(result, ActionDeclaration.SCOPE, urmGate.getActions());
            
            return result;
        }
        
        logExit("retrieveRevisionDescriptor FAILED",uri);
        throw new RevisionDescriptorNotFoundException(uriStr);
    }
    
    private void insertResourceType(NodeRevisionDescriptor nrd) {
        
        XMLValue xmlVal = new XMLValue();
        xmlVal.add( new Element(ACTION, XGlobals.TAMINO_NAMESPACE_PREFIX, XGlobals.TAMINO_NAMESPACE_URI) );
        NodeProperty resourcetypeProp = new NodeProperty(RESOURCETYPE, xmlVal);
        nrd.setProperty( resourcetypeProp );
    }
    
    public synchronized void storeRevisionDescriptor(Uri uri, NodeRevisionDescriptor revisionDescriptor)
        throws ServiceAccessException, RevisionDescriptorNotFoundException {
        if ( ! org.apache.slide.util.Configuration.useIntegratedSecurity() ) {
            return;
        }
        
        logEnter("storeRevisionDescriptor",uri);
        String uriStr = uri.toString();
        
        if ( getPrincipal() == null )
            return;
        
        if ( uriStr.equals(rolesPath) )  {
            return;
        }
        
        URMActionsGate urmGate = new URMActionsGate(this, uriStr);
        if ( urmGate.isHome() )
            return;
        if ( !urmGate.objectExists() ) {
            throw new RevisionDescriptorNotFoundException(uriStr);
        }
        else {
            //urmGate.updateActions(revisionDescriptor);
            urmGate.updateMembers(revisionDescriptor);
        }
        
    }
    /*
     synchronized URMPrincipal getPrincipal()
     throws ServiceAccessException
     {
     URMPrincipal p = super.getPrincipal();
     if ( p != null )
     return p;
     return URMGate.getGuest(this);
     }
     */
    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, String text) {
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, method ,text);
    }
    private void logExit(String method, Uri uri) {
        if( logger.isLoggable(Level.FINE) ) logger.exiting( CLASSNAME, method ,uri.toString());
    }
}


















