Package org.apache.jetspeed.pipeline.valve.impl

Source Code of org.apache.jetspeed.pipeline.valve.impl.ActionValveImpl

/*
* 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.jetspeed.pipeline.valve.impl;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import javax.portlet.PortletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jetspeed.PortalReservedParameters;
import org.apache.jetspeed.cache.ContentCacheKey;
import org.apache.jetspeed.cache.JetspeedContentCache;
import org.apache.jetspeed.container.window.PortletWindowAccessor;
import org.apache.jetspeed.exception.JetspeedException;
import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
import org.apache.jetspeed.om.page.ContentFragment;
import org.apache.jetspeed.om.page.ContentFragmentImpl;
import org.apache.jetspeed.om.page.ContentPage;
import org.apache.jetspeed.om.page.Fragment;
import org.apache.jetspeed.om.page.Page;
import org.apache.jetspeed.pipeline.PipelineException;
import org.apache.jetspeed.pipeline.valve.AbstractValve;
import org.apache.jetspeed.pipeline.valve.ActionValve;
import org.apache.jetspeed.pipeline.valve.ValveContext;
import org.apache.jetspeed.request.RequestContext;
import org.apache.pluto.PortletContainer;
import org.apache.pluto.PortletContainerException;
import org.apache.pluto.om.entity.PortletEntity;
import org.apache.pluto.om.window.PortletWindow;

/**
* <p>
* ActionValveImpl
* </p>
*
* Default implementation of the ActionValve interface.  Expects to be
* called after the ContainerValve has set up the appropriate action window
* within the request context.  This should come before ANY rendering takes
* place.
*
* @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
* @version $Id: ActionValveImpl.java 550655 2007-06-26 01:41:35Z taylor $
*
*/
public class ActionValveImpl extends AbstractValve implements ActionValve
{

    private static final Log log = LogFactory.getLog(ActionValveImpl.class);
    private PortletContainer container;
    private PortletWindowAccessor windowAccessor;
    private boolean patchResponseCommitted = false;
    private JetspeedContentCache portletContentCache;

    public ActionValveImpl(PortletContainer container, PortletWindowAccessor windowAccessor, JetspeedContentCache portletContentCache)
    {
        this.container = container;
        this.windowAccessor = windowAccessor;
        this.portletContentCache = portletContentCache;
    }
   
    public ActionValveImpl(PortletContainer container, PortletWindowAccessor windowAccessor, JetspeedContentCache portletContentCache, boolean patchResponseCommitted)
    {
        this.container = container;
        this.windowAccessor = windowAccessor;
        this.portletContentCache = portletContentCache;       
        this.patchResponseCommitted = patchResponseCommitted;
    }

    /**
     * @see org.apache.jetspeed.pipeline.valve.Valve#invoke(org.apache.jetspeed.request.RequestContext, org.apache.jetspeed.pipeline.valve.ValveContext)
     */
    public void invoke(RequestContext request, ValveContext context) throws PipelineException
    {    
        boolean responseCommitted = false;
        try
        {           
            PortletWindow actionWindow = request.getActionWindow();
            if (actionWindow != null)
            {
                // If portlet entity is null, try to refresh the actionWindow.
                // Under some clustered environments, a cached portlet window could have null entity.
                if (null == actionWindow.getPortletEntity())
                {
                    try
                    {
                        Fragment fragment = request.getPage().getFragmentById(actionWindow.getId().toString());
                        ContentFragment contentFragment = new ContentFragmentImpl(fragment, new HashMap());
                        actionWindow = this.windowAccessor.getPortletWindow(contentFragment);
                    }
                    catch (Exception e)
                    {
                        log.error("Failed to refresh action window.", e);
                    }
                }

                initWindow(actionWindow, request);
                HttpServletResponse response = request.getResponseForWindow(actionWindow);
                HttpServletRequest requestForWindow = request.getRequestForWindow(actionWindow);
                requestForWindow.setAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE, request);
               
                //PortletMessagingImpl msg = new PortletMessagingImpl(windowAccessor);
               
                requestForWindow.setAttribute("JETSPEED_ACTION", request);
                container.processPortletAction(
                    actionWindow,
                    requestForWindow,
                    response);
                // The container redirects the client after PortletAction processing
                // so there is no need to continue the pipeline
               
                //msg.processActionMessage("todo", request);
               
                // clear the cache for all portlets on the current page
                clearPortletCacheForPage(request, actionWindow);
               
                if (patchResponseCommitted)
                {
                    responseCommitted = true;
                }
                else
                {
                    responseCommitted = response.isCommitted();
                }
                request.setAttribute(PortalReservedParameters.PIPELINE, null); // clear the pipeline
            }
        }
        catch (PortletContainerException e)
        {
            log.fatal("Unable to retrieve portlet container!", e);
            throw new PipelineException("Unable to retrieve portlet container!", e);
        }
        catch (PortletException e)
        {
            log.warn("Unexpected PortletException in ActionValveImpl", e);
            //  throw new PipelineException("Unexpected PortletException in ActionValveImpl", e);

        }
        catch (IOException e)
        {
            log.error("Unexpected IOException in ActionValveImpl", e);
            // throw new PipelineException("Unexpected IOException in ActionValveImpl", e);
        }
        catch (IllegalStateException e)
        {
            log.error("Illegal State Exception. Response was written to in Action Phase", e);
            responseCommitted = true;
        }
        catch (Throwable t)
        {
            log.error("Unknown exception processing Action", t);
        }
        finally
        {
            // Check if an action was processed and if its response has been committed
            // (Pluto will redirect the client after PorletAction processing)
            if ( responseCommitted )
            {
                log.info("Action processed and response committed (pipeline processing stopped)");
            }
            else
            {
                // Pass control to the next Valve in the Pipeline
                context.invokeNext(request);
            }
        }

    }

    protected void clearPortletCacheForPage(RequestContext request, PortletWindow actionWindow)
    throws JetspeedException
    {
        ContentPage page = request.getPage();
        if (null == page)
        {
            throw new JetspeedException("Failed to find PSML Pin ContentPageAggregator.build");
        }
        ContentFragment root = page.getRootContentFragment();
        if (root == null)
        {
            throw new JetspeedException("No root ContentFragment found in ContentPage");
        }
        if (!isNonStandardAction(actionWindow))
        {
            notifyFragments(root, request, page);
        }
        else
        {
            ContentFragment fragment = page.getContentFragmentById(actionWindow.getId().toString());
            clearTargetCache(fragment, request);
        }
    }
   
    /**
     * Actions can be marked as non-standard if they don't participate in
     * JSR-168 standard action behavior. By default, actions are supposed
     * to clear the cache of all other portlets on the page.
     * By setting this parameter, we can ignore the standard behavior
     * and not clear the cache on actions. This is useful for portlets
     * which never participate with other portlets.
     *
     */   
    protected boolean isNonStandardAction(PortletWindow actionWindow)
    {
        PortletEntity entity = actionWindow.getPortletEntity();
        if (entity != null)
        {
            PortletDefinitionComposite portletDefinition = (PortletDefinitionComposite)entity.getPortletDefinition();
            if (portletDefinition != null)
            {
                Collection actionList = null;
       
                if (portletDefinition != null)
                {
                    actionList = portletDefinition.getMetadata().getFields(PortalReservedParameters.PORTLET_EXTENDED_DESCRIPTOR_NON_STANDARD_ACTION);
                }
                if (actionList != null)
                {
                    if (!actionList.isEmpty())
                        return true;
                }
            }
        }
        return false;
    }
  
    protected void notifyFragments(ContentFragment f, RequestContext context, ContentPage page)
    {
        if (f.getContentFragments() != null && f.getContentFragments().size() > 0)
        {
            Iterator children = f.getContentFragments().iterator();
            while (children.hasNext())
            {
                ContentFragment child = (ContentFragment) children.next();
                if (!"hidden".equals(f.getState()))
                {
                    notifyFragments(child, context, page);
                }
            }
        }   
        ContentCacheKey cacheKey = portletContentCache.createCacheKey(context, f.getId());
        if (portletContentCache.isKeyInCache(cacheKey))
        {
            portletContentCache.remove(cacheKey);
            portletContentCache.invalidate(context);
        }
    }

    protected void clearTargetCache(ContentFragment f, RequestContext context)
    {
        ContentCacheKey cacheKey = portletContentCache.createCacheKey(context, f.getId());       
        if (portletContentCache.isKeyInCache(cacheKey))
        {
            portletContentCache.remove(cacheKey);
            portletContentCache.invalidate(context);           
        }
    }
   
    /**
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        // TODO Auto-generated method stub
        return "ActionValveImpl";
    }
   
    /**
     * Makes sure that this PortletWindow's PortletEntity is set to have the
     * current requests fragment.
     * @param window
     * @param request
     */
    protected void initWindow(PortletWindow window, RequestContext request)
    {
        Page page = request.getPage();
        Fragment fragment = page.getFragmentById(window.getId().toString());
        ((MutablePortletEntity)window.getPortletEntity()).setFragment(fragment);
    }

}
TOP

Related Classes of org.apache.jetspeed.pipeline.valve.impl.ActionValveImpl

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.