KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > pageflow > PageFlowUtils


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;
19
20 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
21
22 import org.apache.beehive.netui.core.urls.FreezableMutableURI;
23 import org.apache.beehive.netui.core.urls.MutableURI;
24 import org.apache.beehive.netui.core.urls.URIContext;
25 import org.apache.beehive.netui.core.urls.URLRewriterService;
26 import org.apache.beehive.netui.core.urls.URLType;
27 import org.apache.beehive.netui.core.urltemplates.URLTemplateDescriptor;
28 import org.apache.beehive.netui.pageflow.internal.ActionResultImpl;
29 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
30 import org.apache.beehive.netui.pageflow.internal.InternalConstants;
31 import org.apache.beehive.netui.pageflow.internal.AdapterManager;
32 import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
33 import org.apache.beehive.netui.pageflow.internal.URIContextFactory;
34 import org.apache.beehive.netui.pageflow.scoping.ScopedRequest;
35 import org.apache.beehive.netui.pageflow.scoping.ScopedResponse;
36 import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
37 import org.apache.beehive.netui.util.internal.FileUtils;
38 import org.apache.beehive.netui.util.internal.ServletUtils;
39 import org.apache.beehive.netui.util.config.ConfigUtil;
40 import org.apache.beehive.netui.util.config.bean.UrlConfig;
41 import org.apache.beehive.netui.util.logging.Logger;
42 import org.apache.beehive.netui.script.common.ImplicitObjectUtil;
43 import org.apache.struts.action.ActionForm;
44 import org.apache.struts.action.ActionMapping;
45 import org.apache.struts.action.ActionServlet;
46 import org.apache.struts.action.ActionMessage;
47 import org.apache.struts.config.FormBeanConfig;
48 import org.apache.struts.config.ModuleConfig;
49 import org.apache.struts.upload.MultipartRequestWrapper;
50 import org.apache.struts.util.RequestUtils;
51
52 import javax.servlet.ServletContext JavaDoc;
53 import javax.servlet.ServletRequest JavaDoc;
54 import javax.servlet.http.HttpServletRequest JavaDoc;
55 import javax.servlet.http.HttpServletResponse JavaDoc;
56 import javax.servlet.http.HttpSession JavaDoc;
57 import java.io.PrintStream JavaDoc;
58 import java.net.URISyntaxException JavaDoc;
59 import java.util.Collections JavaDoc;
60 import java.util.HashMap JavaDoc;
61 import java.util.Map JavaDoc;
62 import java.util.Stack JavaDoc;
63 import java.util.List JavaDoc;
64 import java.util.ArrayList JavaDoc;
65 import java.util.Iterator JavaDoc;
66
67 import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
68
69
70
71 /**
72  * Utility methods related to Page Flow.
73  */

74 public class PageFlowUtils
75         implements PageFlowConstants, InternalConstants
76 {
77     private static final Logger _log = Logger.getInstance( PageFlowUtils.class );
78
79     private static final String JavaDoc ACTION_URI_ATTR = ATTR_PREFIX + "_actionURI";
80     private static final int PAGEFLOW_EXTENSION_LEN = PAGEFLOW_EXTENSION.length();
81     private static final String JavaDoc DEFAULT_AUTORESOLVE_EXTENSIONS[] = new String JavaDoc[]{ ACTION_EXTENSION, PAGEFLOW_EXTENSION };
82     
83     
84     /** Map of Struts module prefix to Map of form-type-name to form-name. */
85     private static Map JavaDoc/*< String, Map< String, List< String > > >*/ _formNameMaps =
86             new InternalConcurrentHashMap/*< String, Map< String, List< String > > >*/();
87
88     
89     /**
90      * Get the Struts module path for a URI. This is the parent directory, relative to the web
91      * application root, of the file referenced by the URI.
92      *
93      * @param request the current HttpServletRequest.
94      * @param requestURI the URI for which to get the Struts module path.
95      */

96     public static String JavaDoc getModulePath( HttpServletRequest JavaDoc request, String JavaDoc requestURI )
97     {
98         return getModulePathForRelativeURI( getRelativeURI( request, requestURI, null ) );
99     }
100
101     /**
102      * Get the Struts module path for the current request URI. This is the parent directory,
103      * relative to the web application root, of the file referenced by the request URI.
104      *
105      * @param request the current HttpServletRequest.
106      */

107     public static String JavaDoc getModulePath( HttpServletRequest JavaDoc request )
108     {
109         return getModulePathForRelativeURI( InternalUtils.getDecodedServletPath( request ) );
110     }
111
112     /**
113      * Get the Struts module path for a URI that is relative to the web application root.
114      *
115      * @param uri the URI for which to get the module path.
116      */

117     public static String JavaDoc getModulePathForRelativeURI( String JavaDoc uri )
118     {
119         assert uri.length() > 0;
120         assert uri.charAt( 0 ) == '/' : uri;
121
122         // Strip off the actual page name (e.g., some_page.jsp)
123
int slash = uri.lastIndexOf( '/' );
124         uri = uri.substring( 0, slash );
125
126         return uri;
127     }
128
129     /**
130      * Get the request URI, relative to the URI of the given PageFlowController.
131      *
132      * @param request the current HttpServletRequest.
133      * @param relativeTo a PageFlowController to which the returned URI should be relative, or
134      * <code>null</code> if the returned URI should be relative to the webapp root.
135      */

136     public static final String JavaDoc getRelativeURI( HttpServletRequest JavaDoc request, PageFlowController relativeTo )
137     {
138         if ( relativeTo == null ) return InternalUtils.getDecodedServletPath( request );
139         return getRelativeURI( request, InternalUtils.getDecodedURI( request ), relativeTo );
140     }
141
142     /**
143      * Get a URI relative to the URI of the given PageFlowController.
144      *
145      * @param request the current HttpServletRequest.
146      * @param uri the URI which should be made relative.
147      * @param relativeTo a PageFlowController to which the returned URI should be relative, or
148      * <code>null</code> if the returned URI should be relative to the webapp root.
149      */

150     public static final String JavaDoc getRelativeURI( HttpServletRequest JavaDoc request, String JavaDoc uri, PageFlowController relativeTo )
151     {
152         String JavaDoc contextPath = request.getContextPath();
153         if ( relativeTo != null ) contextPath += relativeTo.getModulePath();
154         int overlap = uri.indexOf( contextPath + '/' );
155         if ( overlap == -1 ) return null;
156         return uri.substring( overlap + contextPath.length() );
157     }
158
159     /**
160      * Get a URI for the "begin" action in the PageFlowController associated with the given
161      * request URI.
162      *
163      * @return a String that is the URI for the "begin" action in the PageFlowController associated
164      * with the given request URI.
165      */

166     public static String JavaDoc getBeginActionURI( String JavaDoc requestURI )
167     {
168         // Translate this to a request for the begin action ("begin.do") for this PageFlowController.
169
InternalStringBuilder retVal = new InternalStringBuilder();
170         int lastSlash = requestURI.lastIndexOf( '/' );
171
172         if ( lastSlash != -1 )
173         {
174             retVal.append( requestURI.substring( 0, lastSlash ) );
175         }
176
177         retVal.append( '/' ).append( BEGIN_ACTION_NAME ).append( ACTION_EXTENSION );
178         return retVal.toString();
179     }
180
181     /**
182      * Get the stack of nested page flows for the current user session. Create and store an empty
183      * stack if none exists.
184      *
185      * @deprecated Use {@link PageFlowStack#get} instead.
186      *
187      * @param request the current HttpServletRequest
188      * @return a {@link PageFlowStack} of nested page flows ({@link PageFlowController}s) for the current user session.
189      */

190     public static final Stack JavaDoc getPageFlowStack( HttpServletRequest JavaDoc request )
191     {
192         return PageFlowStack.get( request, true ).getLegacyStack();
193     }
194     
195     /**
196      * Destroys the stack of {@link PageFlowController}s that have invoked nested page flows.
197      *
198      * @deprecated Use {@link PageFlowStack#destroy} instead.
199      *
200      * @param request the current HttpServletRequest.
201      */

202     public static void destroyPageFlowStack( HttpServletRequest JavaDoc request )
203     {
204         PageFlowStack.destroy( request );
205     }
206     
207     /**
208      * Get the {@link PageFlowController} that is nesting the current one.
209      *
210      * @param request the current HttpServletRequest.
211      * @return the nesting {@link PageFlowController}, or <code>null</code> if the current one
212      * is not being nested.
213      */

214     public static PageFlowController getNestingPageFlow( HttpServletRequest JavaDoc request )
215     {
216         PageFlowStack jpfStack = PageFlowStack.get( request, false );
217         
218         if ( jpfStack != null && ! jpfStack.isEmpty() )
219         {
220             PageFlowController top = jpfStack.peek().getPageFlow();
221             return top;
222         }
223         
224         return null;
225     }
226
227     /**
228      * Get the current PageFlowController.
229      *
230      * @param request the current HttpServletRequest.
231      * @return the current PageFlowController from the user session, or <code>null</code>
232      * if there is none.
233      */

234     public static final PageFlowController getCurrentPageFlow( HttpServletRequest JavaDoc request )
235     {
236         ActionResolver cur = getCurrentActionResolver( request );
237         return cur != null && cur.isPageFlow() ? ( PageFlowController ) cur : null;
238     }
239     
240     /**
241      * Get the current ActionResolver ({@link PageFlowController}).
242      *
243      * @return the current ActionResolver from the user session, or <code>null</code> if there is none.
244      */

245     public static ActionResolver getCurrentActionResolver( HttpServletRequest JavaDoc request )
246     {
247         //
248
// First see if the current page flow is a long-lived, which is stored in its own attribute.
249
//
250
HttpServletRequest JavaDoc unwrappedRequest = unwrapMultipart( request );
251         String JavaDoc currentLongLivedModulePath =
252                 ( String JavaDoc ) ScopedServletUtils.getScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
253         ActionResolver retVal;
254         
255         if ( currentLongLivedModulePath != null )
256         {
257             retVal = getLongLivedPageFlow( currentLongLivedModulePath, unwrappedRequest );
258         }
259         else
260         {
261             retVal = ( ActionResolver ) ScopedServletUtils.getScopedSessionAttr( CURRENT_JPF_ATTR, unwrappedRequest );
262         }
263         
264         return retVal;
265     }
266     
267     /**
268      * Get the current {@link GlobalApp} instance.
269      *
270      * @deprecated Use {@link #getSharedFlow} instead.
271      * @param request the current HttpServletRequest.
272      * @return the current {@link GlobalApp} from the user session, or <code>null</code> if none
273      * exists.
274      */

275     public static GlobalApp getGlobalApp( HttpServletRequest JavaDoc request )
276     {
277         SharedFlowController sf = getSharedFlow( InternalConstants.GLOBALAPP_CLASSNAME, request );
278         return sf instanceof GlobalApp ? ( GlobalApp ) sf : null;
279     }
280
281     /**
282      * Get the a map of shared flow name to shared flow instance, based on the names defined in the
283      * {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller#sharedFlowRefs sharedFlowRefs} attribute
284      * of the {@link org.apache.beehive.netui.pageflow.annotations.Jpf.Controller &#64;Jpf.Controller} annotation on the
285      * <strong>current page flow</strong>.
286      *
287      * @param request the current HttpServletRequest, which is used to determine the current page flow.
288      * @return a Map of shared flow name (string) to shared flow instance ({@link SharedFlowController}).
289      */

290     public static Map JavaDoc/*< String, SharedFlowController >*/ getSharedFlows( HttpServletRequest JavaDoc request )
291     {
292         Map JavaDoc/*< String, SharedFlowController >*/ sharedFlows = ImplicitObjectUtil.getSharedFlow( request );
293         return sharedFlows != null ? sharedFlows : Collections.EMPTY_MAP;
294     }
295     
296     /**
297      * Get the shared flow with the given class name.
298      *
299      * @param sharedFlowClassName the class name of the shared flow to remove.
300      * @param request the current HttpServletRequest.
301      * @return the {@link SharedFlowController} of the given class name which is stored in the user session.
302      */

303     public static SharedFlowController getSharedFlow( String JavaDoc sharedFlowClassName, HttpServletRequest JavaDoc request )
304     {
305         HttpSession JavaDoc session = request.getSession( false );
306         
307         if ( session != null )
308         {
309             return ( SharedFlowController ) session.getAttribute( SHARED_FLOW_ATTR_PREFIX + sharedFlowClassName );
310         }
311         
312         return null;
313     }
314     
315     /**
316      * Destroy the current {@link SharedFlowController} of the given class name.
317      * @param sharedFlowClassName the class name of the current SharedFlowController to destroy.
318      * @param request the current HttpServletRequest.
319      */

320     public static void removeSharedFlow( String JavaDoc sharedFlowClassName, HttpServletRequest JavaDoc request )
321     {
322         HttpSession JavaDoc session = request.getSession( false );
323         if ( session != null ) request.getSession().removeAttribute( SHARED_FLOW_ATTR_PREFIX + sharedFlowClassName );
324     }
325     
326     
327     /**
328      * Remove a "long-lived" page flow from the session. Once it is created, a long-lived page flow
329      * is never removed from the session unless this method or {@link PageFlowController#remove} is
330      * called. Navigating to another page flow hides the current long-lived controller, but does not
331      * remove it.
332      */

333     public static void removeLongLivedPageFlow( String JavaDoc modulePath, HttpServletRequest JavaDoc request )
334     {
335         HttpServletRequest JavaDoc unwrappedRequest = unwrapMultipart( request );
336         String JavaDoc attrName = InternalUtils.getLongLivedFlowAttr( modulePath );
337         ScopedServletUtils.removeScopedSessionAttr( attrName, unwrappedRequest );
338
339         //
340
// Now, if the current page flow is long-lived, remove the reference.
341
//
342
String JavaDoc currentLongLivedModulePath =
343                 ( String JavaDoc ) ScopedServletUtils.getScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
344         
345         if ( modulePath.equals( currentLongLivedModulePath ) )
346         {
347             ScopedServletUtils.removeScopedSessionAttr( CURRENT_LONGLIVED_ATTR, unwrappedRequest );
348         }
349     }
350     
351     /**
352      * Get the long-lived page flow instance associated with the given module (directory) path.
353      *
354      * @param modulePath the webapp-relative path to the directory containing the long-lived page flow.
355      * @param request the current HttpServletRequest.
356      * @return the long-lived page flow instance associated with the given module, or <code>null</code> if none is found.
357      */

358     public static PageFlowController getLongLivedPageFlow( String JavaDoc modulePath, HttpServletRequest JavaDoc request )
359     {
360         String JavaDoc attr = InternalUtils.getLongLivedFlowAttr( modulePath );
361         PageFlowController retVal = ( PageFlowController )
362                 ScopedServletUtils.getScopedSessionAttr( attr, unwrapMultipart( request ) );
363         return retVal;
364     }
365     
366     /**
367      * Make any form beans in the given {@link Forward} object available as attributets in the
368      * request/session (as appropriate).
369      *
370      * @param mapping the ActionMapping for the current Struts action being processed.
371      * @param fwd the {@link Forward} object that contains the ActionForm instances to be
372      * made available in the request/session (as appropriate).
373      * @param request the current HttpServletRequest.
374      * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
375      * in the request if there is no existing form with the same name.
376      */

377     public static void setOutputForms( ActionMapping mapping, Forward fwd, HttpServletRequest JavaDoc request,
378                                        boolean overwrite )
379     {
380         if ( fwd == null ) return;
381         
382         //
383
// *If* there is a target action mapping, set output forms for it.
384
//
385
if ( mapping != null ) setOutputForms( mapping, fwd.getOutputForms(), request, overwrite );
386         
387         InternalUtils.setForwardedFormBean( request, fwd.getFirstOutputForm( request ) );
388     }
389     
390     /**
391      * Make any form beans in the given {@link Forward} object available as attributets in the
392      * request/session (as appropriate).
393      *
394      * @param mapping the ActionMapping for the current Struts action being processed.
395      * @param fwd the {@link Forward} object that contains the ActionForm instances to be
396      * made available in the request/session (as appropriate).
397      * @param request the current HttpServletRequest.
398      */

399     public static void setOutputForms( ActionMapping mapping, Forward fwd, HttpServletRequest JavaDoc request )
400     {
401         if ( fwd == null )
402         {
403             return;
404         }
405
406         if ( mapping != null )
407         {
408             setOutputForms( mapping, fwd.getOutputForms(), request );
409         }
410
411         InternalUtils.setForwardedFormBean( request, fwd.getFirstOutputForm( request ) );
412     }
413
414     /**
415      * Make a set of form beans available as attributets in the request/session (as appropriate).
416      *
417      * @param mapping the ActionMapping for the current Struts action being processed.
418      * @param outputForms an array of ActionForm instances to be made available in the
419      * request/session (as appropriate).
420      * @param request the current HttpServletRequest.
421      */

422     public static void setOutputForms( ActionMapping mapping, ActionForm[] outputForms,
423                                        HttpServletRequest JavaDoc request )
424     {
425         setOutputForms( mapping, outputForms, request, true );
426     }
427     
428     /**
429      * Make a set of form beans available as attributets in the request/session (as appropriate).
430      *
431      * @param mapping the ActionMapping for the current Struts action being processed.
432      * @param outputForms an array of ActionForm instances to be made available in the
433      * request/session (as appropriate).
434      * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
435      * in the request if there is no existing form with the same name.
436      * @param request the current HttpServletRequest.
437      */

438     public static void setOutputForms( ActionMapping mapping, ActionForm[] outputForms,
439                                        HttpServletRequest JavaDoc request, boolean overwrite )
440     {
441         try
442         {
443             //
444
// Now set any output forms in the request or session, as appropriate.
445
//
446
assert mapping.getScope() == null
447                     || mapping.getScope().equals( "request" )
448                     || mapping.getScope().equals( "session" )
449                 : mapping.getScope();
450
451             
452             for ( int i = 0; i < outputForms.length; ++i )
453             {
454                 setOutputForm( mapping, outputForms[i], request, overwrite );
455             }
456         }
457         catch ( Exception JavaDoc e )
458         {
459             _log.error( "Error while setting Struts form-beans", e );
460         }
461     }
462
463     private static List JavaDoc/*< String >*/ getFormNamesFromModuleConfig( String JavaDoc formBeanClassName, ModuleConfig moduleConfig )
464     {
465         String JavaDoc modulePrefix = moduleConfig.getPrefix();
466         Map JavaDoc/*< String, List< String > >*/ formNameMap = ( Map JavaDoc ) _formNameMaps.get( modulePrefix ); // map of form-type-name to form-name
467

468         if ( formNameMap == null )
469         {
470             formNameMap = new HashMap JavaDoc/*< String, List< String > >*/();
471             FormBeanConfig[] formBeans = moduleConfig.findFormBeanConfigs();
472             
473             for ( int j = 0; j < formBeans.length; ++j )
474             {
475                 assert formBeans[j] != null;
476                 String JavaDoc formBeanType = InternalUtils.getFormBeanType( formBeans[j] );
477                 List JavaDoc/*< String >*/ formBeanNames = ( List JavaDoc ) formNameMap.get( formBeanType );
478                 
479                 if ( formBeanNames == null )
480                 {
481                     formBeanNames = new ArrayList JavaDoc/*< String >*/();
482                     formNameMap.put( formBeanType, formBeanNames );
483                 }
484                 
485                 formBeanNames.add( formBeans[j].getName() );
486             }
487             
488             _formNameMaps.put( modulePrefix, formNameMap );
489         }
490         
491         return ( List JavaDoc ) formNameMap.get( formBeanClassName );
492     }
493     
494     /**
495      * Make a form bean available as an attributet in the request/session (as appropriate).
496      *
497      * @param mapping the ActionMapping for the current Struts action being processed.
498      * @param form an ActionForm instance to be made available in the request/session
499      * (as appropriate).
500      * @param overwrite if <code>false</code> a form from <code>fwd</code> will only be set
501      * in the request if there is no existing form with the same name.
502      * @param request the current HttpServletRequest.
503      */

504     public static void setOutputForm( ActionMapping mapping, ActionForm form,
505                                       HttpServletRequest JavaDoc request, boolean overwrite )
506     {
507         if ( form != null )
508         {
509             ModuleConfig moduleConfig = mapping.getModuleConfig();
510             Class JavaDoc formClass = InternalUtils.unwrapFormBean( form ).getClass();
511             
512             //
513
// Get the names of *all* form beans of the desired type, and blast out this instance under all those names.
514
//
515
List JavaDoc/*< String >*/ formNames = getFormNamesFromModuleConfig( formClass.getName(), moduleConfig );
516             
517             if ( formNames == null )
518             {
519                 String JavaDoc formName = generateFormBeanName( formClass, request );
520                 InternalUtils.setFormInScope( formName, form, mapping, request, overwrite );
521             }
522             else
523             {
524                 assert formNames.size() > 0; // getFormNamesFromModuleConfig returns null or a nonempty list
525

526                 for ( Iterator JavaDoc ii = formNames.iterator(); ii.hasNext(); )
527                 {
528                     String JavaDoc formName = ( String JavaDoc ) ii.next();
529                     InternalUtils.setFormInScope( formName, form, mapping, request, overwrite );
530                 }
531             }
532         }
533     }
534     
535     /**
536      * Get the name for the type of a ActionForm instance. Use a name looked up from
537      * the current Struts module, or, if none is found, create one.
538      *
539      * @param formInstance the ActionForm instance whose type will determine the name.
540      * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
541      * @return the name found in the Struts module, or, if none is found, a name that is either:
542      * <ul>
543      * <li>a camel-cased version of the base class name (minus any package or outer-class
544      * qualifiers, or, if that name is already taken,</li>
545      * <li>the full class name, with '.' and '$' replaced by '_'.</li>
546      * </ul>
547      */

548     public static String JavaDoc getFormBeanName( ActionForm formInstance, HttpServletRequest JavaDoc request )
549     {
550         return getFormBeanName( formInstance.getClass(), request );
551     }
552
553     /**
554      * Get the name for an ActionForm type. Use a name looked up from the current Struts module, or,
555      * if none is found, create one.
556      *
557      * @param formBeanClass the ActionForm-derived class whose type will determine the name.
558      * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
559      * @return the name found in the Struts module, or, if none is found, a name that is either:
560      * <ul>
561      * <li>a camel-cased version of the base class name (minus any package or outer-class
562      * qualifiers, or, if that name is already taken,</li>
563      * <li>the full class name, with '.' and '$' replaced by '_'.</li>
564      * </ul>
565      */

566     public static String JavaDoc getFormBeanName( Class JavaDoc formBeanClass, HttpServletRequest JavaDoc request )
567     {
568         ModuleConfig moduleConfig = RequestUtils.getRequestModuleConfig( request );
569         List JavaDoc/*< String >*/ names = getFormNamesFromModuleConfig( formBeanClass.getName(), moduleConfig );
570         
571         if ( names != null )
572         {
573             assert names.size() > 0; // getFormNamesFromModuleConfig returns null or a nonempty list
574
return ( String JavaDoc ) names.get( 0 );
575         }
576         
577         return generateFormBeanName( formBeanClass, request );
578     }
579
580     /**
581      * Create the name for a form bean type.
582      *
583      * @param formBeanClass the class whose type will determine the name.
584      * @param request the current HttpServletRequest, which contains a reference to the current Struts module.
585      * @return the name found in the Struts module, or, if none is found, a name that is either:
586      * <ul>
587      * <li>a camel-cased version of the base class name (minus any package or outer-class
588      * qualifiers, or, if that name is already taken,</li>
589      * <li>the full class name, with '.' and '$' replaced by '_'.</li>
590      * </ul>
591      */

592     private static String JavaDoc generateFormBeanName( Class JavaDoc formBeanClass, HttpServletRequest JavaDoc request )
593     {
594         ModuleConfig moduleConfig = RequestUtils.getRequestModuleConfig( request );
595         String JavaDoc formBeanClassName = formBeanClass.getName();
596         
597         //
598
// A form-bean wasn't found for this type, so we'll create a name. First try and create
599
// name that is a camelcased version of the classname without all of its package/outer-class
600
// qualifiers. If one with that name already exists, munge the fully-qualified classname.
601
//
602
String JavaDoc formType = formBeanClassName;
603         int lastQualifier = formType.lastIndexOf( '$' );
604
605         if ( lastQualifier == -1 )
606         {
607             lastQualifier = formType.lastIndexOf( '.' );
608         }
609
610         String JavaDoc formName = formType.substring( lastQualifier + 1 );
611         formName = Character.toLowerCase( formName.charAt( 0 ) ) + formName.substring( 1 );
612
613         if ( moduleConfig.findFormBeanConfig( formName ) != null )
614         {
615             formName = formType.replace( '.', '_' ).replace( '$', '_' );
616             assert moduleConfig.findFormBeanConfig( formName ) == null : formName;
617         }
618         
619         return formName;
620     }
621     
622     /**
623      * Get the class name of a {@link PageFlowController}, given the URI to it.
624      *
625      * @param uri the URI to the {@link PageFlowController}, which should be relative to the
626      * web application root (i.e., it should not include the context path).
627      */

628     public static String JavaDoc getPageFlowClassName( String JavaDoc uri )
629     {
630         assert uri != null;
631         assert uri.length() > 0;
632         
633         if ( uri.charAt( 0 ) == '/' ) uri = uri.substring( 1 );
634         
635         assert FileUtils.osSensitiveEndsWith( uri, PAGEFLOW_EXTENSION ) : uri;
636         if ( FileUtils.osSensitiveEndsWith( uri, PAGEFLOW_EXTENSION ) )
637         {
638             uri = uri.substring( 0, uri.length() - PAGEFLOW_EXTENSION_LEN );
639         }
640         
641         return uri.replace( '/', '.' );
642     }
643     
644     /**
645      * Get the class name of a {@link PageFlowController}, given the URI to it.
646      *
647      * @deprecated Use {@link #getPageFlowClassName(String)} instead.
648      *
649      * @param uri the URI to the {@link PageFlowController}, which should be relative to the
650      * web application root (i.e., it should not include the context path).
651      */

652     public static String JavaDoc getJpfClassName( String JavaDoc uri )
653     {
654         return getPageFlowClassName( uri );
655     }
656     
657     /**
658      * Get the URI for a {@link PageFlowController}, given its class name.
659      *
660      * @param className the name of the {@link PageFlowController} class.
661      * @return a String that is the URI for the {@link PageFlowController}, relative to the web
662      * application root (i.e., not including the context path).
663      */

664     public static String JavaDoc getPageFlowURI( String JavaDoc className )
665     {
666         return '/' + className.replace( '.', '/' ) + PAGEFLOW_EXTENSION;
667     }
668     
669     /**
670      * @deprecated Use {@link PageFlowActionServlet#getModuleConfPath} instead.
671      *
672      * Get the path to the Struts module configration file (e.g.,
673      * "/WEB-INF/.pageflow-struts-generated/jpf-struts-config-someModule") for a given module
674      * path (e.g., "someModule"), according to the PageFlow convention.
675      *
676      * @param modulePath the Struts module path.
677      * @return a String that is the path to the Struts configuration file, relative to the
678      * web application root.
679      */

680     public static String JavaDoc getModuleConfPath( String JavaDoc modulePath )
681     {
682         return new PageFlowActionServlet.DefaultModuleConfigLocator().getModuleConfigPath( modulePath );
683     }
684     
685
686     /**
687      * Get the most recent action URI that was processed by {@link FlowController#execute}.
688      *
689      * @param request the current ServletRequest.
690      * @return a String that is the most recent action URI. This is only valid during a request
691      * that has been forwarded from the action URI.
692      */

693     public static String JavaDoc getActionURI( ServletRequest JavaDoc request )
694     {
695         return ( String JavaDoc ) request.getAttribute( ACTION_URI_ATTR );
696     }
697     
698     /**
699      * Sets the most recent action URI that was processed by {@link FlowController#execute}.
700      */

701     static void setActionURI( HttpServletRequest JavaDoc request )
702     {
703         request.setAttribute( ACTION_URI_ATTR, InternalUtils.getDecodedURI( request ) );
704     }
705     
706     /**
707      * Tell whether a web application resource requires a secure transport protocol. This is
708      * determined from web.xml; for example, the following block specifies that all resources under
709      * /login require a secure transport protocol.
710      * <pre>
711      * &lt;security-constraint&gt;
712      * &lt;web-resource-collection&gt;
713      * &lt;web-resource-name&gt;Secure PageFlow - begin&lt;/web-resource-name&gt;
714      * &lt;url-pattern&gt;/login/*&lt;/url-pattern&gt;
715      * &lt;/web-resource-collection&gt;
716      * &lt;user-data-constraint&gt;
717      * &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
718      * &lt;/user-data-constraint&gt;
719      * &lt;/security-constraint&gt;
720      * </pre>
721      *
722      * @param uri a webapp-relative URI for a resource. There must not be query parameters or a scheme
723      * on the URI.
724      * @param request the current request.
725      * @return <code>Boolean.TRUE</code> if a transport-guarantee of <code>CONFIDENTIAL</code> or
726      * <code>INTEGRAL</code> is associated with the given resource; <code>Boolean.FALSE</code>
727      * a transport-guarantee of <code>NONE</code> is associated with the given resource; or
728      * <code>null</code> if there is no transport-guarantee associated with the given resource.
729      */

730     public static SecurityProtocol getSecurityProtocol( String JavaDoc uri, ServletContext JavaDoc servletContext,
731                                                         HttpServletRequest JavaDoc request )
732     {
733         return AdapterManager.getServletContainerAdapter( servletContext ).getSecurityProtocol( uri, request );
734     }
735     
736     /**
737      * @deprecated Use {@link #getSecurityProtocol(String, ServletContext, HttpServletRequest)} instead.
738      */

739     public static Boolean JavaDoc isSecureResource( String JavaDoc uri, ServletContext JavaDoc context )
740     {
741         // TODO: once DefaultServletContainerAdapter has this functionality, delegate to it.
742
return null;
743     }
744
745     /**
746      * Set a named action output, which corresponds to an input declared by the <code>pageInput</code> JSP tag.
747      * The actual value can be read from within a JSP using the <code>"pageInput"</code> databinding context.
748      *
749      * @deprecated Use {@link #addActionOutput} instead.
750      * @param name the name of the action output.
751      * @param value the value of the action output.
752      * @param request the current ServletRequest.
753      */

754     public static void addPageInput( String JavaDoc name, Object JavaDoc value, ServletRequest JavaDoc request )
755     {
756         addActionOutput( name, value, request );
757     }
758     
759     /**
760      * Set a named action output, which corresponds to an input declared by the <code>pageInput</code> JSP tag.
761      * The actual value can be read from within a JSP using the <code>"pageInput"</code> databinding context.
762      *
763      * @param name the name of the action output.
764      * @param value the value of the action output.
765      * @param request the current ServletRequest.
766      */

767     public static void addActionOutput( String JavaDoc name, Object JavaDoc value, ServletRequest JavaDoc request )
768     {
769         Map JavaDoc map = InternalUtils.getActionOutputMap( request, true );
770         
771         if ( map.containsKey( name ) )
772         {
773             if ( _log.isWarnEnabled() )
774             {
775                 _log.warn( "Overwriting action output\"" + name + "\"." );
776             }
777         }
778         
779         map.put( name, value );
780     }
781     
782     /**
783      * Get a named action output that was registered in the current request.
784      *
785      * @deprecated Use {@link #getActionOutput} instead.
786      * @param name the name of the action output.
787      * @param request the current ServletRequest
788      * @see #addActionOutput
789      */

790     public static Object JavaDoc getPageInput( String JavaDoc name, ServletRequest JavaDoc request )
791     {
792         return getActionOutput( name, request );
793     }
794     
795     /**
796      * Get a named action output that was registered in the current request.
797      *
798      * @param name the name of the action output.
799      * @param request the current ServletRequest
800      * @see #addActionOutput
801      */

802     public static Object JavaDoc getActionOutput( String JavaDoc name, ServletRequest JavaDoc request )
803     {
804         Map JavaDoc map = InternalUtils.getActionOutputMap( request, false );
805         return map != null ? map.get( name ) : null;
806     }
807     
808     /**
809      * Add a validation error that will be shown with the Errors and Error tags.
810      * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
811      *
812      * @param propertyName the name of the property with which to associate this error.
813      * @param messageKey the message-resources key for the error message.
814      * @param messageArgs an array of arguments for the error message.
815      * @param request the current ServletRequest.
816      */

817     public static void addValidationError( String JavaDoc propertyName, String JavaDoc messageKey, Object JavaDoc[] messageArgs,
818                                            ServletRequest JavaDoc request )
819     {
820         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, messageArgs ), request );
821     }
822     
823     
824     /**
825      * Add a validation error that will be shown with the Errors and Error tags.
826      * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
827      *
828      * @param propertyName the name of the property with which to associate this error.
829      * @param messageKey the message-resources key for the error message.
830      * @param messageArg an argument for the error message.
831      * @param request the current ServletRequest.
832      */

833     public static void addValidationError( String JavaDoc propertyName, String JavaDoc messageKey, Object JavaDoc messageArg,
834                                            ServletRequest JavaDoc request )
835     {
836         addActionError( request, propertyName, messageKey, new Object JavaDoc[]{ messageArg } );
837     }
838     
839     /**
840      * Add a validation error that will be shown with the Errors and Error tags.
841      * @deprecated Use {@link #addActionError(ServletRequest, String, String, Object[])} instead.
842      *
843      * @param propertyName the name of the property with which to associate this error.
844      * @param messageKey the message-resources key for the error message.
845      * @param request the current ServletRequest.
846      */

847     public static void addValidationError( String JavaDoc propertyName, String JavaDoc messageKey, ServletRequest JavaDoc request )
848     {
849         addActionError( request, propertyName, messageKey );
850     }
851     
852     /**
853      * Add a property-related message that will be shown with the Errors and Error tags.
854      *
855      * @param request the current ServletRequest.
856      * @param propertyName the name of the property with which to associate this error.
857      * @param messageKey the message-resources key for the message.
858      * @param messageArgs zero or more arguments to the message.
859      */

860     public static void addActionError( ServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc messageKey,
861                                        Object JavaDoc[] messageArgs )
862     {
863         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, messageArgs ), request );
864     }
865     
866     /**
867      * Add a property-related message that will be shown with the Errors and Error tags.
868      *
869      * @param request the current ServletRequest.
870      * @param propertyName the name of the property with which to associate this error.
871      * @param messageKey the message-resources key for the message.
872      */

873     public static void addActionError( ServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc messageKey )
874     {
875         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, null ), request );
876     }
877     
878     /**
879      * Add a property-related message that will be shown with the Errors and Error tags.
880      *
881      * @param request the current ServletRequest.
882      * @param propertyName the name of the property with which to associate this error.
883      * @param messageKey the message-resources key for the message.
884      * @param messageArg an argument to the message
885      */

886     public static void addActionError( ServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc messageKey,
887                                        Object JavaDoc messageArg )
888     {
889         Object JavaDoc[] messageArgs = new Object JavaDoc[]{ messageArg };
890         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, messageArgs ), request );
891     }
892     
893     /**
894      * Add a property-related message that will be shown with the Errors and Error tags.
895      *
896      * @param request the current ServletRequest.
897      * @param propertyName the name of the property with which to associate this error.
898      * @param messageKey the message-resources key for the message.
899      * @param messageArg1 the first argument to the message
900      * @param messageArg2 the second argument to the message
901      */

902     public static void addActionError( ServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc messageKey,
903                                        Object JavaDoc messageArg1, Object JavaDoc messageArg2 )
904     {
905         Object JavaDoc[] messageArgs = new Object JavaDoc[]{ messageArg1, messageArg2 };
906         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, messageArgs ), request );
907     }
908     
909     /**
910      * Add a property-related message that will be shown with the Errors and Error tags.
911      *
912      * @param request the current ServletRequest.
913      * @param propertyName the name of the property with which to associate this error.
914      * @param messageKey the message-resources key for the message.
915      * @param messageArg1 the first argument to the message
916      * @param messageArg2 the second argument to the message
917      * @param messageArg3 the third argument to the message
918      */

919     public static void addActionError( ServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc messageKey,
920                                        Object JavaDoc messageArg1, Object JavaDoc messageArg2, Object JavaDoc messageArg3 )
921     {
922         Object JavaDoc[] messageArgs = new Object JavaDoc[]{ messageArg1, messageArg2, messageArg3 };
923         InternalUtils.addActionError( propertyName, new ActionMessage( messageKey, messageArgs ), request );
924     }
925     
926     /**
927      * Add a property-related message as an expression that will be evaluated and shown with the Errors and Error tags.
928      *
929      * @param request the current ServletRequest.
930      * @param propertyName the name of the property with which to associate this error.
931      * @param expression the expression that will be evaluated to generate the error message.
932      * @param messageArgs zero or more arguments to the message.
933      */

934     public static void addActionErrorExpression( HttpServletRequest JavaDoc request, String JavaDoc propertyName, String JavaDoc expression,
935                                                  Object JavaDoc[] messageArgs )
936     {
937         ExpressionMessage msg = new ExpressionMessage( expression, messageArgs );
938         InternalUtils.addActionError( propertyName, msg, request );
939     }
940     
941     /**
942      * Resolve the given action to a URI by running an entire request-processing cycle on the given ScopedRequest
943      * and ScopedResponse.
944      * @exclude
945      *
946      * @param context the current ServletContext
947      * @param request the ServletRequest, which must be a {@link ScopedRequest}.
948      * @param response the ServletResponse, which must be a {@link ScopedResponse}.
949      * @param actionOverride if not <code>null</code>, this qualified action-path is used to construct an action
950      * URI which is set as the request URI. The action-path <strong>must</strong> begin with '/',
951      * which makes it qualified from the webapp root.
952      * @param autoResolveExtensions a list of URI extensions (e.g., ".do", ".jpf") that will be auto-resolved, i.e.,
953      * on which this method will be recursively called. If <code>null</code>, the
954      * default extensions ".do" and ".jpf" will be used.
955      */

956     public static ActionResult strutsLookup( ServletContext JavaDoc context, ServletRequest JavaDoc request,
957                                              HttpServletResponse JavaDoc response, String JavaDoc actionOverride,
958                                              String JavaDoc[] autoResolveExtensions )
959         throws Exception JavaDoc
960     {
961         ScopedRequest scopedRequest = ScopedServletUtils.unwrapRequest( request );
962         ScopedResponse scopedResponse = ScopedServletUtils.unwrapResponse( response );
963         assert scopedRequest != null : request.getClass().getName();
964         assert scopedResponse != null : response.getClass().getName();
965         assert request instanceof HttpServletRequest JavaDoc : request.getClass().getName();
966         
967         if ( scopedRequest == null )
968         {
969             throw new IllegalArgumentException JavaDoc( "request must be of type " + ScopedRequest.class.getName() );
970         }
971         if ( scopedResponse == null )
972         {
973             throw new IllegalArgumentException JavaDoc( "response must be of type " + ScopedResponse.class.getName() );
974         }
975         
976         ActionServlet as = InternalUtils.getActionServlet( context );
977         
978         if ( as == null )
979         {
980             _log.error( "There is no initialized ActionServlet. The ActionServlet must be set to load-on-startup." );
981             return null;
982         }
983         
984         if ( actionOverride != null )
985         {
986             // The action must be fully-qualified with its module path.
987
assert actionOverride.charAt( 0 ) == '/' : actionOverride;
988             InternalStringBuilder uri = new InternalStringBuilder( scopedRequest.getContextPath() );
989             uri.append( actionOverride );
990             uri.append( PageFlowConstants.ACTION_EXTENSION );
991             scopedRequest.setRequestURI( uri.toString() );
992         }
993
994         //
995
// In case the request was already forwarded once, clear out the recorded forwarded-URI. This
996
// will allow us to tell whether processing the request actually forwarded somewhere.
997
//
998
scopedRequest.setForwardedURI( null );
999         
1000        //
1001
// Now process the request. We create a PageFlowRequestWrapper for pageflow-specific request-scoped info.
1002
//
1003
PageFlowRequestWrapper wrappedRequest = PageFlowRequestWrapper.wrapRequest( ( HttpServletRequest JavaDoc ) request );
1004        as.doGet( wrappedRequest, scopedResponse ); // this just calls process() -- same as doPost()
1005

1006        String JavaDoc returnURI;
1007
1008        if ( ! scopedResponse.didRedirect() )
1009        {
1010            returnURI = scopedRequest.getForwardedURI();
1011            
1012            if ( autoResolveExtensions == null )
1013            {
1014                autoResolveExtensions = DEFAULT_AUTORESOLVE_EXTENSIONS;
1015            }
1016            
1017            if ( returnURI != null )
1018            {
1019                for ( int i = 0; i < autoResolveExtensions.length; ++i )
1020                {
1021                    if ( FileUtils.uriEndsWith( returnURI, autoResolveExtensions[i] ) )
1022                    {
1023                        scopedRequest.doForward();
1024                        return strutsLookup( context, wrappedRequest, scopedResponse, null, autoResolveExtensions );
1025                    }
1026                }
1027            }
1028        }
1029        else
1030        {
1031            returnURI = scopedResponse.getRedirectURI();
1032        }
1033        
1034        if ( returnURI != null )
1035        {
1036            return new ActionResultImpl( returnURI, scopedResponse.didRedirect(), scopedResponse.getStatusCode(),
1037                                         scopedResponse.getStatusMessage(), scopedResponse.isError() );
1038        }
1039        else
1040        {
1041            return null;
1042        }
1043    }
1044    
1045    /**
1046     * If the given request is a MultipartRequestWrapper (Struts class that doesn't extend
1047     * HttpServletRequestWrapper), return the wrapped request; otherwise, return the given request.
1048     * @exclude
1049     */

1050    public static HttpServletRequest JavaDoc unwrapMultipart( HttpServletRequest JavaDoc request )
1051    {
1052        if ( request instanceof MultipartRequestWrapper )
1053        {
1054            request = ( ( MultipartRequestWrapper ) request ).getRequest();
1055        }
1056        
1057        return request;
1058    }
1059    
1060    /**
1061     * Get or create the current {@link GlobalApp} instance.
1062     * @deprecated Use {@link #getGlobalApp} instead.
1063     *
1064     * @param request the current HttpServletRequest.
1065     * @param response the current HttpServletResponse
1066     * @return the current {@link GlobalApp} from the user session, or a newly-instantiated one
1067     * (based on the user's Global.app file) if none was in the session. Failing that,
1068     * return <code>null</code>.
1069     */

1070    public static GlobalApp ensureGlobalApp( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
1071    {
1072        ServletContext JavaDoc servletContext = InternalUtils.getServletContext( request );
1073        return ensureGlobalApp( request, response, servletContext );
1074    }
1075    
1076    /**
1077     * Get or create the current {@link GlobalApp} instance.
1078     * @deprecated Use {@link #getSharedFlow} instead.
1079     *
1080     * @param request the current HttpServletRequest.
1081     * @param response the current HttpServletResponse
1082     * @return the current {@link GlobalApp} from the user session, or a newly-instantiated one
1083     * (based on the user's Global.app file) if none was in the session. Failing that,
1084     * return <code>null</code>.
1085     */

1086    public static GlobalApp ensureGlobalApp( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1087                                             ServletContext JavaDoc servletContext )
1088    {
1089        GlobalApp ga = getGlobalApp( request );
1090        
1091        if ( ga != null )
1092        {
1093            ga.reinitialize( request, response, servletContext );
1094        }
1095        else
1096        {
1097            ga = FlowControllerFactory.getGlobalApp( request, response, servletContext );
1098        }
1099        
1100        return ga;
1101    }
1102    
1103    /**
1104     * @deprecated This is an internal utility. {@link InternalUtils#getBindingUpdateErrors} can be used, but it is
1105     * not guaranteed to be supported in the future.
1106     */

1107    public static Map JavaDoc getBindingUpdateErrors( ServletRequest JavaDoc request )
1108    {
1109        return InternalUtils.getBindingUpdateErrors( request );
1110    }
1111    
1112    /**
1113     * @deprecated This is an internal utility. {@link InternalUtils#ensureModuleConfig} can be used, but it is
1114     * not guaranteed to be supported in the future.
1115     */

1116    public static ModuleConfig ensureModuleConfig( String JavaDoc modulePath, ServletRequest JavaDoc request, ServletContext JavaDoc context )
1117    {
1118        return InternalUtils.ensureModuleConfig( modulePath, request, context );
1119    }
1120    
1121    /**
1122     * @deprecated This will be removed with no replacement in a future release.
1123     */

1124    public static ModuleConfig getGlobalAppConfig( ServletContext JavaDoc servletContext )
1125    {
1126        return InternalUtils.getModuleConfig( GLOBALAPP_MODULE_CONTEXT_PATH, servletContext );
1127    }
1128    
1129    /**
1130     * @deprecated This is an internal utility. {@link InternalUtils#getModuleConfig} can be used, but it is
1131     * not guaranteed to be supported in the future.
1132     */

1133    public static ModuleConfig getModuleConfig( String JavaDoc modulePath, ServletContext JavaDoc context )
1134    {
1135        return InternalUtils.getModuleConfig( modulePath, context );
1136    }
1137    
1138    /**
1139     * Get the file extension from a file name.
1140     * @deprecated Use {@link FileUtils#getFileExtension} instead.
1141     *
1142     * @param filename the file name.
1143     * @return the file extension (everything after the last '.'), or the empty string if there is no file extension.
1144     */

1145    public static String JavaDoc getFileExtension( String JavaDoc filename )
1146    {
1147        return FileUtils.getFileExtension( filename );
1148    }
1149    
1150    /**
1151     * @deprecated This is an internal utility. {@link InternalUtils#getFlowControllerClassName} can be used, but it is
1152     * not guaranteed to be supported in the future.
1153     */

1154    public static String JavaDoc getPageFlowClassName( String JavaDoc modulePath, ServletRequest JavaDoc request, ServletContext JavaDoc context )
1155    {
1156        return InternalUtils.getFlowControllerClassName( modulePath, request, context );
1157    }
1158    
1159    /**
1160     * @deprecated This method no longer has any effect, and will be removed without replacement in a future release.
1161     */

1162    public static boolean ensureAppDeployment( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
1163                                               ServletContext JavaDoc servletContext )
1164    {
1165        return false;
1166    }
1167    
1168    /**
1169     * Tell whether a given URI is absolute, i.e., whether it contains a scheme-part (e.g., "http:").
1170     * @deprecated Use {@link FileUtils#isAbsoluteURI} instead.
1171     *
1172     * @param uri the URI to test.
1173     * @return <code>true</code> if the given URI is absolute.
1174     */

1175    public static boolean isAbsoluteURI( String JavaDoc uri )
1176    {
1177        return FileUtils.isAbsoluteURI( uri );
1178    }
1179    
1180    /**
1181     * @deprecated Use {@link #getCurrentPageFlow} instead.
1182     */

1183    public static final PageFlowController ensureCurrentPageFlow( HttpServletRequest JavaDoc request,
1184                                                                  HttpServletResponse JavaDoc response,
1185                                                                  ServletContext JavaDoc servletContext )
1186    {
1187        try
1188        {
1189            FlowControllerFactory factory = FlowControllerFactory.get( servletContext );
1190            return factory.getPageFlowForRequest( new RequestContext( request, response ) );
1191        }
1192        catch ( InstantiationException JavaDoc e )
1193        {
1194            _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
1195        }
1196        catch ( IllegalAccessException JavaDoc e )
1197        {
1198            _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e );
1199        }
1200        
1201        return null;
1202    }
1203    
1204    /**
1205     * @deprecated Use {@link #getCurrentPageFlow} instead.
1206     */

1207    public static final PageFlowController ensureCurrentPageFlow( HttpServletRequest JavaDoc request,
1208                                                                  HttpServletResponse JavaDoc response )
1209    {
1210        ServletContext JavaDoc servletContext = InternalUtils.getServletContext( request );
1211        
1212        if ( servletContext == null && _log.isWarnEnabled() )
1213        {
1214            _log.warn( "could not get ServletContext from request " + request );
1215        }
1216        
1217        return ensureCurrentPageFlow( request, response, servletContext );
1218    }
1219    
1220    /**
1221     * @deprecated This is an internal utility. {@link InternalUtils#addBindingUpdateError} can be used, but it is
1222     * not guaranteed to be supported in the future.
1223     */

1224    public static void addBindingUpdateError( ServletRequest JavaDoc request, String JavaDoc expression, String JavaDoc message, Throwable JavaDoc e )
1225    {
1226        InternalUtils.addBindingUpdateError( request, expression, message, e );
1227    }
1228    
1229    /**
1230     * @deprecated This is an internal utility. {@link ServletUtils#dumpRequest} can be used, but it is
1231     * not guaranteed to be supported in the future.
1232     */

1233    public static void dumpRequest( HttpServletRequest JavaDoc request, PrintStream JavaDoc output )
1234    {
1235        ServletUtils.dumpRequest( request, output );
1236    }
1237    
1238    /**
1239     * @deprecated This is an internal utility. {@link ServletUtils#dumpServletContext} can be used, but it is
1240     * not guaranteed to be supported in the future.
1241     */

1242    public static void dumpServletContext( ServletContext JavaDoc context, PrintStream JavaDoc output )
1243    {
1244        ServletUtils.dumpServletContext( context, output );
1245    }
1246    
1247    /**
1248     * @deprecated Use {@link ServletUtils#preventCache} instead.
1249     */

1250    public static void preventCache( HttpServletResponse JavaDoc response )
1251    {
1252        ServletUtils.preventCache( response );
1253    }
1254    
1255    /**
1256     * @deprecated This is an internal utility. {@link InternalUtils#setCurrentActionResolver} can be used, but it is
1257     * not guaranteed to be supported in the future.
1258     */

1259    public static void setCurrentActionResolver( ActionResolver resolver, HttpServletRequest JavaDoc request )
1260    {
1261        InternalUtils.setCurrentActionResolver( resolver, request );
1262    }
1263
1264    /**
1265     * Create a raw action URI, which can be modified before being sent through the registered URL rewriting chain
1266     * using {@link URLRewriterService#rewriteURL}. Use {@link #getRewrittenActionURI} to get a fully-rewritten URI.
1267     *
1268     * @param servletContext the current ServletContext.
1269     * @param request the current HttpServletRequest.
1270     * @param response the current HttpServletResponse.
1271     * @param actionName the action name to convert into a MutableURI; may be qualified with a path from the webapp
1272     * root, in which case the parent directory from the current request is <i>not</i> used.
1273     * @return a MutableURI for the given action, suitable for URL rewriting.
1274     * @throws URISyntaxException if there is a problem converting the action URI (derived from processing the given
1275     * action name) into a MutableURI.
1276     */

1277    public static MutableURI getActionURI( ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request,
1278                                           HttpServletResponse JavaDoc response, String JavaDoc actionName )
1279            throws URISyntaxException JavaDoc
1280    {
1281        if ( actionName.length() < 1 ) throw new IllegalArgumentException JavaDoc( "actionName must be non-empty" );
1282        
1283        InternalStringBuilder actionURI = new InternalStringBuilder( request.getContextPath() );
1284        
1285        if ( actionName.charAt( 0 ) != '/' )
1286        {
1287            actionURI.append( getModulePath( request ) );
1288            actionURI.append( '/' );
1289        }
1290        
1291        actionURI.append( actionName );
1292        if ( ! actionName.endsWith( ACTION_EXTENSION ) ) actionURI.append( ACTION_EXTENSION );
1293        
1294        FreezableMutableURI uri = new FreezableMutableURI();
1295        uri.setEncoding( response.getCharacterEncoding() );
1296        uri.setURI( actionURI.toString(), true );
1297        return uri;
1298    }
1299    
1300    /**
1301     * Create a fully-rewritten URI given an action name and parameters.
1302     *
1303     * @param servletContext the current ServletContext.
1304     * @param request the current HttpServletRequest.
1305     * @param response the current HttpServletResponse.
1306     * @param actionName the action name to convert into a fully-rewritten URI; may be qualified with a path from the
1307     * webapp root, in which case the parent directory from the current request is <i>not</i> used.
1308     * @param params the additional parameters to include in the URI query.
1309     * @param fragment the fragment (anchor or location) for this url.
1310     * @param forXML flag indicating that the query of the uri should be written
1311     * using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1312     * @return a fully-rewritten URI for the given action.
1313     * @throws URISyntaxException if there is a problem converting the action URI (derived
1314     * from processing the given action name) into a MutableURI.
1315     */

1316    public static String JavaDoc getRewrittenActionURI( ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request,
1317                                                HttpServletResponse JavaDoc response, String JavaDoc actionName, Map JavaDoc params,
1318                                                String JavaDoc fragment, boolean forXML )
1319            throws URISyntaxException JavaDoc
1320    {
1321        MutableURI uri = getActionURI( servletContext, request, response, actionName );
1322        if ( params != null ) uri.addParameters( params, false );
1323        if ( fragment != null ) uri.setFragment( uri.encode( fragment ) );
1324
1325        boolean needsToBeSecure = needsToBeSecure( servletContext, request, uri.getPath(), true );
1326        URLRewriterService.rewriteURL( servletContext, request, response, uri, URLType.ACTION, needsToBeSecure );
1327        String JavaDoc key = getURLTemplateKey( URLType.ACTION, needsToBeSecure );
1328        URIContext uriContext = URIContextFactory.getInstance( forXML );
1329
1330        return URLRewriterService.getTemplatedURL( request, uri, key, uriContext );
1331    }
1332
1333    /**
1334     * Create a fully-rewritten URI given a path and parameters.
1335     *
1336     * <p> Calls the rewriter service using a type of {@link URLType#RESOURCE}. </p>
1337     *
1338     * @param servletContext the current ServletContext.
1339     * @param request the current HttpServletRequest.
1340     * @param response the current HttpServletResponse.
1341     * @param path the path to process into a fully-rewritten URI.
1342     * @param params the additional parameters to include in the URI query.
1343     * @param fragment the fragment (anchor or location) for this URI.
1344     * @param forXML flag indicating that the query of the uri should be written
1345     * using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1346     * @return a fully-rewritten URI for the given action.
1347     * @throws URISyntaxException if there's a problem converting the action URI (derived
1348     * from processing the given action name) into a MutableURI.
1349     */

1350    public static String JavaDoc getRewrittenResourceURI( ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request,
1351                                                  HttpServletResponse JavaDoc response, String JavaDoc path, Map JavaDoc params,
1352                                                  String JavaDoc fragment, boolean forXML )
1353            throws URISyntaxException JavaDoc
1354    {
1355        return rewriteResourceOrHrefURL( servletContext, request, response, path, params, fragment, forXML, URLType.RESOURCE );
1356    }
1357
1358    /**
1359     * Create a fully-rewritten URI given a path and parameters.
1360     *
1361     * <p> Calls the rewriter service using a type of {@link URLType#ACTION}. </p>
1362     *
1363     * @param servletContext the current ServletContext.
1364     * @param request the current HttpServletRequest.
1365     * @param response the current HttpServletResponse.
1366     * @param path the path to process into a fully-rewritten URI.
1367     * @param params the additional parameters to include in the URI query.
1368     * @param fragment the fragment (anchor or location) for this URI.
1369     * @param forXML flag indicating that the query of the uri should be written
1370     * using the &quot;&amp;amp;&quot; entity, rather than the character, '&amp;'.
1371     * @return a fully-rewritten URI for the given action.
1372     * @throws URISyntaxException if there's a problem converting the action URI (derived
1373     * from processing the given action name) into a MutableURI.
1374     */

1375    public static String JavaDoc getRewrittenHrefURI( ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request,
1376                                              HttpServletResponse JavaDoc response, String JavaDoc path, Map JavaDoc params,
1377                                              String JavaDoc fragment, boolean forXML )
1378            throws URISyntaxException JavaDoc
1379    {
1380        return rewriteResourceOrHrefURL( servletContext, request, response, path, params, fragment, forXML, URLType.ACTION );
1381    }
1382
1383    private static String JavaDoc rewriteResourceOrHrefURL( ServletContext JavaDoc servletContext, HttpServletRequest JavaDoc request,
1384                                                    HttpServletResponse JavaDoc response, String JavaDoc path, Map JavaDoc params,
1385                                                    String JavaDoc fragment, boolean forXML, URLType urlType )
1386            throws URISyntaxException JavaDoc
1387    {
1388        boolean encoded = false;
1389        UrlConfig urlConfig = ConfigUtil.getConfig().getUrlConfig();
1390
1391        if (urlConfig != null && urlConfig.isSetUrlEncodeUrls()) {
1392            encoded = !urlConfig.getUrlEncodeUrls();
1393        }
1394
1395        FreezableMutableURI uri = new FreezableMutableURI();
1396        uri.setEncoding( response.getCharacterEncoding() );
1397        uri.setURI( path, encoded );
1398
1399        if ( params != null )
1400        {
1401            uri.addParameters( params, false );
1402        }
1403
1404        if ( fragment != null )
1405        {
1406            uri.setFragment( uri.encode( fragment ) );
1407        }
1408
1409        URIContext uriContext = URIContextFactory.getInstance( forXML );
1410        if ( uri.isAbsolute() )
1411        {
1412            return uri.getURIString( uriContext );
1413        }
1414
1415        if ( path.length() != 0 && path.charAt( 0 ) != '/' )
1416        {
1417            String JavaDoc reqUri = request.getRequestURI();
1418            String JavaDoc reqPath = reqUri.substring( 0, reqUri.lastIndexOf( '/' ) + 1 );
1419            uri.setPath( reqPath + uri.getPath() );
1420        }
1421
1422        boolean needsToBeSecure = needsToBeSecure( servletContext, request, uri.getPath(), true );
1423        URLRewriterService.rewriteURL( servletContext, request, response, uri, urlType, needsToBeSecure );
1424        String JavaDoc key = getURLTemplateKey( urlType, needsToBeSecure );
1425
1426        return URLRewriterService.getTemplatedURL( request, uri, key, uriContext );
1427    }
1428
1429    /**
1430     * Tell whether a given URI should be written to be secure.
1431     * @param context the current ServletContext.
1432     * @param request the current HttpServletRequest.
1433     * @param uri the URI to check.
1434     * @param stripContextPath if <code>true</code>, strip the webapp context path from the URI before
1435     * processing it.
1436     * @return <code>true</code> when:
1437     * <ul>
1438     * <li>the given URI is configured in the deployment descriptor to be secure (according to
1439     * {@link SecurityProtocol}), or
1440     * <li>the given URI is not configured in the deployment descriptor, and the current request
1441     * is secure ({@link HttpServletRequest#isSecure} returns
1442     * <code>true</code>).
1443     * </ul>
1444     * <code>false</code> when:
1445     * <ul>
1446     * <li>the given URI is configured explicitly in the deployment descriptor to be unsecure
1447     * (according to {@link SecurityProtocol}), or
1448     * <li>the given URI is not configured in the deployment descriptor, and the current request
1449     * is unsecure ({@link HttpServletRequest#isSecure} returns
1450     * <code>false</code>).
1451     * </ul>
1452     */

1453    public static boolean needsToBeSecure(ServletContext JavaDoc context, ServletRequest JavaDoc request,
1454                                          String JavaDoc uri, boolean stripContextPath)
1455    {
1456        // Get the web-app relative path for security check
1457
String JavaDoc secureCheck = uri;
1458        if (stripContextPath) {
1459            String JavaDoc contextPath = ((HttpServletRequest JavaDoc) request).getContextPath();
1460            if (secureCheck.startsWith(contextPath)) {
1461                secureCheck = secureCheck.substring(contextPath.length());
1462            }
1463        }
1464
1465        boolean secure = false;
1466        if (secureCheck.indexOf('?') > -1) {
1467            secureCheck = secureCheck.substring(0, secureCheck.indexOf('?'));
1468        }
1469
1470        SecurityProtocol sp = getSecurityProtocol(secureCheck, context, (HttpServletRequest JavaDoc) request);
1471        if (sp.equals(SecurityProtocol.UNSPECIFIED)) {
1472            secure = request.isSecure();
1473        }
1474        else {
1475            secure = sp.equals(SecurityProtocol.SECURE);
1476        }
1477
1478        return secure;
1479    }
1480
1481    /**
1482     * Returns a key for the URL template type given the URL type and a
1483     * flag indicating a secure URL or not.
1484     *
1485     * @param urlType the type of URL (ACTION, RESOURCE).
1486     * @param needsToBeSecure indicates that the template should be for a secure URL.
1487     * @return the key/type of template to use.
1488     */

1489    public static String JavaDoc getURLTemplateKey( URLType urlType, boolean needsToBeSecure )
1490    {
1491        String JavaDoc key = URLTemplateDescriptor.ACTION_TEMPLATE;
1492        if ( urlType.equals( URLType.ACTION ) )
1493        {
1494            if ( needsToBeSecure )
1495            {
1496                key = URLTemplateDescriptor.SECURE_ACTION_TEMPLATE;
1497            }
1498            else
1499            {
1500                key = URLTemplateDescriptor.ACTION_TEMPLATE;
1501            }
1502        }
1503        else if ( urlType.equals( URLType.RESOURCE ) )
1504        {
1505            if ( needsToBeSecure )
1506            {
1507                key = URLTemplateDescriptor.SECURE_RESOURCE_TEMPLATE;
1508            }
1509            else
1510            {
1511                key = URLTemplateDescriptor.RESOURCE_TEMPLATE;
1512            }
1513        }
1514
1515        return key;
1516    }
1517}
1518
Popular Tags