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 JavaDoc ) request );
669             return ( FacesBackingBean ) ScopedServletUtils.getScopedSessionAttr( FACES_BACKING_ATTR, unwrappedRequest );
670         }
671         
672         return null;
673     }
674     
675     public static void setFacesBackingBean( ServletRequest JavaDoc request, FacesBackingBean bean )
676     {
677         if ( request instanceof HttpServletRequest JavaDoc )
678         {
679             HttpServletRequest JavaDoc unwrappedRequest = PageFlowUtils.unwrapMultipart( ( HttpServletRequest JavaDoc ) request );
680             
681             if ( bean == null )
682             {
683                 ScopedServletUtils.removeScopedSessionAttr( FACES_BACKING_ATTR, unwrappedRequest );
684             }
685             else
686             {
687                 ScopedServletUtils.setScopedSessionAttr( FACES_BACKING_ATTR, bean, unwrappedRequest );
688             }
689         }
690     }
691     
692     public static String JavaDoc inferModulePathFromClassName( String JavaDoc className )
693     {
694         int lastDot = className.lastIndexOf( '.' );
695         
696         if ( lastDot != -1 )
697         {
698             className = className.substring( 0, lastDot );
699             return '/' + className.replace( '.', '/' );
700         }
701         else
702         {
703             return "";
704         }
705     }
706     
707     public static boolean isMultipartHandlingEnabled( ServletRequest JavaDoc request )
708     {
709         ModuleConfig moduleConfig = ( ModuleConfig ) request.getAttribute( Globals.MODULE_KEY );
710         return moduleConfig.getControllerConfig().getMultipartClass() != null;
711     }
712     
713     public static PageflowConfig.MultipartHandler.Enum getMultipartHandlerType()
714     {
715         PageflowConfig pfConfig = ConfigUtil.getConfig().getPageflowConfig();
716         return pfConfig != null ? pfConfig.getMultipartHandler() : null;
717     }
718     
719     public static void setServletContext( ServletRequest JavaDoc request, ServletContext JavaDoc servletContext )
720     {
721         ScopedServletUtils.getOuterServletRequest( request ).setAttribute( SERVLET_CONTEXT_ATTR, servletContext );
722     }
723     
724     public static ServletContext JavaDoc getServletContext( ServletRequest JavaDoc req )
725     {
726         HttpSession JavaDoc session = getHttpSession( req, false );
727         return session != null
728             ? session.getServletContext()
729             : ( ServletContext JavaDoc ) ScopedServletUtils.getOuterServletRequest( req ).getAttribute( SERVLET_CONTEXT_ATTR );
730     }
731     
732     public static HttpSession JavaDoc getHttpSession( ServletRequest JavaDoc request, boolean create )
733     {
734         if ( ! ( request instanceof HttpServletRequest JavaDoc ) ) return null;
735         return ( ( HttpServletRequest JavaDoc ) request ).getSession( create );
736     }
737
738     /**
739      * Simply adds the context path and parent directory, based on the current request URI.
740      */

741     public static String JavaDoc createActionURL( HttpServletRequest JavaDoc servletRequest, String JavaDoc qualifiedAction )
742     {
743         String JavaDoc pageURI = getDecodedURI( servletRequest );
744         int lastSlash = pageURI.lastIndexOf( '/' );
745         
746         if ( lastSlash != -1 )
747         {
748             InternalStringBuilder value = new InternalStringBuilder( qualifiedAction.length() + lastSlash );
749             value.append( pageURI.substring( 0, lastSlash ) );
750             value.append( qualifiedAction );
751             return value.toString();
752         }
753
754         return qualifiedAction;
755     }
756
757     public static String JavaDoc createActionPath( ServletRequest JavaDoc request, String JavaDoc qualifiedAction )
758     {
759         ModuleConfig appConfig = ( ModuleConfig ) request.getAttribute( Globals.MODULE_KEY );
760         
761         if ( appConfig != null )
762         {
763             InternalStringBuilder value = new InternalStringBuilder( qualifiedAction.length() + 16 );
764             value.append( appConfig.getPrefix() );
765             value.append( qualifiedAction );
766             return value.toString();
767         }
768
769         return qualifiedAction;
770     }
771
772     public static String JavaDoc qualifyAction( ServletContext JavaDoc servletContext, String JavaDoc action )
773     {
774         assert action != null;
775         InternalStringBuilder sb = null;
776
777         String JavaDoc queryString = null;
778         int question = action.indexOf( '?' );
779         if ( question >= 0 ) queryString = action.substring( question );
780
781         String JavaDoc actionMapping = getActionMappingName( action );
782         sb = new InternalStringBuilder( action.length() + ACTION_EXTENSION_LEN + 1 );
783         sb.append( actionMapping );
784         sb.append( ACTION_EXTENSION );
785         if ( queryString != null ) sb.append( queryString );
786
787         return sb.toString();
788     }
789     
790     /**
791      * Return the form action converted into an action mapping path. The
792      * value of the <code>action</code> property is manipulated as follows in
793      * computing the name of the requested mapping:
794      * <ul>
795      * <li>Any filename extension is removed (on the theory that extension
796      * mapping is being used to select the controller servlet).</li>
797      * <li>If the resulting value does not start with a slash, then a
798      * slash is prepended.</li>
799      * </ul>
800      *
801      * @param action the action name to be converted.
802      * @return an action path, suitable for lookup in the Struts configuration file.
803      */

804     public static String JavaDoc getActionMappingName( String JavaDoc action )
805     {
806         return getCleanActionName( action, true );
807     }
808     
809     public static String JavaDoc getCleanActionName( String JavaDoc action, boolean prependSlash )
810     {
811         int question = action.indexOf( '?' );
812         if ( question >= 0 )
813         {
814             action = action.substring( 0, question );
815         }
816         
817         if ( action.endsWith( ACTION_EXTENSION ) )
818         {
819             action = action.substring( 0, action.length() - ACTION_EXTENSION_LEN );
820         }
821         
822         if ( action.charAt( 0 ) == '/' )
823         {
824             if ( ! prependSlash ) action = action.substring( 1 );
825         }
826         else
827         {
828             if ( prependSlash ) action = '/' + action;
829         }
830         
831         return action;
832     }
833
834
835     /**
836      * Add a parameter to the given URL. Assumes there is no trailing
837      * anchor/fragment indicated with a '#'.
838      *
839      * @param url the URL to which to append.
840      * @param paramName the name of the parameter to add.
841      * @param paramVal the value of the parameter to add.
842      * @return the URL, with the given parameter added.
843      */

844     public static String JavaDoc addParam( String JavaDoc url, String JavaDoc paramName, String JavaDoc paramVal )
845     {
846         return url + ( url.indexOf( '?' ) != -1 ? '&' : '?' ) + paramName + '=' + paramVal;
847     }
848     
849     public static String JavaDoc getActionName( ActionMapping mapping )
850     {
851         if ( mapping == null ) return null;
852         
853         String JavaDoc actionName = mapping.getPath();
854         if ( actionName.charAt( 0 ) == '/' ) actionName = actionName.substring( 1 );
855         
856         //
857
// Look to see if we need are in a disambiguated action, i.e., one whose name is qualified
858
// by the form. If so, we need to restore the unqualified action name.
859
//
860
if ( mapping instanceof PageFlowActionMapping )
861         {
862             String JavaDoc unqualifiedAction = ( ( PageFlowActionMapping ) mapping ).getUnqualifiedActionName();
863             if ( unqualifiedAction != null ) actionName = unqualifiedAction;
864         }
865         
866         return actionName;
867     }
868     
869     public static ActionMapping getCurrentActionMapping( ServletRequest JavaDoc request )
870     {
871         return ( ActionMapping ) request.getAttribute( Globals.MAPPING_KEY );
872     }
873     
874     public static ActionForm getCurrentActionForm( ServletRequest JavaDoc request )
875     {
876         ActionMapping mapping = getCurrentActionMapping( request );
877         String JavaDoc attribute = mapping != null ? mapping.getAttribute() : null;
878         if ( attribute == null ) return null;
879         
880         if ( "request".equals( mapping.getScope() ) )
881         {
882             return ( ActionForm ) request.getAttribute( attribute );
883         }
884         else
885         {
886             HttpSession JavaDoc session = getHttpSession( request, false );
887             return session != null ? ( ActionForm ) session.getAttribute( attribute ) : null;
888         }
889     }
890     
891     public static boolean sessionExpired( ServletRequest JavaDoc servletRequest )
892     {
893         if ( servletRequest instanceof HttpServletRequest JavaDoc )
894         {
895             HttpServletRequest JavaDoc request = ( HttpServletRequest JavaDoc ) servletRequest;
896             String JavaDoc requestedSessionID = request.getRequestedSessionId();
897     
898             if ( requestedSessionID != null )
899             {
900                 HttpSession JavaDoc session = request.getSession( false );
901                 return session == null || ! requestedSessionID.equals( session.getId() );
902             }
903         }
904         
905         return false;
906     }
907     
908     public static void throwPageFlowException( PageFlowException ex )
909     {
910         throwPageFlowException( ex, null );
911     }
912     
913     public static void throwPageFlowException( PageFlowException effect, ServletRequest JavaDoc request )
914             throws PageFlowException
915     {
916         if ( request != null && effect.causeMayBeSessionExpiration() && sessionExpired( request ) )
917         {
918             PageflowConfig pfc = ConfigUtil.getConfig().getPageflowConfig();
919             if ( pfc == null || ! pfc.isSetThrowSessionExpiredException() || pfc.getThrowSessionExpiredException() )
920             {
921                 throw new SessionExpiredException( effect );
922             }
923         }
924         
925         throw effect;
926     }
927     
928     /**
929      * Get the Struts ActionConfig for the given action config path and module path.
930      */

931     public static ActionConfig findActionConfig( String JavaDoc actionConfigPath, String JavaDoc modulePath, ServletContext JavaDoc context )
932     {
933         ModuleConfig moduleConfig = getModuleConfig( modulePath, context );
934         assert moduleConfig != null;
935         return moduleConfig.findActionConfig( actionConfigPath );
936     }
937
938     /**
939      * Get the Struts ActionMapping path from the ActionMapping that is in the request under the key
940      * Globals.MAPPING_KEY.
941      *
942      * @return the path for the ActionMapping, as found with ActionMapping.getPath()
943      */

944     public static String JavaDoc getActionMappingPath( ServletRequest JavaDoc request )
945     {
946         ActionMapping actionMapping = ( ActionMapping ) request.getAttribute( Globals.MAPPING_KEY );
947         return actionMapping != null ? actionMapping.getPath() : null;
948     }
949
950     /**
951      * Gets the Struts module path from the input request. If a ModuleConfig
952      * object has been populated into the request it is used to get the module prefix,
953      * otherwise getModulePath is called, which derives the module path from
954      * the request URI.
955      */

956     public static String JavaDoc getModulePathFromReqAttr( HttpServletRequest JavaDoc request )
957     {
958         //
959
// If a config was in the request, use its associated prefix; otherwise, fall back to the URI.
960
//
961
ModuleConfig config = ( ModuleConfig ) request.getAttribute( Globals.MODULE_KEY );
962         return config != null ? config.getPrefix() : PageFlowUtils.getModulePath( request );
963     }
964     
965     /**
966      * Set the forwarded form. This overrides the auto-generated form created by processActionForm
967      * and populated by processPopulate (in PageFlowRequestProcessor).
968      */

969     public static void setForwardedFormBean( ServletRequest JavaDoc request, ActionForm form )
970     {
971         if ( form == null )
972         {
973             request.removeAttribute( FORWARDED_FORMBEAN_ATTR );
974         }
975         else
976         {
977             request.setAttribute( FORWARDED_FORMBEAN_ATTR, form );
978         }
979     }
980     
981     public static ActionForm getForwardedFormBean( ServletRequest JavaDoc request, boolean removeFromRequest )
982     {
983         ActionForm form = ( ActionForm ) request.getAttribute( FORWARDED_FORMBEAN_ATTR );
984         if ( removeFromRequest ) request.removeAttribute( FORWARDED_FORMBEAN_ATTR );
985         return form;
986     }
987     
988     /**
989      * Tell whether a special request attribute was set, indicating that we should avoid writing to the response (or
990      * setting response error codes).
991      */

992     public static boolean avoidDirectResponseOutput( ServletRequest JavaDoc request )
993     {
994         Boolean JavaDoc avoid = ( Boolean JavaDoc ) request.getAttribute( AVOID_DIRECT_RESPONSE_OUTPUT_ATTR );
995         return avoid != null && avoid.booleanValue();
996     }
997
998     /**
999      * Set a special request attribute to indicate that we should avoid writing to the response (or
1000     * setting response error codes).
1001     */

1002    public static void setAvoidDirectResponseOutput( ServletRequest JavaDoc request )
1003    {
1004        request.setAttribute( AVOID_DIRECT_RESPONSE_OUTPUT_ATTR, Boolean.TRUE );
1005    }
1006    
1007    /**
1008     * Set the module prefix for the ModuleConfig that is performing a forward in this request.
1009     */

1010    public static void setForwardingModule( ServletRequest JavaDoc request, String JavaDoc modulePrefix )
1011    {
1012        request.setAttribute( FORWARDING_MODULE_ATTR, modulePrefix );
1013    }
1014    
1015    /**
1016     * Set the module prefix for the ModuleConfig that is performing a forward in this request.
1017     */

1018    public static String JavaDoc getForwardingModule( ServletRequest JavaDoc request )
1019    {
1020        return ( String JavaDoc ) request.getAttribute( FORWARDING_MODULE_ATTR );
1021    }
1022    
1023    public static String JavaDoc getFormBeanType( FormBeanConfig formBeanConfig )
1024    {
1025        String JavaDoc formBeanType = null;
1026        
1027        // First, try to read the form bean type from our custom property, which supports the any-bean feature.
1028
if ( formBeanConfig instanceof PageFlowActionFormBean )
1029        {
1030            formBeanType = ( ( PageFlowActionFormBean ) formBeanConfig ).getActualType();
1031        }
1032        
1033        // If we didn't find it there, this is a normal Struts ActionForm. Just get it from the type attr.
1034
if ( formBeanType == null ) formBeanType = formBeanConfig.getType();
1035        
1036        return formBeanType;
1037    }
1038    
1039    /**
1040     * Tell {@link #getDecodedServletPath} (and all that call it) to ignore the attribute that specifies the Servlet
1041     * Include path, which is set when a Servlet include is done through RequestDispatcher. Normally,
1042     * getDecodedServletPath tries the Servlet Include path before falling back to getServletPath() on the request.
1043     * Note that this is basically a stack of instructions to ignore the include path, and this method expects each
1044     * call with <code>ignore</code>==<code>true</code> to be balanced by a call with
1045     * <code>ignore</code>==<code>false</code>.
1046     */

1047    public static void setIgnoreIncludeServletPath( ServletRequest JavaDoc request, boolean ignore )
1048    {
1049        Integer JavaDoc depth = ( Integer JavaDoc ) request.getAttribute( IGNORE_INCLUDE_SERVLET_PATH_ATTR );
1050        
1051        if ( ignore )
1052        {
1053            if ( depth == null ) depth = new Integer JavaDoc( 0 );
1054            request.setAttribute( IGNORE_INCLUDE_SERVLET_PATH_ATTR, new Integer JavaDoc( depth.intValue() + 1 ) );
1055        }
1056        else
1057        {
1058            assert depth != null : "call to setIgnoreIncludeServletPath() was imbalanced";
1059            depth = new Integer JavaDoc( depth.intValue() - 1 );
1060            
1061            if ( depth.intValue() == 0 )
1062            {
1063                request.removeAttribute( IGNORE_INCLUDE_SERVLET_PATH_ATTR );
1064            }
1065            else
1066            {
1067                request.setAttribute( IGNORE_INCLUDE_SERVLET_PATH_ATTR, depth );
1068            }
1069        }
1070    }
1071    
1072    public static boolean ignoreIncludeServletPath( ServletRequest JavaDoc request )
1073    {
1074        return request.getAttribute( IGNORE_INCLUDE_SERVLET_PATH_ATTR ) != null;
1075    }
1076
1077    /**
1078     * If the given request is a MultipartRequestWrapper (Struts class that doesn't extend
1079     * HttpServletRequestWrapper), return the wrapped request; otherwise, return the given request.
1080     */

1081    public static ServletRequest JavaDoc unwrapMultipart( ServletRequest JavaDoc request )
1082    {
1083        if ( request instanceof MultipartRequestWrapper )
1084        {
1085            request = ( ( MultipartRequestWrapper ) request ).getRequest();
1086        }
1087
1088        return request;
1089    }
1090    
1091    /**
1092     * Set the given Struts module in the request, and expose its set of MessageResources as request attributes.
1093     *
1094     * @param prefix the prefix of the desired module.
1095     * @param request the current HttpServletRequest.
1096     * @param servletContext the current ServletContext.
1097     * @return the selected ModuleConfig, or <code>null</code> if there is none for the given module prefix.
1098     */

1099    public static ModuleConfig selectModule( String JavaDoc prefix, HttpServletRequest JavaDoc request, ServletContext JavaDoc servletContext )
1100    {
1101        ModuleConfig config = getModuleConfig( prefix, servletContext );
1102
1103        if ( config == null )
1104        {
1105            request.removeAttribute( Globals.MODULE_KEY );
1106            return null;
1107        }
1108        
1109        // Just return it if it's already registered.
1110
if ( request.getAttribute( Globals.MODULE_KEY ) == config ) return config;
1111        
1112        request.setAttribute( Globals.MODULE_KEY, config );
1113
1114        MessageResourcesConfig[] mrConfig = config.findMessageResourcesConfigs();
1115        Object JavaDoc formBean = unwrapFormBean( getCurrentActionForm( request ) );
1116        
1117        for ( int i = 0; i < mrConfig.length; i++ )
1118        {
1119            String JavaDoc key = mrConfig[i].getKey();
1120            MessageResources resources = ( MessageResources ) servletContext.getAttribute( key + prefix );
1121            
1122            if ( resources != null )
1123            {
1124                if ( ! ( resources instanceof ExpressionAwareMessageResources ) )
1125                {
1126                    resources = new ExpressionAwareMessageResources( resources, formBean, request, servletContext );
1127                }
1128                
1129                request.setAttribute( key, resources );
1130            }
1131            else
1132            {
1133                request.removeAttribute( key );
1134            }
1135        }
1136        
1137        return config;
1138    }
1139    
1140    public static MessageResources getMessageResources( String JavaDoc bundleName, ServletRequest JavaDoc request,
1141                                                        ServletContext JavaDoc servletContext )
1142    {
1143        MessageResources resources = (MessageResources) request.getAttribute(bundleName);
1144        
1145        if ( resources == null )
1146        {
1147            String JavaDoc qualified = getQualifiedBundleName(bundleName, request);
1148            resources = (MessageResources) servletContext.getAttribute(qualified);
1149        }
1150        
1151        // If we can't find resources with this name, try them at the root (unqualified).
1152
if ( resources == null ) resources = (MessageResources) servletContext.getAttribute(bundleName);
1153        
1154        return resources;
1155    }
1156    
1157    /**
1158     * Qualify the given bundle name with the current module path to return a full bundle name.
1159     *
1160     * @return the qualified Bundle name
1161     */

1162    public static String JavaDoc getQualifiedBundleName( String JavaDoc bundleName, ServletRequest JavaDoc request )
1163    {
1164        if ( bundleName != null )
1165        {
1166            if ( bundleName.indexOf( '/' ) == -1 )
1167            {
1168                ModuleConfig mc = ( ModuleConfig ) request.getAttribute( Globals.MODULE_KEY );
1169
1170                // Note that we don't append the module path for the root module.
1171
if ( mc != null && mc.getPrefix() != null && mc.getPrefix().length() > 1 )
1172                {
1173                    bundleName += mc.getPrefix();
1174                }
1175            }
1176            else if ( bundleName.endsWith( "/" ) )
1177            {
1178                // Special handling for bundles referring to the root module -- they should not have
1179
// the module path ("/") at the end.
1180
bundleName = bundleName.substring( 0, bundleName.length() - 1 );
1181            }
1182        }
1183
1184        return bundleName;
1185    }
1186
1187    public static Locale JavaDoc lookupLocale(JspContext JavaDoc jspContext) {
1188        assert jspContext instanceof PageContext JavaDoc : "Found JspContext of type \"" + (jspContext != null ? jspContext.getClass().getName() : "null") + "\"";
1189        return lookupLocale(((PageContext JavaDoc)jspContext).getRequest());
1190    }
1191
1192    public static Locale JavaDoc lookupLocale(ServletRequest JavaDoc request) {
1193        assert request instanceof HttpServletRequest JavaDoc : "Found servlet request of type \"" + (request != null ? request.getClass().getName() : "null") + "\"";
1194
1195        Locale JavaDoc locale = null;
1196        HttpServletRequest JavaDoc httpServletRequest = (HttpServletRequest JavaDoc)request;
1197        HttpSession JavaDoc session = httpServletRequest.getSession(false);
1198        if(session != null)
1199            locale = (Locale JavaDoc)session.getAttribute(Globals.LOCALE_KEY);
1200
1201        if(locale == null)
1202            locale = request.getLocale();
1203
1204        return locale;
1205    }
1206}
1207
Popular Tags