KickJava   Java API By Example, From Geeks To Geeks.

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


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.pageflow.internal.InternalConstants;
23 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
24 import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper;
25 import org.apache.beehive.netui.util.Bundle;
26 import org.apache.beehive.netui.util.internal.DiscoveryUtils;
27 import org.apache.beehive.netui.util.config.ConfigUtil;
28 import org.apache.beehive.netui.util.config.bean.ModuleConfigLocators;
29 import org.apache.beehive.netui.util.config.bean.PageflowConfig;
30 import org.apache.beehive.netui.util.logging.Logger;
31 import org.apache.commons.digester.Digester;
32 import org.apache.struts.Globals;
33 import org.apache.struts.action.ActionServlet;
34 import org.apache.struts.action.DynaActionFormClass;
35 import org.apache.struts.action.RequestProcessor;
36 import org.apache.struts.config.ControllerConfig;
37 import org.apache.struts.config.FormBeanConfig;
38 import org.apache.struts.config.MessageResourcesConfig;
39 import org.apache.struts.config.ModuleConfig;
40 import org.apache.struts.config.ModuleConfigFactory;
41 import org.apache.struts.config.impl.ModuleConfigImpl;
42 import org.apache.struts.util.RequestUtils;
43 import org.xml.sax.InputSource JavaDoc;
44
45 import javax.servlet.ServletConfig JavaDoc;
46 import javax.servlet.ServletContext JavaDoc;
47 import javax.servlet.ServletException JavaDoc;
48 import javax.servlet.ServletRequest JavaDoc;
49 import javax.servlet.ServletResponse JavaDoc;
50 import javax.servlet.UnavailableException JavaDoc;
51 import javax.servlet.http.HttpServletRequest JavaDoc;
52 import javax.servlet.http.HttpServletResponse JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.io.InputStream JavaDoc;
55 import java.io.ObjectInputStream JavaDoc;
56 import java.io.ObjectOutputStream JavaDoc;
57 import java.net.MalformedURLException JavaDoc;
58 import java.net.URL JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.Collections JavaDoc;
61 import java.util.Enumeration JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.Map JavaDoc;
64 import java.util.Iterator JavaDoc;
65
66 import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
67
68
69 /**
70  * ActionServlet that automatically registers requested Struts modules based on a set of module configuration file
71  * locators. The user may specify {@link ModuleConfigLocator} classes in /WEB-INF/beehive-netui-config.xml using the
72  * <code>&lt;module-config-locators&gt;</code> element.
73  */

74 public class AutoRegisterActionServlet extends ActionServlet
75 {
76     /**
77      * @deprecated To register {@link ModuleConfigLocator}s, use the <code>module-config-locators</code> element
78      * in <code>pageflow-config</code> of /WEB-INF/netui-config.xml.
79      */

80     public static String JavaDoc MODULE_CONFIG_LOCATOR_CLASS_ATTR = "moduleConfigLocators";
81     
82     /** Map of module-path to ModuleConfig */
83     private Map JavaDoc/*< String, ModuleConfig >*/ _registeredModules = new InternalConcurrentHashMap/*< String, ModuleConfig >*/();
84     private transient Digester _cachedConfigDigester = null;
85     private Map JavaDoc _configParams = null;
86     private ModuleConfigLocator[] _moduleConfigLocators = null;
87     
88     private static final Logger _log = Logger.getInstance( AutoRegisterActionServlet.class );
89
90     private static final ModuleConfig NONEXISTANT_MODULE_CONFIG = new NonexistantModuleConfig();
91     
92     
93     public void init()
94         throws ServletException JavaDoc
95     {
96         super.init();
97         setupModuleConfigLocators();
98     }
99     
100     private void setupModuleConfigLocators()
101     {
102         ModuleConfigLocator[] defaultLocators = getDefaultModuleConfigLocators();
103         ArrayList JavaDoc/*< ModuleConfigLocator >*/ locators = new ArrayList JavaDoc/*< ModuleConfigLocator >*/();
104         
105         for ( int i =0; i < defaultLocators.length; ++i )
106         {
107             locators.add( defaultLocators[i] );
108         }
109         
110         //
111
// Look for ModuleConfigLocators in netui-config.xml.
112
//
113
PageflowConfig pfConfig = ConfigUtil.getConfig().getPageflowConfig();
114         
115         if ( pfConfig != null )
116         {
117             ModuleConfigLocators mcLocators = pfConfig.getModuleConfigLocators();
118             
119             if ( mcLocators != null )
120             {
121                 ModuleConfigLocators.ModuleConfigLocator[] array = mcLocators.getModuleConfigLocatorArray();
122                 
123                 for ( int i = 0; i < array.length; i++ )
124                 {
125                     addModuleConfigLocator( array[i].getLocatorClass().trim(), locators );
126                 }
127             }
128         }
129         
130         //
131
// Look for ModuleConfigLocators specified in web.xml (deprecated method for specifying them).
132
//
133
String JavaDoc configLocatorList = getServletConfig().getInitParameter( MODULE_CONFIG_LOCATOR_CLASS_ATTR );
134         
135         if ( configLocatorList != null )
136         {
137             if ( _log.isWarnEnabled() )
138             {
139                 _log.warn( "Found module-config-locators list in context-parameter " + MODULE_CONFIG_LOCATOR_CLASS_ATTR
140                            + ", which is deprecated. Please use the <module-config-locators> element in "
141                            + InternalConstants.NETUI_CONFIG_PATH + " instead." );
142             }
143             
144             String JavaDoc[] configLocatorClassNames = configLocatorList.split( "," );
145             
146             for ( int i = 0; i < configLocatorClassNames.length; ++i )
147             {
148                 addModuleConfigLocator( configLocatorClassNames[i].trim(), locators );
149             }
150         }
151         
152         _moduleConfigLocators = ( ModuleConfigLocator[] ) locators.toArray( new ModuleConfigLocator[locators.size()] );
153     }
154     
155     private static void addModuleConfigLocator( String JavaDoc locatorClassName, ArrayList JavaDoc/*< ModuleConfigLocator >*/ locators )
156     {
157         try
158         {
159             Class JavaDoc locatorClass = DiscoveryUtils.loadImplementorClass( locatorClassName, ModuleConfigLocator.class );
160             
161             if ( locatorClass != null ) // previous call will log an error if it can't find the class
162
{
163                 ModuleConfigLocator locator = ( ModuleConfigLocator ) locatorClass.newInstance();
164                 locators.add( locator );
165             }
166         }
167         catch ( IllegalAccessException JavaDoc e )
168         {
169             _log.error( "Could not create an instance of specified module-config-locator " + locatorClassName, e );
170         }
171         catch ( InstantiationException JavaDoc e )
172         {
173             _log.error( "Could not create an instance of specified module-config-locator " + locatorClassName, e );
174         }
175     }
176     
177     /**
178      * Get the base list of ModuleConfigLocators, to specify locations for auto-registered Struts modules. By default,
179      * this list is empty; derived classes may override to provide locators, or the user may specify them using
180      * the "moduleConfigLocators" init-parameter. When an unrecognized Struts module is requested, each registered
181      * ModuleConfigLocator is queried for a possible path to the configuration file for the module. If the
182      * configuration file is found, the module is auto-registered against the file.
183      */

184     protected ModuleConfigLocator[] getDefaultModuleConfigLocators()
185     {
186         return new ModuleConfigLocator[0];
187     }
188     
189     /**
190      * Get the current list of registered ModuleConfigLocators.
191      *
192      * @return an array of registered ModuleConfigLocators.
193      * @see #getDefaultModuleConfigLocators
194      */

195     public ModuleConfigLocator[] getModuleConfigLocators()
196     {
197         return _moduleConfigLocators;
198     }
199     
200     /**
201      * Interface for specifying alternate locations for auto-registered Struts modules.
202      *
203      * @see AutoRegisterActionServlet#getDefaultModuleConfigLocators
204      */

205     public static interface ModuleConfigLocator
206     {
207         /**
208          * Get the webapp-relative path to a Struts module config file, based on the module name.
209          *
210          * @param moduleName the name of the Struts module, e.g., "someModule" or "some/other/module".
211          * @return the webapp-relative path the the Struts module config file.
212          */

213         public String JavaDoc getModuleConfigPath( String JavaDoc moduleName );
214     }
215     
216     /**
217      * Get the webapp-relative path to the Struts module configration file for a given module path,
218      * based on registered ModuleConfigLocators.
219      *
220      * @param modulePath the Struts module path.
221      * @return a String that is the path to the Struts configuration file, relative to the web application root,
222      * or <code>null</code> if no appropriate configuration file is found.
223      * @see #getDefaultModuleConfigLocators
224      */

225     public String JavaDoc getModuleConfPath( String JavaDoc modulePath )
226     {
227         if ( _moduleConfigLocators != null )
228         {
229             for ( int i = 0; i < _moduleConfigLocators.length; ++i )
230             {
231                 ModuleConfigLocator locator = _moduleConfigLocators[i];
232                 String JavaDoc moduleConfigPath = locator.getModuleConfigPath( modulePath );
233                 
234                 try
235                 {
236                     if ( getConfigResource( moduleConfigPath ) != null ) return moduleConfigPath;
237                 }
238                 catch ( MalformedURLException JavaDoc e )
239                 {
240                     _log.error( "ModuleConfigLocator " + locator.getClass().getName()
241                                 + " returned an invalid path: " + moduleConfigPath + '.', e );
242                 }
243             }
244         }
245         
246         return null;
247     }
248     
249     private boolean isAutoLoadModulePath( String JavaDoc modulePath, String JavaDoc prefix )
250     {
251         if ( _moduleConfigLocators != null )
252         {
253             for ( int i = 0; i < _moduleConfigLocators.length; ++i )
254             {
255                 ModuleConfigLocator locator = _moduleConfigLocators[i];
256                 if ( modulePath.equals( locator.getModuleConfigPath( prefix ) ) ) return true;
257             }
258         }
259         
260         return false;
261     }
262     
263     //
264
// For cases where the servlet is serialized/deserialized, we'll hold onto ServletConfig
265
// attributes, since the ServletConfig reference is transient. Then, we'll return these
266
// cached values if necessary in getInitParameter(), getInitParameterNames().
267
//
268
private void writeObject( ObjectOutputStream JavaDoc stream )
269         throws IOException JavaDoc
270     {
271         if ( _log.isInfoEnabled() )
272         {
273             _log.info( "serializing ActionServlet " + this );
274         }
275         
276         if ( _configParams != null )
277         {
278             stream.writeObject( _configParams );
279         }
280         else
281         {
282             ServletConfig JavaDoc servletConfig = getServletConfig();
283             assert servletConfig != null;
284             HashMap JavaDoc params = new HashMap JavaDoc();
285             
286             for ( Enumeration JavaDoc e = servletConfig.getInitParameterNames(); e.hasMoreElements(); )
287             {
288                 String JavaDoc name = ( String JavaDoc ) e.nextElement();
289                 params.put( name, servletConfig.getInitParameter( name ) );
290             }
291             
292             stream.writeObject( params );
293         }
294     }
295     
296     // See comments on writeObject.
297
private void readObject( ObjectInputStream JavaDoc stream )
298         throws IOException JavaDoc, ClassNotFoundException JavaDoc
299     {
300         if ( _log.isInfoEnabled() ) _log.info( "deserializing ActionServlet " + this );
301         _configParams = ( Map JavaDoc ) stream.readObject();
302     }
303
304     public String JavaDoc getInitParameter( String JavaDoc s )
305     {
306         if ( getServletConfig() == null )
307         {
308             assert _configParams != null; // see comments on writeObject
309
return ( String JavaDoc ) _configParams.get( s );
310         }
311         
312         return super.getInitParameter( s );
313     }
314
315     public Enumeration JavaDoc getInitParameterNames()
316     {
317         if ( getServletConfig() == null )
318         {
319             assert _configParams != null; // see comments on writeObject
320
return Collections.enumeration( _configParams.keySet() );
321         }
322         
323         return super.getInitParameterNames();
324     }
325
326     /**
327      * This method is almost exactly the same as the base class initModuleConfig. The only difference
328      * is that it does not throw an UnavailableException if a module configuration file is missing or
329      * invalid.
330      *
331      * @exclude
332      */

333     protected ModuleConfig initModuleConfig
334             ( String JavaDoc prefix, String JavaDoc paths ) throws ServletException JavaDoc
335     {
336
337         if ( _log.isDebugEnabled() )
338         {
339             _log.debug( "Initializing module path '" + prefix + "' configuration from '" + paths + '\'' );
340         }
341
342         // Parse the configuration for this module
343
ModuleConfig moduleConfig = null;
344         InputStream JavaDoc input = null;
345         String JavaDoc mapping;
346         
347         try
348         {
349             ModuleConfigFactory factoryObject =
350                     ModuleConfigFactory.createFactory();
351             moduleConfig = factoryObject.createModuleConfig( prefix );
352
353             // Support for module-wide ActionMapping type override
354
mapping = getServletConfig().getInitParameter( "mapping" );
355             if ( mapping != null )
356             {
357                 moduleConfig.setActionMappingClass( mapping );
358             }
359
360             // Configure the Digester instance we will use
361
Digester digester = initConfigDigester();
362
363             // Process each specified resource path
364
while ( paths.length() > 0 )
365             {
366                 digester.push( moduleConfig );
367                 String JavaDoc path;
368                 int comma = paths.indexOf( ',' );
369                 if ( comma >= 0 )
370                 {
371                     path = paths.substring( 0, comma ).trim();
372                     paths = paths.substring( comma + 1 );
373                 }
374                 else
375                 {
376                     path = paths.trim();
377                     paths = "";
378                 }
379                 if ( path.length() < 1 )
380                 {
381                     break;
382                 }
383                 
384                 URL JavaDoc url = getConfigResource( path );
385                 
386                 //
387
// THIS IS THE MAIN DIFFERENCE: we're doing a null-check here.
388
//
389
if ( url != null )
390                 {
391                     InputSource JavaDoc is = new InputSource JavaDoc( url.toExternalForm() );
392                     input = getConfigResourceAsStream( path );
393                     is.setByteStream( input );
394                     
395                     // also, we're not letting it fail here either.
396
try
397                     {
398                         digester.parse( is );
399                         getServletContext().setAttribute( Globals.MODULE_KEY + prefix, moduleConfig );
400                     }
401                     catch ( Exception JavaDoc e )
402                     {
403                         _log.error( Bundle.getString( "PageFlow_Struts_ModuleParseError", path ), e );
404                     }
405                     input.close();
406                 }
407                 else
408                 {
409                     //
410
// Special case. If this is the default (root) module and the module path is one that's normally
411
// generated by the page flow compiler, then we don't want to error out if it's missing, since
412
// this probably just means that there's no root-level page flow. Set up a default, empty,
413
// module config.
414
//
415
if ( prefix.equals( "" ) && isAutoLoadModulePath( path, prefix ) )
416                     {
417                         if ( _log.isInfoEnabled() )
418                         {
419                             _log.info( "There is no root module at " + path + "; initializing a default module." );
420                         }
421                         
422                         //
423
// Set the ControllerConfig to a MissingRootModuleControllerConfig. This is used by
424
// PageFlowRequestProcessor.
425
//
426
moduleConfig.setControllerConfig( new MissingRootModuleControllerConfig() );
427                     }
428                     else
429                     {
430                         _log.error( Bundle.getString( "PageFlow_Struts_MissingModuleConfig", path ) );
431                     }
432                 }
433             }
434
435         }
436         catch ( Throwable JavaDoc t )
437         {
438             _log.error( internal.getMessage( "configParse", paths ), t );
439             throw new UnavailableException JavaDoc( internal.getMessage( "configParse", paths ) );
440         }
441         finally
442         {
443             if ( input != null )
444             {
445                 try
446                 {
447                     input.close();
448                 }
449                 catch ( IOException JavaDoc e )
450                 {
451                     // ignore
452
}
453             }
454         }
455
456         // Force creation and registration of DynaActionFormClass instances
457
// for all dynamic form beans we wil be using
458
FormBeanConfig fbs[] = moduleConfig.findFormBeanConfigs();
459         for ( int i = 0; i < fbs.length; i++ )
460         {
461             if ( fbs[i].getDynamic() )
462             {
463                 DynaActionFormClass.createDynaActionFormClass( fbs[i] );
464             }
465         }
466
467         // Special handling for the default module (for
468
// backwards compatibility only, will be removed later)
469
if ( prefix.length() < 1 )
470         {
471             defaultControllerConfig( moduleConfig );
472             defaultMessageResourcesConfig( moduleConfig );
473         }
474
475         // Return the completed configuration object
476
//config.freeze(); // Now done after plugins init
477
return moduleConfig;
478
479     }
480
481     static class MissingRootModuleControllerConfig extends ControllerConfig
482     {
483         public MissingRootModuleControllerConfig()
484         {
485             setProcessorClass( PageFlowRequestProcessor.class.getName() );
486         }
487     }
488
489     
490     /**
491      * Get a resource URL for a module configuration file. By default, this looks in the ServletContext
492      * and in the context classloader.
493      *
494      * @param path the path to the resource.
495      * @return an URL for the resource, or <code>null</code> if the resource is not found.
496      * @throws MalformedURLException
497      */

498     protected URL JavaDoc getConfigResource( String JavaDoc path )
499         throws MalformedURLException JavaDoc
500     {
501         URL JavaDoc resource = getServletContext().getResource( path );
502         if ( resource != null ) return resource;
503         if ( path.startsWith( "/" ) ) path = path.substring( 1 );
504         return Thread.currentThread().getContextClassLoader().getResource( path );
505     }
506
507     /**
508      * Get a resource stream for a module configuration file. By default, this looks in the ServletContext
509      * and in the context classloader.
510      *
511      * @param path the path to the resource.
512      * @return an InputStream for the resource, or <code>null</code> if the resource is not found.
513      */

514     protected InputStream JavaDoc getConfigResourceAsStream( String JavaDoc path )
515     {
516         InputStream JavaDoc stream = getServletContext().getResourceAsStream( path );
517         if ( stream != null ) return stream;
518         if ( path.startsWith( "/" ) ) path = path.substring( 1 );
519         return Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
520     }
521     
522     /**
523      * Register a Struts module, initialized by the given configuration file.
524      *
525      * @param modulePath the module path, starting at the webapp root, e.g., "/info/help".
526      * @param configFilePath the path, starting at the webapp root, to the module configuration
527      * file (e.g., "/WEB-INF/my-generated-struts-config-info-help.xml").
528      * @return the Struts ModuleConfig that was initialized.
529      */

530     protected synchronized ModuleConfig registerModule( String JavaDoc modulePath, String JavaDoc configFilePath )
531         throws ServletException JavaDoc
532     {
533         if ( _log.isInfoEnabled() )
534         {
535             _log.info( "Dynamically registering module " + modulePath + ", config XML " + configFilePath );
536         }
537         
538         if ( _log.isInfoEnabled() )
539         {
540             InternalStringBuilder msg = new InternalStringBuilder( "Dynamically registering module " ).append( modulePath );
541             _log.info( msg.append( ", config XML " ).append( configFilePath ).toString() );
542         }
543
544         if ( _cachedConfigDigester == null )
545         {
546             _cachedConfigDigester = initConfigDigester();
547         }
548
549         configDigester = _cachedConfigDigester;
550         ModuleConfig ac = initModuleConfig( modulePath, configFilePath );
551         initModuleMessageResources( ac );
552         initModuleDataSources( ac );
553         initModulePlugIns( ac );
554         ac.freeze();
555         configDigester = null;
556
557         if ( _log.isDebugEnabled() )
558         {
559             _log.debug( "Finished registering module " + modulePath + ", config XML " + configFilePath );
560         }
561         
562         return ac;
563     }
564
565     /**
566      * This override of the base class process() registers a Struts module on the fly if the
567      * config file can be found in our standard place (named in our standard way), regardless
568      * of whether the module is configured in web.xml.
569      */

570     protected void process( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
571         throws IOException JavaDoc, ServletException JavaDoc
572     {
573         //
574
// First wrap the request with an object that contains request-scoped values that our runtime uses. This
575
// is faster than sticking everything into attributes on the request (then basically reading from a HashMap).
576
//
577
PageFlowRequestWrapper requestWrapper = PageFlowRequestWrapper.wrapRequest( request );
578         request = requestWrapper;
579         
580         ServletContext JavaDoc servletContext = getServletContext();
581         String JavaDoc modulePath = PageFlowUtils.getModulePathForRelativeURI( InternalUtils.getDecodedServletPath( request ) );
582         ModuleConfig registeredApp;
583         
584         //
585
// Get the registered Struts module for the request.
586
//
587
registeredApp = getModuleConfig( modulePath, request, response );
588         
589         //
590
// If we've dynamically registered a module, then we need to override the base process() behavior to select the
591
// module. Note that we don't want to synchronize the call to process().
592
//
593
if ( registeredApp != null )
594         {
595             //
596
// Try to select the appropriate Struts module and delegate to its RequestProcessor.
597
//
598
ModuleConfig moduleConfig = InternalUtils.selectModule( modulePath, request, servletContext );
599             RequestProcessor requestProcessor = getRequestProcessor( moduleConfig );
600             requestProcessor.process( request, response );
601         }
602         else
603         {
604             
605             //
606
// This is the same as the base process() behavior, but it checks for a missing module-configuration.
607
//
608
ModuleConfig moduleConfig = null;
609             
610             if ( InternalUtils.getModuleConfig( RequestUtils.getModuleName( request, servletContext ), servletContext ) != null )
611             {
612                 String JavaDoc modulePrefix = RequestUtils.getModuleName( request, servletContext );
613                 moduleConfig = InternalUtils.selectModule( modulePrefix, request, servletContext );
614             }
615             
616             String JavaDoc servletPath = InternalUtils.getDecodedServletPath( request );
617             RequestProcessor rp = moduleConfig != null ? getRequestProcessor( moduleConfig ) : null;
618             
619             if ( rp != null && moduleCanHandlePath( moduleConfig, rp, servletPath ) )
620             {
621                 rp.process( request, response );
622             }
623             else
624             {
625                 if ( processUnhandledAction( request, response, servletPath ) ) return;
626                 
627                 String JavaDoc originalServletPath = requestWrapper.getOriginalServletPath();
628                 if ( originalServletPath != null )
629                 {
630                     servletPath = originalServletPath;
631                     modulePath = PageFlowUtils.getModulePathForRelativeURI( originalServletPath );
632                 }
633                 
634                 if ( _log.isErrorEnabled() )
635                 {
636                     InternalStringBuilder msg = new InternalStringBuilder( "No module configuration registered for " );
637                     msg.append( servletPath ).append( " (module path " ).append( modulePath ).append( ")." );
638                     _log.error( msg.toString() );
639                 }
640
641                 //
642
// If we're not in production mode, send a diagnostic on the response; otherwise, simply send a 404.
643
//
644
if ( modulePath.length() == 0 ) modulePath = "/";
645                 InternalUtils.sendDevTimeError( "PageFlow_NoModuleConf", null, HttpServletResponse.SC_NOT_FOUND,
646                                                 request, response, servletContext,
647                                                 new Object JavaDoc[]{ servletPath, modulePath } );
648             }
649         }
650     }
651  
652     /**
653      * Tell whether the given module can handle the given path. By default, this is always true.
654      */

655     protected boolean moduleCanHandlePath( ModuleConfig moduleConfig, RequestProcessor rp, String JavaDoc servletPath )
656     {
657         return true;
658     }
659     
660     /**
661      * @exclude
662      */

663     protected Digester initConfigDigester() throws ServletException JavaDoc
664     {
665         _cachedConfigDigester = super.initConfigDigester();
666         return _cachedConfigDigester;
667     }
668     
669     public void destroy()
670     {
671         _registeredModules.clear();
672         super.destroy();
673     }
674
675     void ensureModuleSelected( String JavaDoc modulePath, HttpServletRequest JavaDoc request, ServletResponse JavaDoc response )
676         throws IOException JavaDoc, ServletException JavaDoc
677     {
678         if ( getModuleConfig( modulePath, request, response ) != null )
679         {
680             InternalUtils.selectModule( modulePath, request, getServletContext() );
681         }
682     }
683     
684     /**
685      * Get the Struts ModuleConfig for the given module path.
686      *
687      * @param modulePath the module path, from the request URI.
688      * @param request the current ServletRequest
689      * @param response the current HttpServletResponse
690      * @return the Struts ModuleConfig that corresponds with <code>modulePath</code>
691      * @throws IOException
692      * @throws ServletException
693      */

694     protected ModuleConfig getModuleConfig( String JavaDoc modulePath, ServletRequest JavaDoc request,
695                                             ServletResponse JavaDoc response )
696         throws IOException JavaDoc, ServletException JavaDoc
697     {
698         ensureModuleRegistered( modulePath, request );
699         
700         ModuleConfig mc = ( ModuleConfig ) _registeredModules.get( modulePath );
701         
702         if ( mc.getPrefix() == null )
703         {
704             assert mc instanceof NonexistantModuleConfig : mc.getClass().getName();
705             mc = null;
706         }
707         
708         return mc;
709     }
710     
711     /**
712      * Ensures that the Struts module for the given path is registered (dynamically, if necessary).
713      * @exclude
714      *
715      * @param modulePath the module path, from the request URI.
716      * @param request the current ServletRequest
717      * @throws IOException
718      * @throws ServletException
719      */

720     public ModuleConfig ensureModuleRegistered( String JavaDoc modulePath, ServletRequest JavaDoc request )
721         throws IOException JavaDoc, ServletException JavaDoc
722     {
723         //
724
// Dynamically register the Struts module, if appropriate. If we've already
725
// tried to register it (_registeredModules.containsKey( modulePath )), don't
726
// try again.
727
//
728
// Note that two threads could potentially get in here at the same time, and
729
// both will register the module. This is OK -- reads from _registeredModules
730
// are consistent, and the worst that will happen is that the module will get
731
// registered with a valid ModuleConfig a few times.
732
//
733
ModuleConfig ac = ( ModuleConfig ) _registeredModules.get( modulePath );
734         
735         if ( ac == null )
736         {
737             //
738
// See if there's an explicit initialization for this module in
739
// the webapp configuration. If there is, we'll use that.
740
//
741
ac = ( ModuleConfig ) getServletContext().getAttribute( Globals.MODULE_KEY + modulePath );
742
743             if ( ac == null )
744             {
745                 //
746
// If we find the Struts config file for this module, we can dynamically
747
// register it.
748
//
749
String JavaDoc moduleConfPath = getModuleConfPath( modulePath );
750                 
751                 if ( moduleConfPath != null )
752                 {
753                     ac = registerModule( modulePath, moduleConfPath );
754                 }
755             }
756
757             if ( ac == null )
758             {
759                 _registeredModules.put( modulePath, NONEXISTANT_MODULE_CONFIG );
760                                                    // ConcurrentHashMap doesn't allow null values
761
}
762             else
763             {
764                 _registeredModules.put( modulePath, ac );
765                 getServletContext().setAttribute( Globals.MODULE_KEY + modulePath, ac );
766             }
767         }
768         
769         return ac;
770     }
771     
772     private static class NonexistantModuleConfig extends ModuleConfigImpl
773     {
774         public NonexistantModuleConfig()
775         {
776             super( ( String JavaDoc ) null );
777         }
778     }
779     
780     //-----------------------------------------------------------------------------------------------------------
781
// The following methods (defaultControllerConfig, defaultMessageResourcesConfig, defaultFormBeansConfig,
782
// defaultForwardsConfig, defaultMappingsConfig) were copied straight from the Struts ActionServlet.java
783
// (they're private, not protected).
784

785     /**
786      * Perform backwards-compatible configuration of the default module's
787      * controller configuration from servlet initialization parameters (as
788      * were used in Struts 1.0).
789      *
790      * @param config The ModuleConfig object for the default module
791      *
792      * @since Struts 1.1
793      * @deprecated Will be removed in a release after Struts 1.1.
794      */

795     private void defaultControllerConfig(ModuleConfig config) {
796
797         String JavaDoc value = null;
798         ControllerConfig cc = config.getControllerConfig();
799         
800         value = getServletConfig().getInitParameter("bufferSize");
801         if (value != null) {
802             cc.setBufferSize(Integer.parseInt(value));
803         }
804         
805         value = getServletConfig().getInitParameter("content");
806         if (value != null) {
807             cc.setContentType(value);
808         }
809         
810         value = getServletConfig().getInitParameter("locale");
811         // must check for null here
812
if (value != null) {
813             if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)) {
814                 cc.setLocale(true);
815             } else {
816                 cc.setLocale(false);
817             }
818         }
819         
820         value = getServletConfig().getInitParameter("maxFileSize");
821         if (value != null) {
822             cc.setMaxFileSize(value);
823         }
824         
825         value = getServletConfig().getInitParameter("nocache");
826         if (value != null) {
827             if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)) {
828                 cc.setNocache(true);
829             } else {
830                 cc.setNocache(false);
831             }
832         }
833         
834         value = getServletConfig().getInitParameter("multipartClass");
835         if (value != null) {
836             cc.setMultipartClass(value);
837         }
838         
839         value = getServletConfig().getInitParameter("tempDir");
840         if (value != null) {
841             cc.setTempDir(value);
842         }
843
844     }
845
846     /**
847      * Perform backwards-compatible configuration of the default module's
848      * message resources configuration from servlet initialization parameters
849      * (as were used in Struts 1.0).
850      *
851      * @param config The ModuleConfig object for the default module
852      *
853      * @since Struts 1.1
854      * @deprecated Will be removed in a release after Struts 1.1.
855      */

856     private void defaultMessageResourcesConfig(ModuleConfig config) {
857
858         String JavaDoc value = null;
859
860         MessageResourcesConfig mrc =
861             config.findMessageResourcesConfig(Globals.MESSAGES_KEY);
862         if (mrc == null) {
863             mrc = new MessageResourcesConfig();
864             mrc.setKey(Globals.MESSAGES_KEY);
865             config.addMessageResourcesConfig(mrc);
866         }
867         value = getServletConfig().getInitParameter("application");
868         if (value != null) {
869             mrc.setParameter(value);
870         }
871         value= getServletConfig().getInitParameter("factory");
872         if (value != null) {
873             mrc.setFactory(value);
874         }
875         value = getServletConfig().getInitParameter("null");
876         if (value != null) {
877             if (value.equalsIgnoreCase("true") ||
878                 value.equalsIgnoreCase("yes")) {
879                 mrc.setNull(true);
880             } else {
881                 mrc.setNull(false);
882             }
883         }
884     }
885     
886     /**
887      * Clear the internal map of registered modules.
888      *
889      * @exclude
890      */

891     public void clearRegisteredModules()
892     {
893         ServletContext JavaDoc servletContext = getServletContext();
894         
895         for ( Iterator JavaDoc ii = _registeredModules.keySet().iterator(); ii.hasNext(); )
896         {
897             String JavaDoc modulePrefix = ( String JavaDoc ) ii.next();
898             servletContext.removeAttribute( Globals.MODULE_KEY + modulePrefix );
899         }
900         
901         _registeredModules.clear();
902     }
903     
904     /**
905      * Last chance to handle an unhandled action URI.
906      * @return <code>true</code> if this method handled it (by forwarding somewhere or writing to the response).
907      */

908     protected boolean processUnhandledAction( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc uri )
909             throws IOException JavaDoc, ServletException JavaDoc
910     {
911         return false;
912     }
913 }
914
Popular Tags