/**
 * License Agreement.
 *
 * Rich Faces - Natural Ajax for Java Server Faces (JSF)
 *
 * Copyright (C) 2007 Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */
/*

 * Created on 25.09.2004

 *

 * 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.ajax4jsf.portlet.context;

import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletContext;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author shura Implementation of <code>FacesContextFactory</code> for
 *         Portlet
 * 
 * Environment Use default factory for create default Faces
 * 
 * implementation context and setup wrappers for it.
 * 
 * 
 * 
 * 
 * 
 */
public class FacesContextFactoryImpl extends FacesContextFactory {
	/**
	 * 
	 * Hold <code>FacesContextFactory</code> from default implementation.
	 * 
	 */
	// private FacesContextFactory defaultFacesContextFactory;
	private static final Log _log = LogFactory
			.getLog(FacesContextFactoryImpl.class);

	/**
	 * 
	 * Create instance of Faces context factory, based on implementation.
	 * 
	 * @param defaultFactory -
	 * 
	 * Factory from JSF implementation.
	 * 
	 */
	public FacesContextFactoryImpl(/* FacesContextFactory defaultFactory */) {
		super();
		// if (this.defaultFacesContextFactory == null) {
		// this.defaultFacesContextFactory = defaultFactory;
		// }
		if (_log.isDebugEnabled()) {
			_log.debug("Portal - specific FacesContextFactory has initialised");
		}
	}

	/*
	 * 
	 * (non-Javadoc)
	 * 
	 * 
	 * 
	 * @see javax.faces.context.FacesContextFactory#getFacesContext(java.lang.Object,
	 * 
	 * java.lang.Object, java.lang.Object, javax.faces.lifecycle.Lifecycle)
	 * 
	 */
	public FacesContext getFacesContext(Object context, Object request,
			Object response, Lifecycle lifecycle) throws FacesException {
		if ((null == context) || (null == request) || (null == response)
				|| (null == lifecycle)) {
			throw new NullPointerException(
					"One or more parameters for a faces context instantiation is null");
		}
		AbstractExternalContext externalContext;
		if ((context instanceof PortletContext)
				&& (request instanceof ActionRequest)
				&& (response instanceof ActionResponse)) {
			externalContext = new PortletContextImpl((PortletContext) context,
					(PortletRequest) request, (PortletResponse) response);
			if (_log.isDebugEnabled()) {
				_log
						.debug("Portal request - create portal version of the ExternalContext for action request");
			}
		} else if ((context instanceof PortletContext)
				&& (request instanceof RenderRequest)
				&& (response instanceof RenderResponse)) {
			externalContext = new PortletRenderContextImpl((PortletContext) context,
					(PortletRequest) request, (PortletResponse) response);
			if (_log.isDebugEnabled()) {
				_log
						.debug("Portal request - create portal version of the ExternalContext for render response");
			}
		} else if ((context instanceof ServletContext)
				&& (request instanceof HttpServletRequest)
				&& (response instanceof HttpServletResponse)) {
			externalContext = new ServletContextImpl((ServletContext) context,
					(HttpServletRequest) request,
					(HttpServletResponse) response);
			if (_log.isDebugEnabled()) {
				_log
						.debug("Servlet request - create HttpServlet version of the ExternalContext");
			}
		} else {
			throw new FacesException(
					"Unsupported environment. Only servlet or portlet is allowed");
		}
		return new FacesContextImpl(externalContext, lifecycle);
	}
}