/*
 * 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.jasper.runtime;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.VariableResolver;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.VariableInfo;

import org.apache.commons.el.VariableResolverImpl;
import org.apache.jasper.compiler.Localizer;

/**
 * Implementation of a JSP Context Wrapper.
 *
 * The JSP Context Wrapper is a JspContext created and maintained by a tag
 * handler implementation. It wraps the Invoking JSP Context, that is, the
 * JspContext instance passed to the tag handler by the invoking page via
 * setJspContext().
 *
 * @author Kin-man Chung
 * @author Jan Luehe
 */
public class JspContextWrapper
            extends PageContext implements VariableResolver {

    // Invoking JSP context
    private PageContext invokingJspCtxt;

    private transient Hashtable	pageAttributes;

    // ArrayList of NESTED scripting variables
    private ArrayList nestedVars;

    // ArrayList of AT_BEGIN scripting variables
    private ArrayList atBeginVars;

    // ArrayList of AT_END scripting variables
    private ArrayList atEndVars;

    private Map aliases;

    private Hashtable originalNestedVars;

    /**
     * The variable resolver, for evaluating EL expressions.
     */
    private VariableResolverImpl variableResolver
        = new VariableResolverImpl(this);

    public JspContextWrapper(JspContext jspContext, ArrayList nestedVars,
			     ArrayList atBeginVars, ArrayList atEndVars,
			     Map aliases) {
        this.invokingJspCtxt = (PageContext) jspContext;
	this.nestedVars = nestedVars;
	this.atBeginVars = atBeginVars;
	this.atEndVars = atEndVars;
	this.pageAttributes = new Hashtable(16);
	this.aliases = aliases;

	if (nestedVars != null) {
	    this.originalNestedVars = new Hashtable(nestedVars.size());
	}
	syncBeginTagFile();
    }

    public void initialize(Servlet servlet, ServletRequest request,
                           ServletResponse response, String errorPageURL,
                           boolean needsSession, int bufferSize,
                           boolean autoFlush)
        throws IOException, IllegalStateException, IllegalArgumentException
    {
    }
    
    public Object getAttribute(String name) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	return pageAttributes.get(name);
    }

    public Object getAttribute(String name, int scope) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	if (scope == PAGE_SCOPE) {
	    return pageAttributes.get(name);
	}

	return invokingJspCtxt.getAttribute(name, scope);
    }

    public void setAttribute(String name, Object value) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	if (value != null) {
	    pageAttributes.put(name, value);
	} else {
	    removeAttribute(name, PAGE_SCOPE);
	}
    }

    public void setAttribute(String name, Object value, int scope) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	if (scope == PAGE_SCOPE) {
	    if (value != null) {
		pageAttributes.put(name, value);
	    } else {
		removeAttribute(name, PAGE_SCOPE);
	    }
	} else {
	    invokingJspCtxt.setAttribute(name, value, scope);
	}
    }

    public Object findAttribute(String name) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

        Object o = pageAttributes.get(name);
        if (o == null) {
	    o = invokingJspCtxt.getAttribute(name, REQUEST_SCOPE);
	    if (o == null) {
		if (getSession() != null) {
		    o = invokingJspCtxt.getAttribute(name, SESSION_SCOPE);
		}
		if (o == null) {
		    o = invokingJspCtxt.getAttribute(name, APPLICATION_SCOPE);
		} 
	    }
	}

	return o;
    }

    public void removeAttribute(String name) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	pageAttributes.remove(name);
	invokingJspCtxt.removeAttribute(name, REQUEST_SCOPE);
	if (getSession() != null) {
	    invokingJspCtxt.removeAttribute(name, SESSION_SCOPE);
	}
	invokingJspCtxt.removeAttribute(name, APPLICATION_SCOPE);
    }

    public void removeAttribute(String name, int scope) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	if (scope == PAGE_SCOPE){
	    pageAttributes.remove(name);
	} else {
	    invokingJspCtxt.removeAttribute(name, scope);
	}
    }

    public int getAttributesScope(String name) {

	if (name == null) {
	    throw new NullPointerException(
	            Localizer.getMessage("jsp.error.attribute.null_name"));
	}

	if (pageAttributes.get(name) != null) {
	    return PAGE_SCOPE;
	} else {
	    return invokingJspCtxt.getAttributesScope(name);
	}
    }

    public Enumeration getAttributeNamesInScope(int scope) {
        if (scope == PAGE_SCOPE) {
            return pageAttributes.keys();
	}

	return invokingJspCtxt.getAttributeNamesInScope(scope);
    }

    public void release() {
	invokingJspCtxt.release();
    }

    public JspWriter getOut() {
	return invokingJspCtxt.getOut();
    }

    public HttpSession getSession() {
	return invokingJspCtxt.getSession();
    }

    public Object getPage() {
	return invokingJspCtxt.getPage();
    }

    public ServletRequest getRequest() {
	return invokingJspCtxt.getRequest();
    }

    public ServletResponse getResponse() {
	return invokingJspCtxt.getResponse();
    }

    public Exception getException() {
	return invokingJspCtxt.getException();
    }

    public ServletConfig getServletConfig() {
	return invokingJspCtxt.getServletConfig();
    }

    public ServletContext getServletContext() {
	return invokingJspCtxt.getServletContext();
    }

    public void forward(String relativeUrlPath)
        throws ServletException, IOException
    {
	invokingJspCtxt.forward(relativeUrlPath);
    }

    public void include(String relativeUrlPath)
	throws ServletException, IOException
    {
	invokingJspCtxt.include(relativeUrlPath);
    }

    public void include(String relativeUrlPath, boolean flush) 
	    throws ServletException, IOException {
	include(relativeUrlPath, false); // XXX
    }

    public VariableResolver getVariableResolver() {
	return this;
    }

    public BodyContent pushBody() {
	return invokingJspCtxt.pushBody();
    }

    public JspWriter pushBody(Writer writer) {
	return invokingJspCtxt.pushBody(writer);
    }

    public JspWriter popBody() {
        return invokingJspCtxt.popBody();
    }

    public ExpressionEvaluator getExpressionEvaluator() {
	return invokingJspCtxt.getExpressionEvaluator();
    }

    public void handlePageException(Exception ex)
        throws IOException, ServletException 
    {
	// Should never be called since handleException() called with a
	// Throwable in the generated servlet.
	handlePageException((Throwable) ex);
    }

    public void handlePageException(Throwable t)
        throws IOException, ServletException 
    {
	invokingJspCtxt.handlePageException(t);
    }

    /**
     * VariableResolver interface
     */
    public Object resolveVariable( String pName ) throws ELException
    {
        return variableResolver.resolveVariable(pName);
    }

    /**
     * Synchronize variables at begin of tag file
     */
    public void syncBeginTagFile() {
	saveNestedVariables();
    }

    /**
     * Synchronize variables before fragment invokation
     */
    public void syncBeforeInvoke() {
	copyTagToPageScope(VariableInfo.NESTED);
	copyTagToPageScope(VariableInfo.AT_BEGIN);
    }

    /**
     * Synchronize variables at end of tag file
     */
    public void syncEndTagFile() {
	copyTagToPageScope(VariableInfo.AT_BEGIN);
	copyTagToPageScope(VariableInfo.AT_END);
	restoreNestedVariables();
    }

    /**
     * Copies the variables of the given scope from the virtual page scope of
     * this JSP context wrapper to the page scope of the invoking JSP context.
     *
     * @param scope variable scope (one of NESTED, AT_BEGIN, or AT_END)
     */
    private void copyTagToPageScope(int scope) {
	Iterator iter = null;

	switch (scope) {
	case VariableInfo.NESTED:
	    if (nestedVars != null) {
		iter = nestedVars.iterator();
	    }
	    break;
	case VariableInfo.AT_BEGIN:
	    if (atBeginVars != null) {
		iter = atBeginVars.iterator();
	    }
	    break;
	case VariableInfo.AT_END:
	    if (atEndVars != null) {
		iter = atEndVars.iterator();
	    }
	    break;
	}

	while ((iter != null) && iter.hasNext()) {
	    String varName = (String) iter.next();
	    Object obj = getAttribute(varName);
	    varName = findAlias(varName);
	    if (obj != null) {
		invokingJspCtxt.setAttribute(varName, obj);
	    } else {
		invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
	    }
	}
    }

    /**
     * Saves the values of any NESTED variables that are present in
     * the invoking JSP context, so they can later be restored.
     */
    private void saveNestedVariables() {
	if (nestedVars != null) {
	    Iterator iter = nestedVars.iterator();
	    while (iter.hasNext()) {
		String varName = (String) iter.next();
		varName = findAlias(varName);
		Object obj = invokingJspCtxt.getAttribute(varName);
		if (obj != null) {
		    originalNestedVars.put(varName, obj);
		}
	    }
	}
    }

    /**
     * Restores the values of any NESTED variables in the invoking JSP
     * context.
     */
    private void restoreNestedVariables() {
	if (nestedVars != null) {
	    Iterator iter = nestedVars.iterator();
	    while (iter.hasNext()) {
		String varName = (String) iter.next();
		varName = findAlias(varName);
		Object obj = originalNestedVars.get(varName);
		if (obj != null) {
		    invokingJspCtxt.setAttribute(varName, obj);
		} else {
		    invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
		}
	    }
	}
    }

    /**
     * Checks to see if the given variable name is used as an alias, and if so,
     * returns the variable name for which it is used as an alias.
     *
     * @param varName The variable name to check
     * @return The variable name for which varName is used as an alias, or
     * varName if it is not being used as an alias
     */
    private String findAlias(String varName) {

	if (aliases == null)
	    return varName;

	String alias = (String) aliases.get(varName);
	if (alias == null) {
	    return varName;
	}
	return alias;
    }
}

