KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > modules > ModuleLoader


1 package org.apache.turbine.modules;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001-2002 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache Turbine" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache Turbine", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.util.Iterator JavaDoc;
58 import java.util.List JavaDoc;
59 import java.util.Map JavaDoc;
60
61 import org.apache.commons.collections.FastArrayList;
62 import org.apache.commons.collections.FastHashMap;
63 import org.apache.commons.configuration.Configuration;
64 import org.apache.commons.logging.Log;
65 import org.apache.commons.logging.LogFactory;
66 import org.apache.turbine.Turbine;
67 import org.apache.turbine.TurbineException;
68 import org.apache.turbine.pipeline.PipelineUtil;
69
70 /**
71  * Load modules for use in the view pipeline.
72  *
73  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
74  * @author <a HREF="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
75  * @version $Id: ModuleLoader.java,v 1.12 2004/01/31 01:34:50 epugh Exp $
76  */

77 public class ModuleLoader
78 {
79     private static final Log log = LogFactory.getLog( ModuleLoader.class );
80     /**
81      * Module packages for this module loader.
82      */

83     protected List JavaDoc modulePackages;
84
85     /**
86      * A String representation of the module packages
87      * that are search. Used in exception handling.
88      */

89     protected StringBuffer JavaDoc modulePackagesNames;
90
91     /**
92      * The default module to load when nothing else
93      * can be found.
94      */

95     protected String JavaDoc defaultModule;
96
97     /**
98      * The defaults modules for the various defined types.
99      */

100     protected Map JavaDoc defaultModules;
101
102     /**
103      * Property that controls whether scripting is enabled
104      * for this module loader.
105      */

106     protected boolean scriptingEnabled;
107
108     protected Configuration configuration;
109
110     /**
111      * Default constructor.
112      */

113     public ModuleLoader()
114     {
115         modulePackages = new FastArrayList();
116         modulePackagesNames = new StringBuffer JavaDoc();
117         defaultModules = new FastHashMap();
118     }
119
120     /**
121      * Add a module package to the search list.
122      *
123      * @param modulePackage module package to add to search list
124      */

125     public void addModulePackage(String JavaDoc modulePackage)
126     {
127         modulePackages.add(modulePackage);
128         modulePackagesNames.append(modulePackage).append("\n");
129     }
130
131
132     /**
133      * Set the configuration for the module loader
134      */

135     public void setConfiguration(Configuration configuration)
136     {
137         this.configuration = configuration;
138     }
139
140     /**
141      * Initialize this module loader.
142      */

143     public void init()
144         throws TurbineException
145     {
146         Configuration moduleTypes = configuration.subset("module.default");
147
148         if (moduleTypes == null)
149         {
150             throw new TurbineException(
151                 "module.default subset is missing from TR.props");
152         }
153
154         Iterator JavaDoc j = moduleTypes.getKeys();
155
156         while (j.hasNext())
157         {
158             String JavaDoc moduleType = (String JavaDoc) j.next();
159             String JavaDoc defaultModule = moduleTypes.getString(moduleType);
160
161             // Add the default module for the particular
162
// module type to our container for module defaults.
163
setDefaultModule(moduleType, defaultModule);
164         }
165
166         // Grab our list of module packages so that we can
167
// add them to the search list of the ModuleLoader.
168
List JavaDoc modulePackages = configuration.getList(Turbine.MODULE_PACKAGES);
169
170         Iterator JavaDoc i = modulePackages.iterator();
171
172         while (i.hasNext())
173         {
174             addModulePackage((String JavaDoc) i.next());
175         }
176
177         // Add the package for Turbine's default modules.
178
// This package must be added last so it is searched
179
// for last.
180
addModulePackage(Turbine.DEFAULT_MODULE_PACKAGE);
181     }
182
183     /**
184      * Get an instance of a module
185      *
186      * All clients should use Turbine.getResolver().getModule(type,name)
187      * to get the module. The only client of ModuleLoader.getModule(type,name)
188      * should be the resolver.
189      *
190      * @param name
191      * @param type
192      * @return The desired <code>Module</code>, or <code>null</code>
193      * if not found..
194      */

195     public Module getModule(String JavaDoc type, String JavaDoc name)
196         throws Exception JavaDoc
197     {
198         Module module = null;
199
200         Iterator JavaDoc k;
201         if (type.equals("actions"))
202         {
203             k = getAllPossibleActions(name);
204         }
205         else
206         {
207             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
208             PipelineUtil.parseTemplatePath(name, sb);
209             List JavaDoc names = getPossibleModules(sb.toString());
210             k = getAllPossibleModules(names, type);
211         }
212
213         while (k.hasNext())
214         {
215             String JavaDoc moduleClass = (String JavaDoc) k.next();
216
217             try
218             {
219                 log.debug("Looking for " + moduleClass);
220                 module = (Module) Class.forName(moduleClass).newInstance();
221                 log.debug("Mapped " + name + " to " + moduleClass);
222                 break;
223             }
224             catch (Exception JavaDoc ignored)
225             {
226                 // Likely a non-existant class name combination.
227
}
228         }
229
230         if (module == null)
231         {
232             throw new Exception JavaDoc(
233                 "Can't find module for " + name + " in " + modulePackagesNames);
234         }
235
236         return module;
237     }
238
239     /**
240      * Returns the cross product of module packages, names, and type.
241      *
242      * @param names Possible modules for a specific template.
243      * @param type The type modules to generate possibile fully
244      * qualified class names for.
245      */

246     private Iterator JavaDoc getAllPossibleModules(List JavaDoc names, String JavaDoc type)
247     {
248         FastArrayList modules = new FastArrayList();
249         FastArrayList defaultModules = new FastArrayList();
250
251         Iterator JavaDoc i = modulePackages.iterator();
252         while (i.hasNext())
253         {
254             String JavaDoc modulePackage = (String JavaDoc) i.next();
255             Iterator JavaDoc m = (Iterator JavaDoc) names.iterator();
256             while (m.hasNext())
257             {
258                 String JavaDoc module = modulePackage + "." + type + "." + m.next();
259                 modules.add(module);
260
261             }
262
263             // Add default for type
264
defaultModules.add(modulePackage + "." + getDefaultModule(type));
265         }
266
267         modules.addAll(defaultModules);
268
269         return modules.iterator();
270     }
271
272     /**
273      * @param name The name of the <code>Action</code> to retrieve
274      * class names for.
275      */

276     private Iterator JavaDoc getAllPossibleActions(String JavaDoc name)
277     {
278         FastArrayList actions = new FastArrayList();
279
280         Iterator JavaDoc i = modulePackages.iterator();
281         while (i.hasNext())
282         {
283             String JavaDoc action = (String JavaDoc) i.next() + ".actions." + name;
284             actions.add(action);
285         }
286
287         return actions.iterator();
288     }
289
290     /**
291      * Set the default module to load when no other module
292      * can be found.
293      */

294     public void setDefaultModule(String JavaDoc defaultModule)
295     {
296         this.defaultModule = defaultModule;
297     }
298
299     /**
300      * Set the default module for a type.
301      */

302     public void setDefaultModule(String JavaDoc type, String JavaDoc defaultModule)
303     {
304         defaultModules.put(type, defaultModule);
305     }
306
307     /**
308      * "New module stuff"
309      */

310     public String JavaDoc getDefaultModule(String JavaDoc moduleType)
311     {
312         return (String JavaDoc) defaultModules.get(moduleType);
313     }
314
315     /**
316      * Set whether or not this module loader will attempt
317      * to find BSF script to execute in the place of
318      * java classes.
319      */

320     public void setScriptingEnabled(boolean state)
321     {
322         scriptingEnabled = state;
323     }
324
325     /**
326      *
327      *
328      * @param template
329      * @return
330      */

331      protected List JavaDoc getPossibleModules(String JavaDoc template)
332         throws Exception JavaDoc
333     {
334         List JavaDoc packages = new FastArrayList();
335
336         // Parse the template name and change it into a package.
337
StringBuffer JavaDoc pckage = new StringBuffer JavaDoc();
338         int i = PipelineUtil.parseTemplatePath(template,pckage);
339
340         if (pckage.charAt(0) == '/')
341         {
342             pckage.deleteCharAt(0);
343             i--;
344         }
345
346         if (i >= 0)
347         {
348             for (int j = 0; j <= i; j++)
349             {
350                 if (pckage.charAt(j) == '/')
351                 {
352                     pckage.setCharAt(j, '.');
353                 }
354             }
355         }
356
357         // Remove a possible file extension.
358
for (int j = i + 1; j < pckage.length(); j++)
359         {
360             if (pckage.charAt(j) == '.')
361             {
362                 pckage.delete(j,pckage.length());
363                 break;
364             }
365         }
366
367         // Try first an exact match for a module having the same
368
// name as the input template, traverse then upper level
369
// packages to find a default module named Default.
370
int j = 9999;
371         String JavaDoc module;
372         while (j-- > 0)
373         {
374             module = pckage.toString();
375
376             packages.add(module);
377
378             pckage.setLength(i + 1);
379             if (i > 0)
380             {
381                 // We have still packages to traverse.
382
for (i = pckage.length() - 2; i >= 0; i--)
383                 {
384                     if (pckage.charAt(i) == '.')
385                     {
386                         break;
387                     }
388                 }
389             }
390             else if (j > 0)
391             {
392                 // Only the main level left.
393
j = 1;
394             }
395             pckage.append("Default");
396         }
397
398         // Not found, return the default module name.
399
return packages;
400     }
401 }
402
Popular Tags