/*
 * $Id: PermissionTagBase.java,v 1.21 2005/08/04 13:46:43 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: PermissionTagBase.java,v $
 * Revision 1.21  2005/08/04 13:46:43  marbobo
 * + getEntityName() hinzugefügt
 *
 * Revision 1.20  2005/07/14 18:33:34  marbobo
 * + Dokument-Kontext hinzugefügt
 *
 * Revision 1.19  2005/02/14 14:30:41  bigmac
 * *** empty log message ***
 *
 * Revision 1.18  2005/02/14 14:01:48  bigmac
 * Applikationsweites CSS konfigurierbar gemacht + Refactorings
 *
 * Revision 1.17  2004/11/10 15:02:53  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.16  2004/10/31 03:03:06  marbobo
 * + Unterstützung für Rekursive-Rechte-Überprüfung
 *
 * Revision 1.15  2004/07/20 15:26:00  jonyp
 * added support for new parameter "value"
 *
 * Revision 1.14  2004/07/06 14:24:43  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.13  2004/06/24 23:35:16  marbobo
 * Quellcode maintenance
 *
 * Revision 1.12  2004/05/24 16:49:05  jonyp
 * new content: virtual document
 *
 * Revision 1.11  2004/03/24 13:10:23  bigmac
 * -AclAble
 *
 * Revision 1.10  2004/03/15 13:40:03  bigmac
 * Anpassungen an PermissionManager und weitere Refactorings
 *
 * Revision 1.9  2004/03/02 23:07:16  bigmac
 * Anpassungen an VKCDocumentSerializer und VKCCategorySerializer
 *
 * Revision 1.8  2004/02/20 16:32:25  bigmac
 * + context "subfolder"
 *
 * Revision 1.7  2004/02/09 13:21:59  bigmac
 * *** empty log message ***
 *
 * Revision 1.6  2003/08/02 16:13:36  bigmac
 * *** empty log message ***
 *
 * Revision 1.5  2003/07/04 08:58:03  lawern
 * Debug-Ausgaben rausgenommen
 *
 * Revision 1.4  2003/04/02 10:34:52  bigmac
 * *** empty log message ***
 *
 * Revision 1.3  2003/03/05 09:33:30  jonyp
 * Changes of TageBase due to changed call to WebShare.database.hasPermission (
 *
 * Revision 1.2  2003/02/26 10:13:43  jonyp
 * forceLogin flag
 *
 * Revision 1.1  2003/02/23 13:23:41  koppy
 * Initiale Version
 *
 */
package vkc.view.tag;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;
import vkc.db.entities.VKCUser;
import vkc.exception.DBException;
import vkc.misc.VKCLogManager;
import vkc.security.PermissionManager;
import vkc.security.VKCAcl;
import vkc.util.ServletUtils;
import vkc.view.WebShare;

/**
 * Tag zur Überprüfung der Rechte eines Users auf einer VKC Entität
 * (VKCCategory, VKCDocument, VKCGroup)
 *
 * @author koppy
 */
public abstract class PermissionTagBase extends TagSupport {
    /** Id des zu überprüfenden Users */
    private String userId = null;

    /** Permission token */
    private String requiredPerm = null;

    /** Context, might be one of (category, document, group) */
    private String context = null;

    /** Id in dem verwendeten Context */
    private String contextId = null;

    /** Name der Entity */
    private String entityName = null;

    /** value true/false */
    private String value = null;

    /** value true/false */
    private String recursiv = null;

    /**
     * Konstruktor
     */
    public PermissionTagBase() {
        super();
    }

    /**
     * Überprüft die Rechte des Users
     *
     * @return true, falls Benutzer berechtigt ist, sonst false
     *
     * @throws JspException
     */
    protected boolean hasPermission() throws JspException {
        // vkcuser aus der session holen
        VKCUser user = ServletUtils.getUser( (HttpServletRequest) pageContext.getRequest() );

        // userId
        if ( getUserId() == null ) {
            if ( user == null ) {
                throw new JspException( "VKCUser in session scope not found! (KEY=" + WebShare.USER_KEY + ")");
            }

            setUserId( user.getUserId().toString() );
        }

        if ( getRequiredPerm() == null ) {
            // use default Perm token
            setRequiredPerm( "r" );
        }

        try {
            Object entity = getEntity();

            if ( entity == null ) {
				throw new JspException( "Attribute " + context + " not found in any scope." );
			}

			// Acl holen
			VKCAcl acl = null;

			if ( entity instanceof VKCCategory ) {
				VKCCategory c = (VKCCategory)entity;
				acl = c.getAcl();

	            if ( getRecursiv() != null && getRecursiv().toLowerCase().trim().equals( "true" ) ) {
	                try {
                        return PermissionManager.hasPermissionsRecursiv( c.getCategoryId(), user, getRequiredPerm() );
                    } catch ( Exception e ) {
                        VKCLogManager.errorLog( this, "1", "Exception while checking permission!", e );
                        throw new JspException( e );
                    }
	            }
				
				if ( acl == null ) {
	                throw new JspException( "ACL of the corresponding entity points to null!");
	            }
	
                boolean hasPermission = PermissionManager.hasPermission( acl, user, getRequiredPerm().charAt( 0 ) );
  
                // no parameter given
                if ( getValue() == null ) {
                	return hasPermission;  
                }
  
                // parameter given, check, if user HAS permission
                // value = true, permission = true   ==>  return true 
                // value = true, permission = false  ==>  return false
                
                if ( "true".equals( getValue() ) ) {
                	return hasPermission;
                }
                
                // parameter given, check, if user HAS NOT the permission 
                // value = false, permission = true   ==>  return false 
				// value = false, permission = false  ==>  return true

				if ( "false".equals( getValue() ) ) {
					return !hasPermission;
				}
                
                // should never happen...
                return false;                
        	}
        	        	
        	if ( entity instanceof VKCDocument ) {
        	    return ( (VKCDocument) entity ).hasPermission( user, getRequiredPerm().charAt( 0 ) );
        	}
        	
        	// default
        	return false;
        } catch ( DBException ex ) {
            VKCLogManager.errorLog( this, "1", "DBException while checking permission!", ex );
            throw new JspException( ex );
        }
    }

    /**
     * Gibt je nach Kontext die entsprechende Entität zurück
     *
     * @return the entity of the given context
     *
     * @throws JspTagException , DBException
     */
    protected Object getEntity() {
    	if (getEntityName() != null) {
    		return pageContext.findAttribute(getEntityName());
    	}
    	
        if ( getContext().equals("category") ) {
            return pageContext.findAttribute( "category" );
        } else if ( getContext().equals("subfolder") ) {
			return pageContext.findAttribute( "subfolder" );
		} else if ( getContext().equals("virtualDocument") ) {
			return pageContext.findAttribute( "virtualDocument" );
        } else if ( getContext().equals("document") ) {
			return pageContext.findAttribute( "document" );
        } else {
        	return null;
        }
    }

    /**
     * Allokierte Resourcen wieder freigeben
     */
    public void release() {
        super.release();

        userId = null;
        requiredPerm = null;
        contextId = null;
        context = null;
        value = null;
        recursiv = null;
    }

    /**
     * Getter/ Setter für die verfügbaren Attribute
     */
    public String getContextId() {
        return contextId;
    }

    public void setContextId( String cid ) {
        contextId = cid;
    }

    public String getRequiredPerm() {
        return requiredPerm;
    }

    public void setRequiredPerm( String rp ) {
        requiredPerm = rp;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId( String uid ) {
        userId = uid;
    }

    public String getContext() {
        return context;
    }

    public void setContext( String ctx ) {
        context = ctx;
    }

	public String getValue() {
		return value;
	}

	public void setValue( String string ) {
		value = string;
	}

	public String getRecursiv() {
		return recursiv;
	}

	public void setRecursiv( String string ) {
		recursiv = string;
	}

	public String getEntityName() {
		return entityName;
	}

	public void setEntityName(String entityName) {
		this.entityName = entityName;
	}
}
