KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > pageflow > internal > InternalUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.pageflow.internal;
19
20 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
21
22 import org.apache.beehive.netui.pageflow.*;
23 import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping;
24 import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig;
25 import org.apache.beehive.netui.pageflow.config.PageFlowActionFormBean;
26 import org.apache.beehive.netui.pageflow.handler.Handlers;
27 import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
28 import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
29 import org.apache.beehive.netui.util.Bundle;
30 import org.apache.beehive.netui.util.internal.ServletUtils;
31 import org.apache.beehive.netui.util.config.ConfigUtil;
32 import org.apache.beehive.netui.util.config.bean.PageflowConfig;
33 import org.apache.beehive.netui.util.logging.Logger;
34 import org.apache.struts.Globals;
35 import org.apache.struts.util.MessageResources;
36 import org.apache.struts.action.*;
37 import org.apache.struts.config.ActionConfig;
38 import org.apache.struts.config.ControllerConfig;
39 import org.apache.struts.config.FormBeanConfig;
40 import org.apache.struts.config.ModuleConfig;
41 import org.apache.struts.config.MessageResourcesConfig;
42 import org.apache.struts.upload.MultipartRequestWrapper;
43
44 import javax.servlet.ServletContext JavaDoc;
45 import javax.servlet.ServletException JavaDoc;
46 import javax.servlet.ServletRequest JavaDoc;
47 import javax.servlet.ServletResponse JavaDoc;
48 import javax.servlet.jsp.JspContext JavaDoc;
49 import javax.servlet.jsp.PageContext JavaDoc;
50 import javax.servlet.http.HttpServletRequest JavaDoc;
51 import javax.servlet.http.HttpServletResponse JavaDoc;
52 import javax.servlet.http.HttpSession JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.lang.reflect.Method JavaDoc;
55 import java.util.HashMap JavaDoc;
56 import java.util.Iterator JavaDoc;
57 import java.util.LinkedHashMap JavaDoc;
58 import java.util.Map JavaDoc;
59 import java.util.Locale JavaDoc;
60
61
62
63 public class InternalUtils
64         implements PageFlowConstants, InternalConstants
65 {
66     private static final Logger _log = Logger.getInstance( InternalUtils.class );
67     
68     private static final String JavaDoc BEA_XMLOBJECT_CLASSNAME = "com.bea.xml.XmlObject";
69     private static final String JavaDoc APACHE_XMLOBJECT_CLASSNAME = "org.apache.xmlbeans.XmlObject";
70     private static final Class JavaDoc BEA_XMLOBJECT_CLASS = loadClassNonFatal( BEA_XMLOBJECT_CLASSNAME );
71     private static final Class JavaDoc APACHE_XMLOBJECT_CLASS = loadClassNonFatal( APACHE_XMLOBJECT_CLASSNAME );
72     private static final String JavaDoc LONGLIVED_PAGEFLOWS_ATTR_PREFIX = ATTR_PREFIX + "longLivedPageFlow:";
73     private static final String JavaDoc ACTIONOUTPUT_MAP_ATTR = ATTR_PREFIX + "actionOutputs";
74     private static final String JavaDoc BINDING_UPDATE_ERRORS_ATTR = ATTR_PREFIX + "bindingUpdateErrors";
75     private static final String JavaDoc SHARED_FLOW_CLASSNAME_ATTR = ATTR_PREFIX + "sharedFlowClass";
76     private static final String JavaDoc SERVLET_CONTEXT_ATTR = ATTR_PREFIX + "servletContext";
77     private static final String JavaDoc AVOID_DIRECT_RESPONSE_OUTPUT_ATTR = ATTR_PREFIX + "_avoidDirectResponseOutput";
78     private static final String JavaDoc FORWARDED_FORMBEAN_ATTR = ATTR_PREFIX + "forwardedForm";
79     private static final String JavaDoc FORWARDING_MODULE_ATTR = ATTR_PREFIX + "forwardingModule";
80     private static final String JavaDoc IGNORE_INCLUDE_SERVLET_PATH_ATTR = ATTR_PREFIX + "ignoreIncludeServletPath";
81     
82     
83     /**
84      * If not in production mode, write an error to the response; otherwise, set a response error code.
85      */

86     public static void sendDevTimeError( String JavaDoc messageKey, Throwable JavaDoc cause, int productionTimeErrorCode,
87                                          ServletRequest JavaDoc request, ServletResponse JavaDoc response,
88                                          ServletContext JavaDoc servletContext, Object JavaDoc[] messageArgs )
89             throws IOException JavaDoc
90     {
91         sendDevTimeError( messageKey, messageArgs, cause, productionTimeErrorCode, request, response, servletContext );
92     }
93     
94     /**
95      * If not in production mode, write an error to the response; otherwise, set a response error code.
96      * @deprecated Use {@link #sendDevTimeError(String, Throwable, int, ServletRequest, ServletResponse, ServletContext, Object[])}
97      */

98     public static void sendDevTimeError( String JavaDoc messageKey, Object JavaDoc[] messageArgs, Throwable JavaDoc cause,
99                                          int productionTimeErrorCode, ServletRequest JavaDoc request,
100                                          ServletResponse JavaDoc response, ServletContext JavaDoc servletContext )
101             throws IOException JavaDoc
102     {
103         boolean prodMode = AdapterManager.getServletContainerAdapter( servletContext ).isInProductionMode();
104         boolean avoidDirectResponseOutput = avoidDirectResponseOutput( request );
105         
106         if ( prodMode && ! avoidDirectResponseOutput && response instanceof HttpServletResponse JavaDoc )
107         {
108             if ( _log.isErrorEnabled() )
109             {
110                 _log.error( "Error (message key " + messageKey + ") occurred. Response error was set to "
111                             + productionTimeErrorCode, cause );
112             }
113             
114             ( ( HttpServletResponse JavaDoc ) response ).sendError( productionTimeErrorCode );
115         }
116         else
117         {
118             sendError( messageKey, messageArgs, request, response, cause, prodMode || avoidDirectResponseOutput );
119         }
120     }
121     
122     /**
123      * Write an error to the response.
124      */

125     public static void sendError( String JavaDoc messageKey, Throwable JavaDoc cause, ServletRequest JavaDoc request,
126                                   HttpServletResponse JavaDoc response, Object JavaDoc[] messageArgs )
127             throws IOException JavaDoc
128     {
129         // TODO: the following null check will be unnecessary once the deprecated
130
// FlowController.sendError(String, HttpServletResponse) is removed.
131
boolean avoidDirectResponseOutput = request != null ? avoidDirectResponseOutput( request ) : false;
132         sendError( messageKey, messageArgs, request, response, cause, avoidDirectResponseOutput );
133     }
134     
135     /**
136      * Write an error to the response.
137      */

138     public static void sendError( String JavaDoc messageKey, Object JavaDoc[] messageArgs, ServletRequest JavaDoc request,
139                                   ServletResponse JavaDoc response, Throwable JavaDoc cause, boolean avoidDirectResponseOutput )
140             throws IOException JavaDoc
141     {
142         assert messageArgs.length == 0 || ! ( messageArgs[0] instanceof Object JavaDoc[] )
143                 : "Object[] passed to sendError; this is probably a mistaken use of varargs";
144         
145         // request may be null because of deprecated FlowController.sendError().
146
if ( request != null && avoidDirectResponseOutput )
147         {
148             String JavaDoc baseMessage = Bundle.getString( messageKey + "_Message", messageArgs );
149             throw new ResponseOutputException( baseMessage, cause );
150         }
151         
152         String JavaDoc html = Bundle.getString( messageKey + "_Page", messageArgs );
153         response.setContentType( "text/html;charset=UTF-8" );
154         response.getWriter().println( html );
155         ServletUtils.preventCache( response );
156     }
157     
158     /**
159      * We unwrap two special form types: XmlBeanActionForm and AnyBeanActionForm.
160      */

161     // TODO: make this pluggable
162
public static Object JavaDoc unwrapFormBean( ActionForm form )
163     {
164         if ( form == null ) return null;
165         
166         if ( form instanceof AnyBeanActionForm )
167         {
168             return ( ( AnyBeanActionForm ) form ).getBean();
169         }
170         
171         return form;
172     }
173     
174     public static ActionForm wrapFormBean( Object JavaDoc formBean )
175     {
176         if ( formBean == null ) return null;
177         
178         //
179
// Notice that we even wrap form beans that extend ActionForm but don't extend FormData. This is because
180
// FormData has special logic to make validation annotations work correctly.
181
//
182
if ( formBean instanceof FormData )
183         {
184             return ( ActionForm ) formBean;
185         }
186         else
187         {
188             Class JavaDoc formClass = formBean.getClass();
189             
190             if ( BEA_XMLOBJECT_CLASS != null && BEA_XMLOBJECT_CLASS.isAssignableFrom( formClass ) )
191             {
192                 return new XmlBeanActionForm( formBean );
193             }
194             else if ( APACHE_XMLOBJECT_CLASS != null && APACHE_XMLOBJECT_CLASS.isAssignableFrom( formClass ) )
195             {
196                 return new XmlBeanActionForm( formBean );
197             }
198             
199             return new AnyBeanActionForm( formBean );
200         }
201     }
202     
203     private static Class JavaDoc loadClassNonFatal( String JavaDoc className )
204     {
205         try
206         {
207             return Class.forName( className );
208         }
209         catch ( ClassNotFoundException JavaDoc e )
210         {
211             // Not fatal -- we don't require this to be there. Only if the user wants to use it.
212

213             if ( _log.isDebugEnabled() )
214             {
215                 _log.debug( "Could not load class " + className );
216             }
217         }
218         
219         return null;
220     }
221     
222     /**
223      * Get a Method in a Class.
224      *
225      * @param parentClass the Class in which to find the Method.
226      * @param methodName the name of the Method.
227      * @param signature the argument types for the Method.
228      * @return the Method with the given name and signature, or <code>null</code> if the method does not exist.
229      */

230     public static Method JavaDoc lookupMethod( Class JavaDoc parentClass, String JavaDoc methodName, Class JavaDoc[] signature )
231     {
232         try
233         {
234             return parentClass.getDeclaredMethod( methodName, signature );
235         }
236         catch ( NoSuchMethodException JavaDoc e )
237         {
238             Class JavaDoc superClass = parentClass.getSuperclass();
239             return superClass != null ? lookupMethod( superClass, methodName, signature ) : null;
240         }
241     }
242
243     public static String JavaDoc getFlowControllerClassName( String JavaDoc modulePath, ServletRequest JavaDoc request, ServletContext JavaDoc context )
244     {
245         //
246
// We're going to look in the struts config to get the PageFlowController class.
247
//
248
ModuleConfig mc = ensureModuleConfig( modulePath, request, context );
249         return mc != null ? getFlowControllerClassName( mc ) : null;
250     }
251     
252     public static String JavaDoc getFlowControllerClassName( ModuleConfig mc )
253     {
254         ControllerConfig cc = mc.getControllerConfig();
255         return cc instanceof PageFlowControllerConfig ? ( ( PageFlowControllerConfig ) cc ).getControllerClass() : null;
256     }
257     
258     /**
259      * Tell whether the given module is a long-lived page flow.
260      */

261     public static boolean isLongLived( ModuleConfig moduleConfig )
262     {
263         ControllerConfig cc = moduleConfig.getControllerConfig();
264         
265         if ( cc instanceof PageFlowControllerConfig )
266         {
267             return ( ( PageFlowControllerConfig ) cc ).isLongLivedPageFlow();
268         }
269         else
270         {
271             return false;
272         }
273     }
274     
275     /**
276      * Tell whether the given module is a nested page flow.
277      */

278     public static boolean isNestable( ModuleConfig moduleConfig )
279     {
280         ControllerConfig cc = moduleConfig.getControllerConfig();
281         return cc instanceof PageFlowControllerConfig && ( ( PageFlowControllerConfig ) cc ).isNestedPageFlow();
282     }
283      
284     public static String JavaDoc getLongLivedFlowAttr( String JavaDoc modulePath )
285     {
286         return LONGLIVED_PAGEFLOWS_ATTR_PREFIX + modulePath;
287     }
288     
289     public static void setCurrentPageFlow( PageFlowController jpf, HttpServletRequest JavaDoc request )
290     {
291         setCurrentActionResolver( jpf, request );
292     }
293     
294     public static void removeCurrentPageFlow( HttpServletRequest JavaDoc request )
295     {
296         HttpServletRequest JavaDoc unwrappedRequest = PageFlowUtils.unwrapMultipart( request );
297         ScopedServletUtils.removeScopedSessionAttr( CURRENT_JPF_ATTR, unwrappedRequest );
298         ScopedServletUtils.removeScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
299     }
300     
301     public static String JavaDoc getDecodedURI( HttpServletRequest JavaDoc request )
302     {
303         return request.getContextPath() + getDecodedServletPath( request );
304     }
305     
306     public static String JavaDoc getDecodedServletPath( HttpServletRequest JavaDoc request )
307     {
308         if ( ignoreIncludeServletPath( request ) ) return request.getServletPath();
309         
310         String JavaDoc servletIncludePath = ( String JavaDoc ) request.getAttribute( RequestProcessor.INCLUDE_SERVLET_PATH );
311         return servletIncludePath != null ? servletIncludePath : request.getServletPath();
312     }
313         
314     public static void addActionOutputs( Map JavaDoc toAdd, ServletRequest JavaDoc request, boolean overwrite )
315     {
316         if ( toAdd != null )
317         {
318             Map JavaDoc map = getActionOutputMap( request, true );
319
320             for ( Iterator JavaDoc i = toAdd.entrySet().iterator(); i.hasNext(); )
321             {
322                 Map.Entry JavaDoc entry = ( Map.Entry JavaDoc ) i.next();
323                 String JavaDoc name = ( String JavaDoc ) entry.getKey();
324                 boolean alreadyExists = map.containsKey( name );
325                 
326                 if ( overwrite || ! alreadyExists )
327                 {
328                     if ( alreadyExists )
329                     {
330                         if ( _log.isWarnEnabled() )
331                         {
332                             _log.warn( "Overwriting action output \"" + name + "\"." );
333                         }
334                     }
335                     
336                     map.put( name, entry.getValue() );
337                 }
338             }
339         }
340     }
341     
342     public static void addActionError( String JavaDoc propertyName, ActionMessage error, ServletRequest JavaDoc request )
343     {
344         ActionErrors errors = ( ActionErrors ) request.getAttribute( Globals.ERROR_KEY );
345         if ( errors == null ) request.setAttribute( Globals.ERROR_KEY, errors = new ActionErrors() );
346         errors.add( propertyName, error );
347     }
348     
349     public static Object JavaDoc newReloadableInstance( String JavaDoc className, ServletContext JavaDoc servletContext )
350         throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
351     {
352         return getReloadableClass( className, servletContext ).newInstance();
353     }
354     
355     public static Class JavaDoc getReloadableClass( String JavaDoc className, ServletContext JavaDoc servletContext )
356         throws ClassNotFoundException JavaDoc
357     {
358         ReloadableClassHandler handler = Handlers.get( servletContext ).getReloadableClassHandler();
359         return handler.loadClass( className );
360     }
361     
362     public static Map JavaDoc getActionOutputMap( ServletRequest JavaDoc request, boolean createIfNotExist )
363     {
364         Map JavaDoc map = ( Map JavaDoc ) request.getAttribute( ACTIONOUTPUT_MAP_ATTR );
365
366         if ( map == null && createIfNotExist )
367         {
368             map = new HashMap JavaDoc();
369             request.setAttribute( ACTIONOUTPUT_MAP_ATTR, map );
370         }
371
372         return map;
373     }
374     
375     public static Map JavaDoc getPageInputMap( ServletRequest JavaDoc request )
376     {
377         Map JavaDoc actionOutputsFromPageFlow = getActionOutputMap( request, false );
378         if ( actionOutputsFromPageFlow != null ) return actionOutputsFromPageFlow;
379         FacesBackingBean fbb = getFacesBackingBean( request );
380         return fbb != null ? fbb.getPageInputMap() : null;
381     }
382     
383     /**
384      * Get the Struts ModuleConfig for the given module path.
385      */

386     public static ModuleConfig getModuleConfig( String JavaDoc modulePath, ServletContext JavaDoc context )
387     {
388         return ( ModuleConfig ) context.getAttribute( Globals.MODULE_KEY + modulePath );
389     }
390     
391     /**
392      * Get the Struts ModuleConfig for the given module path. If there is none registered,
393      * and if it is possible to register one automatically, do so.
394      */

395     public static ModuleConfig ensureModuleConfig( String JavaDoc modulePath, ServletRequest JavaDoc request, ServletContext JavaDoc context )
396     {
397         try
398         {
399             ModuleConfig ret = getModuleConfig( modulePath, context );
400             
401             if ( ret != null )
402             {
403                 return ret;
404             }
405             else
406             {
407                 ActionServlet as = getActionServlet( context );
408                 
409                 if ( as instanceof AutoRegisterActionServlet )
410                 {
411                     return ( ( AutoRegisterActionServlet ) as ).ensureModuleRegistered( modulePath, request );
412                 }
413             }
414         }
415         catch ( IOException JavaDoc e )
416         {
417             _log.error( "Error while registering Struts module " + modulePath, e );
418         }
419         catch ( ServletException JavaDoc e )
420         {
421             _log.error( "Error while registering Struts module " + modulePath, e );
422         }
423         
424         return null;
425     }
426    
427     /**
428      * Get the current ActionServlet.
429      *
430      * @param context the current ServletContext
431      * @return the ActionServlet that is stored as an attribute in the ServletContext
432      */

433     public static ActionServlet getActionServlet( ServletContext JavaDoc context )
434     {
435         if ( context == null ) return null;
436         return ( ActionServlet ) context.getAttribute( Globals.ACTION_SERVLET_KEY );
437     }
438     
439     /**
440      * Add a BindingUpdateError to the request.
441      *
442      * @param request the current ServletRequest.
443      * @param expression the expression associated with this error.
444      * @param message the error message.
445      * @param cause the Throwable that caused the error.
446      */

447     public static void addBindingUpdateError( ServletRequest JavaDoc request, String JavaDoc expression, String JavaDoc message, Throwable JavaDoc cause )
448     {
449         Map JavaDoc errors = ( Map JavaDoc ) request.getAttribute( BINDING_UPDATE_ERRORS_ATTR );
450         
451         if ( errors == null )
452         {
453             errors = new LinkedHashMap JavaDoc();
454             request.setAttribute( BINDING_UPDATE_ERRORS_ATTR, errors );
455         }
456         
457         errors.put( expression, new BindingUpdateError( expression, message, cause ) );
458     }
459     
460     /**
461      * Get a map of BindingUpdateErrors stored in the request.
462      *
463      * @return a Map of expression (String) -> BindingUpdateError.
464      */

465     public static Map JavaDoc getBindingUpdateErrors( ServletRequest JavaDoc request )
466     {
467         return ( Map JavaDoc ) request.getAttribute( BINDING_UPDATE_ERRORS_ATTR );
468     }
469     
470     public static void setCurrentModule( ModuleConfig mc, ServletRequest JavaDoc request )
471     {
472         request.setAttribute( Globals.MODULE_KEY, mc );
473     }
474     
475     public static ActionForm createActionForm( ActionMapping mapping, ModuleConfig moduleConfig,
476                                                ActionServlet actionServlet, ServletContext JavaDoc servletContext )
477     {
478         String JavaDoc formName = mapping.getName();
479         if ( formName == null ) return null;
480         FormBeanConfig config = moduleConfig.findFormBeanConfig( formName );
481         if ( config == null ) return null;
482         
483         try
484         {
485             ActionForm bean;
486             
487             if ( config.getDynamic() )
488             {
489                 if ( _log.isDebugEnabled() )
490                 {
491                     _log.debug( "Creating new DynaActionForm instance of type " + config.getType() );
492                 }
493                 
494                 DynaActionFormClass dynaClass = DynaActionFormClass.createDynaActionFormClass( config );
495                 bean = ( ActionForm ) dynaClass.newInstance();
496                 ( ( DynaActionForm ) bean ).initialize( mapping );
497             }
498             else
499             {
500                 if ( _log.isDebugEnabled() )
501                 {
502                     _log.debug( "Creating new ActionForm instance of type " + config.getType() );
503                 }
504                 
505                 bean = ( ActionForm ) newReloadableInstance( config.getType(), servletContext );
506             }
507             
508             bean.setServlet( actionServlet );
509             return bean;
510         }
511         catch ( Exception JavaDoc e )
512         {
513             if ( _log.isErrorEnabled() )
514             {
515                 _log.error( "Error creating action form of type " + config.getType(), e );
516             }
517             
518             return null;
519         }
520     }
521     
522     /**
523      * Set the given form in either the request or session, as appropriate, so Struts/NetUI
524      * tags will have access to it.
525      */

526     public static void setFormInScope( String JavaDoc formName, ActionForm form, ActionMapping mapping,
527                                        HttpServletRequest JavaDoc request, boolean overwrite )
528     {
529         if ( formName != null && form != null )
530         {
531             if ( isSessionScope( mapping ) )
532             {
533                 HttpSession JavaDoc session = request.getSession();
534                 
535                 if ( overwrite || session.getAttribute( formName ) == null )
536                 {
537                     session.setAttribute( formName, form );
538                 }
539             }
540             else
541             {
542                 if ( overwrite || request.getAttribute( formName ) == null )
543                 {
544                     request.setAttribute( formName, form );
545                 }
546             }
547         }
548     }
549     
550     public static boolean isSessionScope( ActionMapping mapping )
551     {
552         return ( mapping.getScope() == null || mapping.getScope().equals( "session" ) );
553     }
554     
555     public static ActionForm getFormBean( ActionMapping mapping, ServletRequest JavaDoc request )
556     {
557         String JavaDoc formBeanName = mapping.getAttribute();
558         
559         if ( formBeanName != null )
560         {
561             if ( isSessionScope( mapping ) )
562             {
563                 HttpSession JavaDoc session = getHttpSession( request, false );
564                 return session != null ? ( ActionForm ) session.getAttribute( formBeanName ) : null;
565             }
566             else
567             {
568                 return ( ActionForm ) request.getAttribute( formBeanName );
569             }
570         }
571         
572         return null;
573     }
574     
575     /**
576      * Set the current ActionResolver ({@link PageFlowController}) in the user session.
577      *
578      * @param resolver the ActionResolver to set as the current one in the user session.
579      * @param request the current HttpServletRequest.
580      */

581     public static void setCurrentActionResolver( ActionResolver resolver, HttpServletRequest JavaDoc request )
582     {
583         HttpServletRequest JavaDoc unwrappedRequest = PageFlowUtils.unwrapMultipart( request );
584         
585         if ( resolver == null )
586         {
587             ScopedServletUtils.removeScopedSessionAttr( CURRENT_JPF_ATTR, unwrappedRequest );
588             ScopedServletUtils.removeScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
589             return;
590         }
591         
592         //
593
// If this is a long-lived page flow, also store the instance in an attribute that never goes away.
594
//
595
if ( resolver.isPageFlow() && isLongLived( ( ( PageFlowController ) resolver ).getModuleConfig() ) )
596         {
597             String JavaDoc longLivedAttrName = getLongLivedFlowAttr( resolver.getModulePath() );
598             
599             // Only set this attribute if it's not already there. We want to avoid our onDestroy() callback that's
600
// invoked when the page flow's session attribute is unbound.
601
if ( ScopedServletUtils.getScopedSessionAttr( longLivedAttrName, request ) != resolver )
602             {
603                 ScopedServletUtils.setScopedSessionAttr( longLivedAttrName, resolver, unwrappedRequest );
604             }
605             ScopedServletUtils.setScopedSessionAttr( CURRENT_LONGLIVED_ATTR, resolver.getModulePath(), unwrappedRequest );
606             ScopedServletUtils.removeScopedSessionAttr( CURRENT_JPF_ATTR, unwrappedRequest );
607         }
608         else
609         {
610             ScopedServletUtils.setScopedSessionAttr( CURRENT_JPF_ATTR, resolver, unwrappedRequest );
611             ScopedServletUtils.removeScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
612         }
613     }
614     
615     public static String JavaDoc getSharedFlowClassName( HttpServletRequest JavaDoc request, ServletContext JavaDoc servletContext )
616     {
617         return getSharedFlowClassNameForRelativeURI( getDecodedServletPath( request ), request, servletContext );
618     }
619     
620     public static String JavaDoc getSharedFlowClassNameForRelativeURI( String JavaDoc relativeURI, ServletRequest JavaDoc request,
621                                                                ServletContext JavaDoc servletContext )
622     {
623         String JavaDoc cachedInRequest = ( String JavaDoc ) request.getAttribute( SHARED_FLOW_CLASSNAME_ATTR );
624         if ( cachedInRequest != null ) return cachedInRequest.length() > 0 ? cachedInRequest : null;
625         
626         String JavaDoc parentDir = PageFlowUtils.getModulePathForRelativeURI( relativeURI );
627         String JavaDoc className = null;
628         
629         if ( parentDir.length() > 0 )
630         {
631             assert parentDir.charAt( 0 ) == '/' : parentDir;
632             parentDir = SHARED_FLOW_MODULE_PREFIX + parentDir.substring( 1 );
633             
634             do
635             {
636                 className = getFlowControllerClassName( parentDir, request, servletContext );
637                 if ( className!= null ) break;
638                 int lastSlash = parentDir.lastIndexOf( '/' );
639                 parentDir = parentDir.substring( 0, lastSlash );
640             } while ( parentDir.length() > 0 );
641         }
642         
643         if ( className == null )
644         {
645             className = getFlowControllerClassName( SHARED_FLOW_ROOT_MODULE, request, servletContext );
646         }
647         
648         if ( className == null )
649         {
650             className = getFlowControllerClassName( GLOBALAPP_MODULE_CONTEXT_PATH, request, servletContext );
651         }
652         
653         request.setAttribute( SHARED_FLOW_CLASSNAME_ATTR, className != null ? className : "" );
654         return className;
655     }
656     
657     public static boolean isSharedFlowModule( ModuleConfig mc )
658     {
659         ControllerConfig cc = mc.getControllerConfig();
660         return cc instanceof PageFlowControllerConfig && ( ( PageFlowControllerConfig ) cc ).isSharedFlow();
661     }
662     
663
664     public static FacesBackingBean getFacesBackingBean( ServletRequest JavaDoc request )
665     {
666         if ( request instanceof HttpServletRequest JavaDoc )
667         {
668             HttpServletRequest JavaDoc unwrappedRequest = PageFlowUtils.unwrapMultipart( ( HttpServletRequest