Package de.danet.an.util.jsf

Source Code of de.danet.an.util.jsf.MyFacesAdaptedPortlet$MyPortletExternalContextImpl

/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2005 Danet GmbH (www.danet.de), BU BTS.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Derived from MyFacesGenericPortlet,
* Copyright 2004 The Apache Software Foundation.
*
* $Id: MyFacesAdaptedPortlet.java 2921 2009-02-14 20:41:30Z mlipp $
*
* $Log$
* Revision 1.32  2007/05/27 15:23:34  mlipp
* Removed erroneously inserted localization in processAction.
*
* Revision 1.31  2007/05/27 10:03:05  mlipp
* Improved locale detection/setting.
*
* Revision 1.30  2007/05/26 22:55:50  mlipp
* Fixed file upload.
*
* Revision 1.29  2007/05/26 21:53:48  mlipp
* More debug infos.
*
* Revision 1.28  2007/05/22 14:04:45  drmlipp
* Avoid duplicate processing of multipart request.
*
* Revision 1.27  2007/02/26 22:12:28  mlipp
* Updated to MyFaces core 1.1.5/Tomahawk 1.1.3.
*
* Revision 1.26  2006/12/12 09:53:20  drmlipp
* Added Ajax support.
*
* Revision 1.25  2006/12/05 09:14:11  drmlipp
* Suppressing superfluous warning.
*
* Revision 1.24  2006/11/20 13:46:30  drmlipp
* Restore initial JSF state after exception.
*
* Revision 1.23  2006/10/11 19:31:59  mlipp
* Fixed problem with language switching.
*
* Revision 1.22  2006/09/29 12:32:11  drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.21  2006/09/20 15:27:43  drmlipp
* Workaround for strange ClasscastException.
*
* Revision 1.20  2006/09/12 12:56:18  drmlipp
* Fixed autoscroll for portlets.
*
* Revision 1.19  2006/09/11 15:29:28  drmlipp
* Improved portlet support.
*
* Revision 1.18  2006/09/08 14:08:06  drmlipp
* Started handling of MyFaces resource loading.
*
* Revision 1.17  2006/08/29 15:03:11  drmlipp
* Added JavaScript insertion to portlet bridge. Re-enabled scrolling support.
*
* Revision 1.16  2006/08/28 21:22:44  mlipp
* Updated MyFaces to 1.1.3.
*
* Revision 1.15  2006/05/31 20:52:18  mlipp
* Fixed problem with left over session data.
*
* Revision 1.14  2006/04/15 10:04:25  mlipp
* Removed Liferay bug workaround.
*
* Revision 1.13  2005/11/14 13:26:02  drmlipp
* Fixed problem with request attributes being passed between portlets
* (breaks MyFaces).
*
* Revision 1.12  2005/11/14 09:34:25  drmlipp
* Improved workaround for liferay bug.
*
* Revision 1.11  2005/11/10 20:52:55  mlipp
* Fixed problem with classloader dependend Lifecycle access.
*
* Revision 1.10  2005/11/10 16:04:23  drmlipp
* Workaround for liferay bug.
*
* Revision 1.9  2005/11/07 14:02:13  drmlipp
* Make action request attributes available during rendering.
*
* Revision 1.8  2005/10/11 12:31:38  drmlipp
* Fixed portlet mode comparison.
*
* Revision 1.7  2005/10/10 20:49:59  mlipp
* Improved JSF lifecycle support.
*
* Revision 1.6  2005/09/28 15:12:41  drmlipp
* Updated MyFaces to 1.1.
*
* Revision 1.5  2005/09/16 13:50:25  drmlipp
* Improved file upload support.
*
* Revision 1.4  2005/09/15 22:06:21  mlipp
* Upload implementation continued.
*
* Revision 1.3  2005/09/15 15:06:30  drmlipp
* Continuing implementation of upload portlet.
*
* Revision 1.2  2005/09/15 11:03:34  drmlipp
* Fixed mode issues.
*
* Revision 1.1  2005/09/13 13:43:29  drmlipp
* Using portlet/JSF bridge from MyFaces again (in an adapted version).
*
*/
package de.danet.an.util.jsf;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.application.FacesMessage;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.webapp.FacesServlet;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortalContext;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;
import javax.portlet.WindowState;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;
import org.apache.myfaces.config.FacesConfigurator;
import org.apache.myfaces.context.ReleaseableExternalContext;
import org.apache.myfaces.context.portlet.PortletExternalContextImpl;
import org.apache.myfaces.context.servlet.ServletFacesContextImpl;
import org.apache.myfaces.portlet.PortletUtil;
import org.apache.myfaces.renderkit.html.util.AddResource;
import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;

import de.danet.an.util.Misc;
import de.danet.an.util.logging.RequestLog;
import de.danet.an.util.logging.RequestScope;

/**
* This portlet initializes MyFaces and converts portlet requests into
* JSF requests.
*
* @author  Stan Silvert (latest modification by $Author: mlipp $)
*/
public class MyFacesAdaptedPortlet extends GenericPortlet {
    private static final org.apache.commons.logging.Log logger
        = org.apache.commons.logging.LogFactory
            .getLog(MyFacesAdaptedPortlet.class);

    // PortletSession attribute
    public static final String VIEW_ID
        = MyFacesAdaptedPortlet.class.getName() + ".VIEW_ID";

    public static final String PREV_MODE
    = MyFacesAdaptedPortlet.class.getName() + ".PREV_MODE";
   
    // PortletSession attribute
    public static final String CURRENT_FACES_CONTEXT
        = MyFacesAdaptedPortlet.class.getName() + ".CURRENT_FACES_CONTEXT";

    protected static final String FACES_INIT_DONE
        = MyFacesAdaptedPortlet.class.getName() + ".FACES_INIT_DONE";

    public static final String FILE_ITEMS
        = MyFacesAdaptedPortlet.class.getName() + ".FILE_ITEMS";
   
    public static final String REQUEST_ATTRIBUTES
        = MyFacesAdaptedPortlet.class.getName() + ".REQUEST_ATTRIBUTES";
   
    public static final String NAMESPACE_PREFIX
    = MyFacesAdaptedPortlet.class.getName() + ".NAMESPACE_PREFIX";

    public static final String LIFECYCLE_ID
    = MyFacesAdaptedPortlet.class.getName() + ".LIFECYCLE_ID";

    /** Name of portlet preference for Edit page. */
    protected static final String PARAM_EDIT_PAGE = "EditPage";

    /** Name of portlet preference for Edit page */
    protected static final String PARAM_HELP_PAGE = "HelpPage";

    /** Name of portlet preference for View page */
    protected static final String PARAM_VIEW_PAGE = "ViewPage";
   
    private static Set serializabilityWarnings = new HashSet();

    /** Private in JavascriptUtils, what a pity... */
    private static final String AUTO_SCROLL_PARAM = "autoScroll";
   
    /** Default URL for the edit page. */
    private String defaultEditPage = null;

    /** Default URL for the help page. */
    private String defaultHelpPage = null;

    /** Default URL for the view page. */
    private String defaultViewPage = null;

    private String uploadMaxFileSize = null;
    private String uploadThresholdSize = null;
   
    protected PortletContext portletContext;

    protected FacesContextFactory facesContextFactory;
    protected Lifecycle lifecycle;

    /**
     * Creates a new instance of MyFacesPortlet
     */
    public MyFacesAdaptedPortlet() {
    }

    /**
     * Portlet lifecycle.
     */
    public void destroy()
    {
        super.destroy();
        FactoryFinder.releaseFactories();
    }

    /**
     * Portlet lifecycle.
     */
    public void init() throws PortletException, UnavailableException
    {
        this.portletContext = getPortletContext();
        this.defaultViewPage = getPortletConfig()
            .getInitParameter(PARAM_VIEW_PAGE);
        this.defaultEditPage = getPortletConfig()
            .getInitParameter(PARAM_EDIT_PAGE);
        this.defaultHelpPage = getPortletConfig()
            .getInitParameter(PARAM_HELP_PAGE);
        uploadMaxFileSize = getPortletConfig()
            .getInitParameter("uploadMaxFileSize");
        uploadThresholdSize = getPortletConfig()
            .getInitParameter("uploadThresholdSize");

        if (null == this.defaultViewPage) {
            // A Faces Portlet is required to have at least the
            // defaultViewPage
            // defined!
            throw new PortletException(
                    "Portlet "
                            + getPortletConfig().getPortletName()
                            + " is incorrectly configured. No default View page is defined.");
        }
        initMyFaces();

        facesContextFactory = (FacesContextFactory) FactoryFinder
                .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);

        // Javadoc says: Lifecycle instance is shared across multiple simultaneous requests, it must be
        // implemented in a thread-safe manner.  So we can acquire it here once:
        LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
                .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
        lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
    }

    protected void setContentType(RenderRequest request, RenderResponse response)
    {
       
        if (response.getContentType() == null)
        {
            String portalPreferredContentType = request.getResponseContentType();
            if (portalPreferredContentType != null)
            {
                response.setContentType(portalPreferredContentType);
            }
            else
            {
                response.setContentType("text/html");
            }
        }
    }

    private String getLifecycleId() {
        String lifecycleId = getPortletConfig().getInitParameter(
                FacesServlet.LIFECYCLE_ID_ATTR);
        return lifecycleId != null ? lifecycleId
                : LifecycleFactory.DEFAULT_LIFECYCLE;
    }

    protected void initMyFaces()
    {
        try
        {
            Boolean b = (Boolean)portletContext.getAttribute(FACES_INIT_DONE);

            if (b == null || b.booleanValue() == false) {
                logger.trace("Initializing MyFaces");

                //Load the configuration
                ExternalContext externalContext = new PortletExternalContextImpl(
                        portletContext, null, null);

                //And configure everything
                new FacesConfigurator(externalContext).configure();

                // parse web.xml - not sure if this is needed for portlet
                WebXml.init(externalContext);

                portletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
            } else {
                logger.info("MyFaces already initialized");
            }
        } catch (Exception ex) {
            logger.error("Error initializing MyFacesAdaptedPortlet", ex);
        }

        logger.info("PortletContext '" + portletContext.getRealPath("/")
                + "' initialized.");
    }

    /**
     * Called by the portlet container to allow the portlet to process an
     * action request.
     */
    public void processAction(ActionRequest request, ActionResponse response)
            throws PortletException, IOException {
        RequestScope scope = RequestLog.enterScope
            (this, "processAction", new Object[] { request, response });
        try {
            doProcessAction(request, response);
        } finally {
            scope.leave();
        }
    }
   
    /**
     * Called by the portlet container to allow the portlet to process an
     * action request.
     */
    private void doProcessAction(ActionRequest request, ActionResponse response)
            throws PortletException, IOException {
        if (logger.isTraceEnabled())
            logger.trace("called processAction");

        if (sessionTimedOut(request)) {
            return;
        }

        if (logger.isDebugEnabled()) {
            dumpRequestInfo(request);
        }
       
        setPortletRequestFlag(request);

        FileUploadException uploadException = null;
        if (PortletFileUpload.isMultipartContent(request)) {
            try {
                DiskFileItemFactory dfif = new DiskFileItemFactory();
                if (uploadMaxFileSize != null) {
                    dfif.setSizeThreshold(resolveSize(uploadThresholdSize));
                }
                PortletFileUpload pfu = new PortletFileUpload(dfif);
                if (uploadMaxFileSize != null) {
                    pfu.setSizeMax(resolveSize(uploadMaxFileSize));
                }
                List items = pfu.parseRequest(request);
                Map reqParms = new HashMap (request.getParameterMap());
                // Liferay (and may be others) process multipart content
                // before calling processAction. Avoid doing it twice.
                Set preprocessed = new HashSet (reqParms.keySet());
                PortletSession session = request.getPortletSession();
                for (Iterator i = items.iterator(); i.hasNext();) {
                    FileItem item = (FileItem) i.next();
                    if (logger.isDebugEnabled()) {
                        logger.debug("Got file item: " + item);
                    }
                    if (item.isFormField()) {
                        if (preprocessed.contains (item.getFieldName())) {
                            continue;
                        }
                        if (!reqParms.containsKey(item.getFieldName())) {
                            reqParms.put(item.getFieldName(),
                                         new String[] { item.getString() });
                        } else {
                            String[] oldVals
                                = ((String[])reqParms.get(item.getFieldName()));
                            String[] newVals = new String[oldVals.length + 1];
                            System.arraycopy
                                (oldVals, 0, newVals, 0, oldVals.length);
                            newVals[oldVals.length] = item.getString();
                            reqParms.put(item.getFieldName(), newVals);
                        }
                    } else {
                        if (session.getAttribute(FILE_ITEMS) == null) {
                            session.setAttribute(FILE_ITEMS, new HashMap());
                        }
                        ((Map)session.getAttribute(FILE_ITEMS))
                            .put(item.getFieldName(), item);
                    }
                }
                request = new ActionRequestWrapper(request, reqParms);
            } catch (FileUploadException e) {
                uploadException = e;
            }
        }

        FacesContext facesContext = facesContext(request, response);

        if (uploadException != null) {
            JSFUtil.addMessage
                (FacesMessage.SEVERITY_ERROR,
                 facesContext.getViewRoot().getLocale(),
                 "de.danet.an.util.I18n", "error.sizeLimitExceeded",
                 new Object [] { uploadMaxFileSize }, uploadException);
        }
       
        try {
            request.setAttribute(JSFUtil.LIFECYCLE, lifecycle);
            List oldAttrs = Collections.list(request.getAttributeNames());
            lifecycle.execute(facesContext);
            Map newAttrs = new HashMap ();
            for (Enumeration e = request.getAttributeNames();
                e.hasMoreElements();) {
                String name = (String)e.nextElement();
                if (oldAttrs.contains(name)
                    || (name.equals
                        ("org.apache.myfaces.application.jsp"
                         + ".JspStateManagerImpl.RESTORED_SERIALIZED_VIEW"))) {
                    continue;
                }
                Object val = request.getAttribute(name);
                request.removeAttribute(name);
                if (!(val instanceof Serializable)) {
                    String valClassName = val.getClass().getName();
                    if (!serializabilityWarnings.contains(valClassName)) {
                        logger.warn("Request attribute " + name + " is of "
                            + "non-serializable type " + valClassName
                            + " and will not be available during rendering");
                        serializabilityWarnings.add (valClassName);
                    }
                    continue;
                }
                newAttrs.put(name, val);
            }
            request.getPortletSession()
                .setAttribute(REQUEST_ATTRIBUTES, newAttrs);
            // Carry AUTO_SCROLL_PARAM over to rendering
            if (request.getParameter(AUTO_SCROLL_PARAM) != null) {
                request.getPortletSession().setAttribute
                    (AUTO_SCROLL_PARAM, request.getParameter(AUTO_SCROLL_PARAM));
            }

            if (!facesContext.getResponseComplete()) {
                request.getPortletSession().setAttribute(VIEW_ID,
                        facesContext.getViewRoot().getViewId());
            }

            request.getPortletSession().setAttribute(CURRENT_FACES_CONTEXT,
                    facesContext);
        } catch (Throwable e) {
            facesContext.release();
            handleExceptionFromLifecycle(e);
        } finally {
            Map fileItemMap = ((Map)request
                    .getPortletSession().getAttribute (FILE_ITEMS));
            if (fileItemMap != null) {
                for (Iterator i=fileItemMap.values().iterator(); i.hasNext();) {
                    FileItem item = (FileItem)i.next();
                    item.delete();
                }
                request.getPortletSession().removeAttribute(FILE_ITEMS);
            }
        }
    }

    private int resolveSize(String param) {
        param = param.toLowerCase();
        int factor = 1;
        String number = param;
       
        if (param.endsWith("g")) {
            factor = 1024 * 1024 * 1024;
            number = param.substring(0, param.length() - 1);
        } else if (param.endsWith("m")) {
            factor = 1024 * 1024;
            number = param.substring(0, param.length() - 1);
        } else if (param.endsWith("k")) {
            factor = 1024;
            number = param.substring(0, param.length() - 1);
        }
        return Integer.parseInt(number) * factor;
    }

    protected void handleExceptionFromLifecycle(Throwable e)
            throws PortletException, IOException
    {
        logException(e, null);

        if (e instanceof IOException)
        {
            throw (IOException)e;
        }

        if (e instanceof PortletException)
        {
            throw (PortletException)e;
        }

        if (e.getMessage() != null)
        {
            throw new PortletException(e.getMessage(), e);
        }

        throw new PortletException(e);
    }

    /**
     * Helper method to serve up the view mode.
     */
    protected void doView(RenderRequest request, RenderResponse response)
            throws PortletException, IOException
    {
        RequestScope scope = RequestLog.enterScope
            (this, "doView", new Object[] { request, response });
        try {
            facesRender(request, response);
        } finally {
            scope.leave();
        }
    }

    /**
     * Helper method to serve up the edit mode.  Can be overridden to add
     * the edit mode concept to a JSF application.
     */
    protected void doEdit(RenderRequest request, RenderResponse response)
            throws PortletException, IOException
    {
        RequestScope scope = RequestLog.enterScope
            (this, "doEdit", new Object[] { request, response });
        try {
            facesRender(request, response);
        } finally {
            scope.leave();
        }
    }

    /**
     * Helper method to serve up the edit mode.  Can be overridden to add
     * the help mode concept to a JSF application.
     */
    protected void doHelp(RenderRequest request, RenderResponse response)
            throws PortletException, IOException
    {
        RequestScope scope = RequestLog.enterScope
            (this, "doHelp", new Object[] { request, response } );
        try {
            facesRender(request, response);
        } finally {
            scope.leave();
        }
    }

    /**
     * This method follows JSF Spec section 2.1.1.  It renders the default view from a non-faces
     * request.
     *
     * @param request The portlet render request.
     * @param response The portlet render response.
     */
    protected void nonFacesRequest(RenderRequest request, RenderResponse response) throws PortletException
    {
        nonFacesRequest(request, response, selectDefaultView(request, response));
       
    }

    /**
     * This method follows JSF Spec section 2.1.1.  It renders a view from a non-faces
     * request.  This is useful for a default view as well as for views that need to
     * be rendered from the portlet's edit and help buttons.
     *
     * @param request The portlet render request.
     * @param response The portlet render response.
     * @param view The name of the view that needs to be rendered.
     */
    protected void nonFacesRequest(RenderRequest request, RenderResponse response, String view)
            throws PortletException
    {
        if (logger.isTraceEnabled())
            logger.trace("Non-faces request: contextPath = "
                    + request.getContextPath());
        setContentType(request, response); // do this in case nonFacesRequest is called by a subclass
        ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder
                .getFactory(FactoryFinder.APPLICATION_FACTORY);
        Application application = appFactory.getApplication();
        ViewHandler viewHandler = application.getViewHandler();
        FacesContext facesContext = facesContext(request, response);
        UIViewRoot viewRoot = viewHandler.createView(facesContext, view);
        viewRoot.setViewId(view);
        facesContext.setViewRoot(viewRoot);
        renderProtected(request, response, facesContext, false);
    }

    /**
     * Save current request attributes before rendering and restore them
     * afterward. This avoids interaction of two or more JSF based portlets
     * on one page.
     * @param request the request
     * @param response the response
     * @param facesContext the faces context
     * @param addActionAttributes if <code>true</code> add attributes
     * created by portlet in previous <code>lifecycle.execute</code>
     * @throws PortletException
     */
    private void renderProtected
        (RenderRequest request, RenderResponse response,
         FacesContext facesContext, boolean addActionAttributes)
        throws PortletException {
        if (logger.isDebugEnabled()) {
            dumpRequestInfo(request);
        }
        // Update locale (may change between requests)
        facesContext.getViewRoot().setLocale(getLocale(request));
        // for use by Ajax servlet
        request.getPortletSession()
            .setAttribute(MyFacesAjaxServlet.RENDER_NAMESPACE, response.getNamespace());
        request.getPortletSession()
            .setAttribute(NAMESPACE_PREFIX, facesContext.getExternalContext()
                          .encodeNamespace(""));
        request.getPortletSession()
            .setAttribute(LIFECYCLE_ID, getLifecycleId());
        // save attributes
        List oldAttrs = Collections.list(request.getAttributeNames());
        if (addActionAttributes) {
            // add request parameters added during performAction
            Map reqAttrs = (Map)
                request.getPortletSession().getAttribute(REQUEST_ATTRIBUTES);
            if (reqAttrs != null) {
                for (Iterator i=reqAttrs.entrySet().iterator(); i.hasNext();) {
                    Map.Entry e = (Map.Entry)i.next();
                    request.setAttribute((String)e.getKey(), e.getValue());
                }
            }
        }
        // Add carried over AUTO_SCROLL_PARAM, but only once
        if (request.getPortletSession()
                    .getAttribute(AUTO_SCROLL_PARAM) != null) {
            if (facesContext.getExternalContext()
                instanceof MyPortletExternalContextImpl) {
                ((MyPortletExternalContextImpl)
                 facesContext.getExternalContext())
                .addParameter(AUTO_SCROLL_PARAM, (String)request
                        .getPortletSession().getAttribute(AUTO_SCROLL_PARAM));
            } else {
                logger.warn
                    ("Encountered faces context with foreign external context");
            }
            request.getPortletSession().removeAttribute(AUTO_SCROLL_PARAM);
        }
        request.setAttribute(JSFUtil.LIFECYCLE, lifecycle);

        try {
            lifecycle.render(facesContext);
        } catch (RuntimeException e) {
            // restores entry view, which should work
            request.getPortletSession().removeAttribute(VIEW_ID);
            throw e;
        }

        AddResource addResource
            = AddResourceFactory.getInstance(facesContext);
        try {
            if (addResource instanceof PortletAppAddResource) {
                ((PortletAppAddResource)addResource)
                    .processAppendices(request, response, facesContext);
            }
        } catch (IOException e) {
            throw new PortletException(e);
        }

        // restore request parameters
        for (Enumeration e = request.getAttributeNames();
            e.hasMoreElements();) {
            String name = (String)e.nextElement();
            if (oldAttrs.contains(name)) {
                continue;
            }
            request.removeAttribute(name);
        }
    }

    protected String selectDefaultView(RenderRequest request,
            RenderResponse response) throws PortletException {
        if (request.getPortletMode().equals(PortletMode.EDIT)
                && defaultEditPage != null) {
            return defaultEditPage;
        }
        if (request.getPortletMode().equals(PortletMode.HELP)
                && defaultHelpPage != null) {
            return defaultHelpPage;
        }
        return defaultViewPage;
    }

    protected FacesContext facesContext
        (PortletRequest request, PortletResponse response) {
        FacesContext facesContext = facesContextFactory.getFacesContext
            (portletContext, request, response, lifecycle);
        return facesContext;
    }

    protected ReleaseableExternalContext makeExternalContext(
            PortletRequest request, PortletResponse response) {
        return (ReleaseableExternalContext) new MyPortletExternalContextImpl(
                portletContext, request, response);
    }

    protected boolean sessionTimedOut(PortletRequest request) {
        return request.getPortletSession(false) == null;
    }

    protected void setPortletRequestFlag(PortletRequest request) {
        request.getPortletSession().setAttribute(
                PortletUtil.PORTLET_REQUEST_FLAG, "true");
    }

    protected Locale getLocale (PortletRequest request) {
        // Liferay leaves a locale here
        Locale locale = (Locale)request.getPortletSession().getAttribute
            ("org.apache.struts.action.LOCALE",
             PortletSession.APPLICATION_SCOPE);
        if (locale != null) {
            return locale;
        }
        // Fallback: use request locale
        return request.getLocale();           
    }
   
    /**
     * Render a JSF view.
     */
    protected void facesRender(RenderRequest request, RenderResponse response)
            throws PortletException, java.io.IOException {
        if (logger.isTraceEnabled()) {
            logger.trace("called facesRender");
        }

        setContentType(request, response);

        String prevMode = (String)
            request.getPortletSession().getAttribute(PREV_MODE);
        if (prevMode == null
            || !prevMode.equals(request.getPortletMode().toString())) {
            request.getPortletSession().removeAttribute(VIEW_ID);
            request.getPortletSession().setAttribute
                (PREV_MODE, request.getPortletMode().toString());
        }
       
        ServletFacesContextImpl facesContext = (ServletFacesContextImpl) request
            .getPortletSession().getAttribute(CURRENT_FACES_CONTEXT);
        String viewId = (String) request.getPortletSession().getAttribute(VIEW_ID);
        if (facesContext == null || viewId == null || sessionTimedOut(request)) {
            setPortletRequestFlag(request);
            nonFacesRequest(request,  response);
            return;
        }

        setPortletRequestFlag(request);

        try {
            // TODO: not sure if this can happen.  Also double check this against spec section 2.1.3
            if (facesContext.getResponseComplete())
                return;

            facesContext.setExternalContext
                (makeExternalContext(request, response));
            renderProtected(request, response, facesContext, true);
        } catch (Throwable e) {
            handleExceptionFromLifecycle(e);
        }
    }

    protected void logException(Throwable e, String msgPrefix) {
        String msg;
        if (msgPrefix == null) {
            if (e.getMessage() == null) {
                msg = "Exception in FacesServlet";
            } else {
                msg = e.getMessage();
            }
        } else {
            if (e.getMessage() == null) {
                msg = msgPrefix;
            } else {
                msg = msgPrefix + ": " + e.getMessage();
            }
        }

        portletContext.log(msg, e);

        Throwable cause = e.getCause();
        if (cause != null && cause != e) {
            logException(cause, "Root cause");
        }

        if (e instanceof PortletException) {
            cause = ((PortletException) e).getCause();

            if (cause != null && cause != e) {
                logException(cause, "Root cause of PortletException");
            }
        }
    }

    public class ActionRequestWrapper implements ActionRequest {
        private ActionRequest delegee;
        Map reqParams;
       
        /**
         * @param delegee
         * @param params
         */
        public ActionRequestWrapper(ActionRequest delegee, Map params) {
            super();
            this.delegee = delegee;
            reqParams = params;
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getParameterNames()
         */
        public Enumeration getParameterNames() {
            return Collections.enumeration(reqParams.keySet());
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getParameter(java.lang.String)
         */
        public String getParameter(String arg0) {
            String[] values = (String[])reqParams.get(arg0);
            if (values == null) {
                return null;
            }
            return values[0];
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getParameterMap()
         */
        public Map getParameterMap() {
            return reqParams;
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getParameterValues(java.lang.String)
         */
        public String[] getParameterValues(String arg0) {
            String[] values = (String[])reqParams.get(arg0);
            return values;
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getAttribute(java.lang.String)
         */
        public Object getAttribute(String arg0) {
            return delegee.getAttribute(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getAttributeNames()
         */
        public Enumeration getAttributeNames() {
            return delegee.getAttributeNames();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getAuthType()
         */
        public String getAuthType() {
            return delegee.getAuthType();
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#getCharacterEncoding()
         */
        public String getCharacterEncoding() {
            return delegee.getCharacterEncoding();
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#getContentLength()
         */
        public int getContentLength() {
            return delegee.getContentLength();
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#getContentType()
         */
        public String getContentType() {
            return delegee.getContentType();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getContextPath()
         */
        public String getContextPath() {
            return delegee.getContextPath();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getLocale()
         */
        public Locale getLocale() {
            return delegee.getLocale();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getLocales()
         */
        public Enumeration getLocales() {
            return delegee.getLocales();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPortalContext()
         */
        public PortalContext getPortalContext() {
            return delegee.getPortalContext();
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#getPortletInputStream()
         */
        public InputStream getPortletInputStream() throws IOException {
            return delegee.getPortletInputStream();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPortletMode()
         */
        public PortletMode getPortletMode() {
            return delegee.getPortletMode();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPortletSession()
         */
        public PortletSession getPortletSession() {
            return delegee.getPortletSession();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPortletSession(boolean)
         */
        public PortletSession getPortletSession(boolean arg0) {
            return delegee.getPortletSession(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPreferences()
         */
        public PortletPreferences getPreferences() {
            return delegee.getPreferences();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getProperties(java.lang.String)
         */
        public Enumeration getProperties(String arg0) {
            return delegee.getProperties(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getProperty(java.lang.String)
         */
        public String getProperty(String arg0) {
            return delegee.getProperty(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getPropertyNames()
         */
        public Enumeration getPropertyNames() {
            return delegee.getPropertyNames();
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#getReader()
         */
        public BufferedReader getReader() throws UnsupportedEncodingException, IOException {
            return delegee.getReader();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getRemoteUser()
         */
        public String getRemoteUser() {
            return delegee.getRemoteUser();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getRequestedSessionId()
         */
        public String getRequestedSessionId() {
            return delegee.getRequestedSessionId();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getResponseContentType()
         */
        public String getResponseContentType() {
            return delegee.getResponseContentType();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getResponseContentTypes()
         */
        public Enumeration getResponseContentTypes() {
            return delegee.getResponseContentTypes();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getScheme()
         */
        public String getScheme() {
            return delegee.getScheme();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getServerName()
         */
        public String getServerName() {
            return delegee.getServerName();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getServerPort()
         */
        public int getServerPort() {
            return delegee.getServerPort();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getUserPrincipal()
         */
        public Principal getUserPrincipal() {
            return delegee.getUserPrincipal();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#getWindowState()
         */
        public WindowState getWindowState() {
            return delegee.getWindowState();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#isPortletModeAllowed(javax.portlet.PortletMode)
         */
        public boolean isPortletModeAllowed(PortletMode arg0) {
            return delegee.isPortletModeAllowed(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#isRequestedSessionIdValid()
         */
        public boolean isRequestedSessionIdValid() {
            return delegee.isRequestedSessionIdValid();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#isSecure()
         */
        public boolean isSecure() {
            return delegee.isSecure();
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#isUserInRole(java.lang.String)
         */
        public boolean isUserInRole(String arg0) {
            return delegee.isUserInRole(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#isWindowStateAllowed(javax.portlet.WindowState)
         */
        public boolean isWindowStateAllowed(WindowState arg0) {
            return delegee.isWindowStateAllowed(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#removeAttribute(java.lang.String)
         */
        public void removeAttribute(String arg0) {
            delegee.removeAttribute(arg0);
        }

        /* (non-Javadoc)
         * @see javax.portlet.PortletRequest#setAttribute(java.lang.String, java.lang.Object)
         */
        public void setAttribute(String arg0, Object arg1) {
            delegee.setAttribute(arg0, arg1);
        }

        /* (non-Javadoc)
         * @see javax.portlet.ActionRequest#setCharacterEncoding(java.lang.String)
         */
        public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
            delegee.setCharacterEncoding(arg0);
        }
    }

    /**
     * This class provides a very crude workaround for carrying the "autoscroll"
     * request parameter from the process stage to the render stage. While
     * it would be a bit more elegant to wrap the RenderRequest, this is not
     * possible as it leads to a class cast exception in pluto 1.0.1.
     *
     * @author Michael Lipp
     */
    public class MyPortletExternalContextImpl
        extends PortletExternalContextImpl {

        private Map reqParams;
        private Map reqParamsImmutable;
       
        /**
         * Create a new instance with all atributes initialized
         * to defaults or the given values.
         *
         * @param portletContext
         * @param portletRequest
         * @param portletResponse
         */
        public MyPortletExternalContextImpl
            (PortletContext portletContext,
             PortletRequest portletRequest, PortletResponse portletResponse) {
            super(portletContext, portletRequest, portletResponse);
            reqParams = new HashMap (portletRequest.getParameterMap());
            reqParamsImmutable = Collections.unmodifiableMap(reqParams);
        }

        public void addParameter (String key, String value) {
            reqParams.put(key, value);
        }
       
        public Map getRequestParameterMap() {
            return reqParamsImmutable;
        }
       
    }
   
    private void dumpRequestInfo (PortletRequest request) {
        logger.debug("Session attributes (application scope):");
        PortletSession pSession = request.getPortletSession();
        for (Enumeration e = pSession
                .getAttributeNames(PortletSession.APPLICATION_SCOPE);
            e.hasMoreElements();) {
            String attrName = (String)e.nextElement();
            logMappingProtected(attrName, pSession.getAttribute
                    (attrName, PortletSession.APPLICATION_SCOPE));
        }
        logger.debug("Session attributes (portlet scope):");
        for (Enumeration e = pSession
                .getAttributeNames(PortletSession.PORTLET_SCOPE);
            e.hasMoreElements();) {
            String attrName = (String)e.nextElement();
            logMappingProtected(attrName, pSession.getAttribute
                    (attrName, PortletSession.PORTLET_SCOPE));
        }
        logger.debug("Request attributes:");
        for (Enumeration e = request.getAttributeNames();
            e.hasMoreElements();) {
            String attrName = (String)e.nextElement();
            logMappingProtected
                (attrName, request.getAttribute(attrName));
        }
        logger.debug("Request parameters:");
        for (Iterator i = request.getParameterMap().entrySet().iterator();
            i.hasNext();) {
            Map.Entry e = (Map.Entry)i.next();
            String[] values = (String[])e.getValue();
            logMappingProtected
                (e.getKey().toString(), "[" + Misc.join(values, ", ") + "]");
        }
        logger.debug("Request properties:");
        for (Enumeration e = request.getPropertyNames(); e.hasMoreElements();) {
            String prop = (String)e.nextElement();
            logMappingProtected (prop.toString(),
                "[" + Misc.join(request.getProperties(prop), ", ") + "]");
        }
    }
   
    private void logMappingProtected (String key, Object value) {
        if (value != null && !(value instanceof String)) {
            value = value.toString();
        }
        if (key.indexOf("PASSWORD") >= 0) {
            logger.debug ("  " + key + " => ********");
        } else {
            logger.debug ("  " + key + " => " + value);
        }
    }
}
TOP

Related Classes of de.danet.an.util.jsf.MyFacesAdaptedPortlet$MyPortletExternalContextImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.