/*
 * Copyright 2003,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.pluto.core;

import org.apache.pluto.Constants;
import org.apache.pluto.PortletContainerException;
import org.apache.pluto.descriptors.portlet.PortletAppDD;
import org.apache.pluto.descriptors.portlet.PortletDD;
import org.apache.pluto.internal.InternalPortletConfig;
import org.apache.pluto.internal.InternalPortletContext;
import org.apache.pluto.internal.InternalPortletRequest;
import org.apache.pluto.internal.InternalPortletResponse;
import org.apache.pluto.internal.impl.ActionRequestImpl;
import org.apache.pluto.internal.impl.ActionResponseImpl;
import org.apache.pluto.internal.impl.PortletConfigImpl;
import org.apache.pluto.internal.impl.RenderRequestImpl;
import org.apache.pluto.internal.impl.RenderResponseImpl;

import javax.portlet.Portlet;
import javax.portlet.PortletException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;

/**
 * Portlet Invocation Servlet. This servlet recieves cross context requests from
 * the the container and services the portlet request for the specified method.
 *
 * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
 * @author <a href="mailto:zheng@apache.org">ZHENG Zhong</a>
 * @version 1.1
 * @since 09/22/2004
 */
public class PortletServlet extends HttpServlet {

    // Private Member Variables ------------------------------------------------

    /**
     * The portlet name as defined in the portlet app descriptor.
     */
    private String portletName = null;

    /**
     * The portlet instance wrapped by this servlet.
     */
    private Portlet portlet = null;

    /**
     * The internal portlet context instance.
     */
    private InternalPortletContext portletContext = null;

    /**
     * The internal portlet config instance.
     */
    private InternalPortletConfig portletConfig = null;

    // HttpServlet Impl --------------------------------------------------------

    public String getServletInfo() {
        return "Pluto PortletServlet [" + portletName + "]";
    }

    /**
     * Initialize the portlet invocation servlet.
     *
     * @throws ServletException if an error occurs while loading portlet.
     */
    public void init() throws ServletException {

        // Call the super initialization method.
        super.init();

        // Retrieve portlet name as defined as an initialization parameter.
        portletName = getInitParameter("portlet-name");

        // Retrieve the associated internal portlet context.
        ServletContext servletContext = getServletContext();
        try {
            portletContext = PortletContextManager.getManager()
                .register(servletContext);

        } catch (PortletContainerException ex) {
            throw new ServletException(ex);
        }

        // Retrieve the portletDD and create portlet config.
        PortletDD portletDD = null;
        PortletAppDD portletAppDD =
            portletContext.getPortletApplicationDefinition();
        for (Iterator it = portletAppDD.getPortlets().iterator();
             it.hasNext();) {
            PortletDD currentDD = (PortletDD) it.next();
            if (currentDD.getPortletName().equals(portletName)) {
                portletDD = currentDD;
                break;
            }
        }
        if (portletDD == null) {
            throw new ServletException("Unable to resolve portlet '"
                + portletName + "'");
        }
        portletConfig = new PortletConfigImpl(getServletConfig(),
            portletContext,
            portletDD);

        // Create and initialize the portlet wrapped in the servlet.
        try {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            Class clazz = loader.loadClass((portletDD.getPortletClass()));
            portlet = (Portlet) clazz.newInstance();
            portlet.init(portletConfig);
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
            throw new ServletException(ex);
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
            throw new ServletException(ex);
        } catch (InstantiationException ex) {
            ex.printStackTrace();
            throw new ServletException(ex);
        } catch (PortletException ex) {
            ex.printStackTrace();
            throw new ServletException(ex);
        }
    }

    public void destroy() {
        PortletContextManager.getManager().remove(portletContext);
        if (portlet != null) {
            portlet.destroy();
        }
        super.destroy();
    }

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response)
        throws ServletException, IOException {
        dispatch(request, response);
    }

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
        throws ServletException, IOException {
        dispatch(request, response);
    }

    protected void doPut(HttpServletRequest request,
                         HttpServletResponse response)
        throws ServletException, IOException {
        dispatch(request, response);
    }

    // Private Methods ---------------------------------------------------------

    /**
     * Dispatch the request to the appropriate portlet methods. This method
     * assumes that the following attributes are set in the servlet request
     * scope:
     * <ul>
     * <li>METHOD_ID: indicating which method to dispatch.</li>
     * <li>PORTLET_REQUEST: the internal portlet request.</li>
     * <li>PORTLET_RESPONSE: the internal portlet response.</li>
     * </ul>
     *
     * @param request  the servlet request.
     * @param response the servlet response.
     * @throws ServletException
     * @throws IOException
     */
    private void dispatch(HttpServletRequest request,
                          HttpServletResponse response)
        throws ServletException, IOException {
        InternalPortletRequest portletRequest = null;
        InternalPortletResponse portletResponse = null;
        try {

            // Save portlet config into servlet request.
            request.setAttribute(Constants.PORTLET_CONFIG, portletConfig);

            // Retrieve attributes from the servlet request.
            Integer methodId = (Integer) request.getAttribute(
                Constants.METHOD_ID);
            portletRequest = (InternalPortletRequest) request.getAttribute(
                Constants.PORTLET_REQUEST);
            portletResponse = (InternalPortletResponse) request.getAttribute(
                Constants.PORTLET_RESPONSE);
            portletRequest.init(portletContext, request);

            // The requested method is RENDER: call Portlet.render(..)
            if (methodId == Constants.METHOD_RENDER) {
                RenderRequestImpl renderRequest =
                    (RenderRequestImpl) portletRequest;
                RenderResponseImpl renderResponse =
                    (RenderResponseImpl) portletResponse;
                portlet.render(renderRequest, renderResponse);

            }

            // The requested method is ACTION: call Portlet.processAction(..)
            else if (methodId == Constants.METHOD_ACTION) {
                ActionRequestImpl actionRequest =
                    (ActionRequestImpl) portletRequest;
                ActionResponseImpl actionResponse =
                    (ActionResponseImpl) portletResponse;
                portlet.processAction(actionRequest, actionResponse);
            }

            // The requested method is NOOP: do nothing.
            else if (methodId == Constants.METHOD_NOOP) {
                // Do nothing.
            }

        } catch (javax.portlet.UnavailableException ex) {
            ex.printStackTrace();
            /*
            if (e.isPermanent()) {
                throw new UnavailableException(e.getMessage());
            } else {
                throw new UnavailableException(e.getMessage(), e.getUnavailableSeconds());
            }*/

            // Portlet.destroy() isn't called by Tomcat, so we have to fix it.
            try {
                portlet.destroy();
            } catch (Throwable th) {
                // Don't care for Exception
            }

            // TODO: Handle everything as permanently for now.
            throw new javax.servlet.UnavailableException(ex.getMessage());

        } catch (PortletException ex) {
            ex.printStackTrace();
            throw new ServletException(ex);

        } finally {
            request.removeAttribute(Constants.PORTLET_CONFIG);
            if (portletRequest != null) {
                portletRequest.release();
            }
        }
    }
}
