/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.myfaces.orchestra.lib.jsf;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Principal;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.faces.context.ExternalContext;

import org.apache.myfaces.orchestra.requestParameterProvider.RequestParameterProviderManager;

/**
 * Class used by _PortletFacesContextWrapper to allow orchestra work in portlets
 * 
 * This class wraps encodeActionURL and encodeResourceURL to include
 * conversationContext param like RequestParameterResponseWrapper does. In portlets
 * we can't do the same than is servlets, because the params added here must be
 * encoded by the portlet container and in portlets we don't have servlet redirect
 * cases.
 * 
 * @author Leonardo Uribe(latest modification by $Author: lu4242 $)
 * @version $Revision: 798382 $ $Date: 2009-07-27 22:23:02 -0500 (Mon, 27 Jul 2009) $
 */
public class PortletExternalContextWrapper extends ExternalContext
{
    private ExternalContext _delegate;

    public PortletExternalContextWrapper(ExternalContext context)
    {
        super();
        this._delegate = context;
    }

    public void dispatch(String arg0) throws IOException
    {
        _delegate.dispatch(arg0);
    }

    public String encodeActionURL(String url)
    {
        if (url != null)
        {
            url = RequestParameterProviderManager.getInstance().encodeAndAttachParameters(url);
        }
        return _delegate.encodeActionURL(url);
    }

    public String encodeNamespace(String arg0)
    {
        return _delegate.encodeNamespace(arg0);
    }

    public String encodeResourceURL(String url)
    {
        if (url != null)
        {
            url = RequestParameterProviderManager.getInstance().encodeAndAttachParameters(url);
        }
        return _delegate.encodeResourceURL(url);
    }

    public Map getApplicationMap()
    {
        return _delegate.getApplicationMap();
    }

    public String getAuthType()
    {
        return _delegate.getAuthType();
    }

    public Object getContext()
    {
        return _delegate.getContext();
    }

    public String getInitParameter(String arg0)
    {
        return _delegate.getInitParameter(arg0);
    }

    public Map getInitParameterMap()
    {
        return _delegate.getInitParameterMap();
    }

    public String getRemoteUser()
    {
        return _delegate.getRemoteUser();
    }

    public Object getRequest()
    {
        return _delegate.getRequest();
    }

    public String getRequestContextPath()
    {
        return _delegate.getRequestContextPath();
    }

    public Map getRequestCookieMap()
    {
        return _delegate.getRequestCookieMap();
    }

    public Map getRequestHeaderMap()
    {
        return _delegate.getRequestHeaderMap();
    }

    public Map getRequestHeaderValuesMap()
    {
        return _delegate.getRequestHeaderValuesMap();
    }

    public Locale getRequestLocale()
    {
        return _delegate.getRequestLocale();
    }

    public Iterator getRequestLocales()
    {
        return _delegate.getRequestLocales();
    }

    public Map getRequestMap()
    {
        return _delegate.getRequestMap();
    }

    public Map getRequestParameterMap()
    {
        return _delegate.getRequestParameterMap();
    }

    public Iterator getRequestParameterNames()
    {
        return _delegate.getRequestParameterNames();
    }

    public Map getRequestParameterValuesMap()
    {
        return _delegate.getRequestParameterValuesMap();
    }

    public String getRequestPathInfo()
    {
        return _delegate.getRequestPathInfo();
    }

    public String getRequestServletPath()
    {
        return _delegate.getRequestServletPath();
    }

    public URL getResource(String arg0) throws MalformedURLException
    {
        return _delegate.getResource(arg0);
    }

    public InputStream getResourceAsStream(String arg0)
    {
        return _delegate.getResourceAsStream(arg0);
    }

    public Set getResourcePaths(String arg0)
    {
        return _delegate.getResourcePaths(arg0);
    }

    public Object getResponse()
    {
        return _delegate.getResponse();
    }

    public Object getSession(boolean arg0)
    {
        return _delegate.getSession(arg0);
    }

    public Map getSessionMap()
    {
        return _delegate.getSessionMap();
    }

    public Principal getUserPrincipal()
    {
        return _delegate.getUserPrincipal();
    }

    public boolean isUserInRole(String arg0)
    {
        return _delegate.isUserInRole(arg0);
    }

    public void redirect(String arg0) throws IOException
    {
        _delegate.redirect(arg0);
    }

    public void log(String s, Throwable throwable)
    {
        _delegate.log(s, throwable);
    }

    public void log(String s)
    {
        _delegate.log(s);
    }
    
    //Methods since 1.2
    
    //Methods since 1.2
    
    public String getResponseContentType()
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "getResponseContentType", 
                    null);
            return (String) method.invoke(_delegate, null);
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }

    public void setRequest(java.lang.Object request)
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "setRequest", 
                    new Class[]{java.lang.Object.class});
            method.invoke(_delegate, new Object[]{request});
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }

    public void setRequestCharacterEncoding(java.lang.String encoding)
        throws java.io.UnsupportedEncodingException
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "setRequestCharacterEncoding", 
                    new Class[]{java.lang.String.class});
            method.invoke(_delegate, new Object[]{encoding});
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }
    
    public void setResponse(java.lang.Object response)
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "setResponse", 
                    new Class[]{java.lang.Object.class});
            method.invoke(_delegate, new Object[]{response});
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }
    
    public void setResponseCharacterEncoding(java.lang.String encoding)
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "setResponseCharacterEncoding", 
                    new Class[]{java.lang.String.class});
            method.invoke(_delegate, new Object[]{encoding});
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }

    public String getResponseCharacterEncoding()
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "getResponseCharacterEncoding", 
                    null);
            return (String) method.invoke(_delegate, null);
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }
        
    public String getRequestCharacterEncoding()
    {
        try
        {
            Method method = _delegate.getClass().getMethod(
                    "getRequestCharacterEncoding", 
                    null);
            return (String) method.invoke(_delegate, null);
        }
        catch (NoSuchMethodException e)
        {
            throw new RuntimeException("JSF 1.2 method not implemented: "+e.getMessage());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Error calling JSF 1.2 method: "+e.getMessage());
        }
    }
}
