/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/src/urm/org/apache/slide/urm/accesscontroler/impl/URMAclValidatorImpl.java,v 1.4 2005/03/02 10:53:32 eckehard Exp $
 * $Revision: 1.4 $
 * $Date: 2005/03/02 10:53:32 $
 *
 * ====================================================================
 *
 * 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.
 */

/**
 * @author eckehard.hermann@softwareag.com
 * @author dieter.kessler@softwareag.com
 * @author zsolt.sasvarie@softwareag.com
 */

package org.apache.slide.urm.accesscontroler.impl;

import org.apache.slide.urm.accesscontroler.URMAccessCheckException;
import org.apache.slide.urm.accesscontroler.URMAclValidator;
import org.apache.slide.urm.accesscontroler.URMSemanticFactory;
import org.apache.slide.urm.common.URMConfigurationException;
import org.apache.slide.urm.common.URMConstants;
import org.apache.slide.urm.common.URMPrincipal;
import org.apache.slide.urm.common.URMConfigurator;
import org.apache.slide.urm.utils.messagelogger.MessageLogger;
import org.apache.slide.urm.URMException;
import org.apache.slide.urm.accesscontroler.URMSemantic;
import org.apache.slide.urm.authenticator.impl.URMGuestAdministratorImpl;
import org.apache.slide.urm.common.impl.URMPrincipalImpl;
import java.util.List;

public class URMAclValidatorImpl extends URMAclValidator {

    private static org.apache.log4j.Logger msLogger =
        org.apache.log4j.Logger.getLogger(URMAclValidator.class.getName());
    
    private URMSemantic mSemantic = null;
    private URMConfigurator validConf = null;
    public URMAclValidatorImpl(URMConfigurator validatorConf) throws URMException {
        validConf = validatorConf;
        mSemantic = getSemantic(validatorConf);
    }
    
    /** Processes an access check.
     *
     * @param principal the principal of the authenticated user.
     * @param resource List of ACLs in the order they should be validated
     * @param action the required action.
     * @return One of the predefined values URMPermit, URMDeny,
     *              URMIndeterminable, URMNotApplicable.
     *
     * @throws URMAccessCheckException if the access check fails.
     */
    public int accessCheck(URMPrincipal principal, List resource, String action)
        throws URMAccessCheckException {
        
        try {
            // if principal is null, use URMGuest account
            if (principal == null) principal = guestLogon();
        
            // check if mSemantic has allready been loaded, if not, try to load it
            return mSemantic.checkPermission(principal, resource, action);
        } catch (URMException e) {
            throw new URMAccessCheckException(msLogger, "E", e);
        }
    }
  
    /**
     * Loads the Semantic information out of the URM configuration and tryto set
     * the 'mSemantic' field
     *
     *
     * @throws   URMException
     *
     */
    protected static URMSemantic getSemantic(URMConfigurator aclAdminConf)  throws URMException {

        URMConfigurator semanticconf = aclAdminConf.getSubConfigurator("AclSemantic");
        
        if (semanticconf == null)
            throw new URMConfigurationException(MessageLogger.getAndLogMessage(
                                msLogger, "URMCOC0017", "AclSemantic"));
                                
        String semantic_factory_class_name = semanticconf.getProperties().getProperty(
                                                URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME);
            
        if (semantic_factory_class_name == null)
            throw new URMConfigurationException(
                MessageLogger.getAndLogMessage(msLogger, "URMCOC0002",
                    URMConstants.FACTORY_CLASS_ATTRIBUTE_NAME, "AclAdministrator/AclSemantic"));

        URMSemanticFactory semanticFactory = null;
        try {
            //semanticFactory = (URMSemanticFactory)URMClassInstantiator.newInstance(semantic_factory_class_name, udb_params);
            semanticFactory = URMSemanticFactory.newInstance(semanticconf);
        } catch (Exception e) {
            throw new URMConfigurationException("Cannot instantiate URMSemanticFactory class");
        }
        return semanticFactory.newSemantic();
    }
    
    /**
     * Returns an URMPrincipal with the active role URMGuest. This principal does
     * not have any access rights on the userdb by using the URMAdministrator
     *
     * @return URMPrincipal with active role URMGuest
     *
     * @throws URMException if an unexpected error
     */
    private  URMPrincipal guestLogon() throws URMException {
        Object owner = new Object();
        URMAclAdministratorImpl aclAdmin = new URMAclAdministratorImpl(validConf.getSubConfigurator("/Authenticator/Administrator"), owner);
        URMGuestAdministratorImpl urmAdmin = new URMGuestAdministratorImpl(validConf.getSubConfigurator("/Authenticator/Administrator"), owner);
        URMPrincipal guest = new URMPrincipalImpl(urmAdmin, aclAdmin);
        return guest;
    }
}

