Package org.apache.beehive.netui.pageflow

Source Code of org.apache.beehive.netui.pageflow.PageFlowActionServlet

/*
* Copyright 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.
*
* $Header:$
*/
package org.apache.beehive.netui.pageflow;

import org.apache.beehive.netui.pageflow.internal.InternalConstants;
import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
import org.apache.beehive.netui.pageflow.internal.InternalUtils;
import org.apache.beehive.netui.pageflow.handler.Handlers;
import org.apache.beehive.netui.pageflow.handler.FlowControllerHandlerContext;
import org.apache.beehive.netui.pageflow.handler.ForwardRedirectHandler;
import org.apache.beehive.netui.util.internal.InternalStringBuilder;
import org.apache.beehive.netui.util.internal.ServletUtils;
import org.apache.beehive.netui.util.logging.Logger;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.action.RequestProcessor;

import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.io.IOException;
import java.util.Map;

/**
* ActionServlet that dynamically registers modules based on naming/location conventions for Struts
* configuration files that are generated by the Page Flow compiler.  These files are located in
* /WEB-INF/classes/_pageflow, and are named struts-config-<i>module-name</i>.xml.
* For auto-registration of config files in other locations, the user may specify additional
* {@link ModuleConfigLocator} classes in /WEB-INF/beehive-netui-config.xml using the
* <code>&lt;module-config-locators&gt;</code> element.
*/
public class PageFlowActionServlet extends AutoRegisterActionServlet
{
    private static final Logger _log = Logger.getInstance( PageFlowActionServlet.class );
   
    private Handlers _handlers;
   
    private static final ModuleConfigLocator[] DEFAULT_MODULE_CONFIG_LOCATORS =
            {
                new DefaultModuleConfigLocator(),
                new LegacyModuleConfigLocator()
            };
   
   
    /**
     * Get the base list of ModuleConfigLocators, to specify locations for auto-registered Struts modules.  By default,
     * this ActionServlet auto-registers Struts modules whose configuration files are located at
     * "/WEB-INF/classes/_pageflow/struts-config-<i>&lt;module&gt;</i>".  Overriding this method allows
     * alternate locations to be specified.  When an unrecognized Struts module is requested, each registered
     * ModuleConfigLocator is queried for a possible path to the configuration file for the module.  If the
     * configuration file is found, the module is auto-registered against the file.
     */
    protected ModuleConfigLocator[] getDefaultModuleConfigLocators()
    {
        return DEFAULT_MODULE_CONFIG_LOCATORS;
    }
   
    /**
     * Default ModuleConfigLocator that looks for Struts module configuration files according to the pattern
     * "/WEB-INF/classes/_pageflow/struts-config-<i>&lt;module&gt;</i>".  An instance of this class
     * is registered by default.
     *
     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
     */
    public static class DefaultModuleConfigLocator implements ModuleConfigLocator, Serializable
    {
        public String getModuleConfigPath( String moduleName )
        {
            InternalStringBuilder moduleConfPath = new InternalStringBuilder( getGenDir() );
            moduleConfPath.append( '/' ).append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_PREFIX );
           
            if ( moduleName.length() > 1 )
            {
                moduleConfPath.append( moduleName.replace( '/', '-' ) );
            }
           
            moduleConfPath.append( PageFlowConstants.PAGEFLOW_MODULE_CONFIG_EXTENSION );
            return moduleConfPath.toString();
        }
       
        protected String getGenDir()
        {
            return PageFlowConstants.PAGEFLOW_MODULE_CONFIG_GEN_DIR;
        }
    }
   
    /**
     * ModuleConfigLocator that looks for legacy Struts module configuration files according to the pattern
     * "/WEB-INF/struts-config-<i>&lt;module&gt;</i>".  An instance of this class is registered by default.
     *
     * @see PageFlowActionServlet#getDefaultModuleConfigLocators
     */
    protected static class LegacyModuleConfigLocator extends DefaultModuleConfigLocator
    {
        protected String getGenDir()
        {
            return InternalConstants.WEBINF_DIR;
        }
    }

    public void init()
            throws ServletException
    {
        //
        // Ensure that PageFlowContextListener gets to do its initializations, even if it's not registered in web.xml.
        //
        ServletContext servletContext = getServletContext();
       
        if ( ! PageFlowContextListener.isInit( servletContext ) )
        {
            PageFlowContextListener.performInitializations( servletContext );
        }
       
        _handlers = Handlers.get( servletContext );
       
        super.init();
    }

    protected void process( HttpServletRequest request, HttpServletResponse response )
            throws IOException, ServletException
    {
        // If this is a direct request for a shared flow (.jpfs) or a Faces backing bean (.jsfb), return a 404 status.
        // These are not web-addressable.
        String servletPath = InternalUtils.getDecodedServletPath( request );
        if ( servletPath.endsWith( InternalConstants.SHARED_FLOW_EXTENSION ) ||
             servletPath.endsWith( InternalConstants.FACES_BACKING_EXTENSION ) )
        {
            if ( _log.isDebugEnabled() )
            {
                _log.debug( "Attempt to hit restricted URI " + servletPath + "; 404 error returned." );
            }
           
            response.sendError( HttpServletResponse.SC_NOT_FOUND );
            return;
        }
       
        // First, reinitialize the page flow classloader, for reloading when recompile occurs in dev mode.
        FlowControllerHandlerContext handlerContext = new FlowControllerHandlerContext( request, response, null );
        _handlers.getReloadableClassHandler().reloadClasses( handlerContext );
       
        super.process( request, response );
    }

    /**
     * Get the webapp-relative path to the Struts module configration file for a given module path.  By default,
     * this is "/WEB-INF/classes/_pageflow/struts-config-<i>&lt;module&gt;</i>", but alternate
     * locations can be specified by adding {@link ModuleConfigLocator}s. 
     *
     * @param modulePath the Struts module path.
     * @return a String that is the path to the Struts configuration file, relative to the web application root.
     * @see #getDefaultModuleConfigLocators
     */
    public String getModuleConfPath( String modulePath )
    {
        return super.getModuleConfPath( modulePath );
    }
   
    /**
     * Struts keeps track of the action servlet URL pattern (e.g., *.do) so it can construct action
     * URIs.  We want to prevent it from noticing *.jpf so it doesn't use that to construct the URIs.
     *
     * @exclude
     */
    public void addServletMapping( String servletName, String urlPattern )
    {
        if ( ! urlPattern.endsWith( PageFlowConstants.JPF_EXTENSION ) )
        {
            super.addServletMapping( servletName, urlPattern );
        }
    }
   
    /**
     * Tell whether the given module can handle the given path.  If this is the root module (path=="") and it's a
     * Page Flow module, then it shouldn't try to handle any path that has a slash in it -- it only handles local
     * actions.
     */
    protected boolean moduleCanHandlePath( ModuleConfig moduleConfig, RequestProcessor rp, String servletPath )
    {
        if ( moduleConfig.getPrefix().equals( "" ) && servletPath.lastIndexOf( '/' ) > 0
             && rp instanceof PageFlowRequestProcessor )
        {
            return false;
        }
       
        return true;
    }
   
    /**
     * Last chance to handle an unhandled action URI.
     * @return <code>true</code> if this method handled it (by forwarding somewhere or writing to the response).
     */
    protected boolean processUnhandledAction( HttpServletRequest request, HttpServletResponse response, String uri )
        throws IOException, ServletException
    {
        //
        // First check to see if we're already in a forwarded fallback request.  If so, just bail.
        //
        PageFlowRequestWrapper rw = PageFlowRequestWrapper.get( request );
        if ( rw.getOriginalServletPath() != null ) return false;      
       
        SharedFlowController sharedFlowToTry = null;
        String uriBaseName = ServletUtils.getBaseName( uri );
        int firstDot = uriBaseName.indexOf( '.' );
        int lastDot = uriBaseName.lastIndexOf( '.' );
       
        if ( firstDot != -1 && firstDot != lastDot )
        {
            String sharedFlowName = uriBaseName.substring( 0, firstDot );
           
            try
            {
                RequestContext rc = new RequestContext( request, response );
                Map defaultSharedFlows = FlowControllerFactory.get( getServletContext() ).getDefaultSharedFlows( rc );
               
                if ( defaultSharedFlows != null )
                {
                    sharedFlowToTry = ( SharedFlowController ) defaultSharedFlows.get( sharedFlowName );
                    uriBaseName = uriBaseName.substring( firstDot + 1 );
                }
            }
            catch ( ClassNotFoundException e )
            {
                throw new ServletException( e );
            }
            catch ( InstantiationException e )
            {
                throw new ServletException( e );
            }
            catch ( IllegalAccessException e )
            {
                throw new ServletException( e );
            }
        }
        else
        {
            sharedFlowToTry = FlowControllerFactory.getGlobalApp( request, response, getServletContext() );
        }
       
        //
        // If we couldn't find an appropriate module, try raising the action on the (deprecated) Global.app.
        //
       
        if ( sharedFlowToTry != null )
        {
            InternalStringBuilder sfActionURI = new InternalStringBuilder( sharedFlowToTry.getModulePath() );
            sfActionURI.append( '/' );
            sfActionURI.append( uriBaseName );
            rw.setOriginalServletPath( uri );
            ForwardRedirectHandler frh = _handlers.getForwardRedirectHandler();
            FlowControllerHandlerContext context = new FlowControllerHandlerContext( request, response, null );
            frh.forward( context, sfActionURI.toString() );
            return true;
        }
       
        return false;
    }
}
TOP

Related Classes of org.apache.beehive.netui.pageflow.PageFlowActionServlet

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.