View Javadoc

1   package org.apache.turbine.services.template;
2   
3   
4   /*
5    * Copyright 2001-2004 The Apache Software Foundation.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License")
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  
21  import java.io.File;
22  
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import org.apache.avalon.framework.service.ServiceException;
28  import org.apache.commons.configuration.Configuration;
29  
30  import org.apache.commons.lang.StringUtils;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.fulcrum.factory.FactoryException;
35  import org.apache.fulcrum.factory.FactoryService;
36  import org.apache.fulcrum.pool.PoolService;
37  
38  import org.apache.turbine.Turbine;
39  import org.apache.turbine.TurbineConstants;
40  import org.apache.turbine.modules.LayoutLoader;
41  import org.apache.turbine.modules.Loader;
42  import org.apache.turbine.modules.NavigationLoader;
43  import org.apache.turbine.modules.PageLoader;
44  import org.apache.turbine.modules.ScreenLoader;
45  import org.apache.turbine.services.InitializationException;
46  import org.apache.turbine.services.TurbineBaseService;
47  import org.apache.turbine.services.TurbineServices;
48  import org.apache.turbine.services.avaloncomponent.AvalonComponentService;
49  import org.apache.turbine.services.servlet.TurbineServlet;
50  import org.apache.turbine.services.template.mapper.BaseTemplateMapper;
51  import org.apache.turbine.services.template.mapper.ClassMapper;
52  import org.apache.turbine.services.template.mapper.DirectMapper;
53  import org.apache.turbine.services.template.mapper.DirectTemplateMapper;
54  import org.apache.turbine.services.template.mapper.LayoutTemplateMapper;
55  import org.apache.turbine.services.template.mapper.Mapper;
56  import org.apache.turbine.services.template.mapper.ScreenTemplateMapper;
57  import org.apache.turbine.util.RunData;
58  import org.apache.turbine.util.TurbineException;
59  import org.apache.turbine.util.uri.URIConstants;
60  
61  /***
62   * This service provides a method for mapping templates to their
63   * appropriate Screens or Navigations.  It also allows templates to
64   * define a layout/navigations/screen modularization within the
65   * template structure.  It also performs caching if turned on in the
66   * properties file.
67   *
68   * This service is not bound to a specific templating engine but we
69   * will use the Velocity templating engine for the examples. It is
70   * available by using the VelocityService.
71   *
72   * This assumes the following properties in the Turbine configuration:
73   *
74   * <pre>
75   * # Register the VelocityService for the "vm" extension.
76   * services.VelocityService.template.extension=vm
77   *
78   * # Default Java class for rendering a Page in this service
79   * # (must be found on the class path (org.apache.turbine.modules.page.VelocityPage))
80   * services.VelocityService.default.page = VelocityPage
81   *
82   * # Default Java class for rendering a Screen in this service
83   * # (must be found on the class path (org.apache.turbine.modules.screen.VelocityScreen))
84   * services.VelocityService.default.screen=VelocityScreen
85   *
86   * # Default Java class for rendering a Layout in this service
87   * # (must be found on the class path (org.apache.turbine.modules.layout.VelocityOnlyLayout))
88   * services.VelocityService.default.layout = VelocityOnlyLayout
89   *
90   * # Default Java class for rendering a Navigation in this service
91   * # (must be found on the class path (org.apache.turbine.modules.navigation.VelocityNavigation))
92   * services.VelocityService.default.navigation=VelocityNavigation
93   *
94   * # Default Template Name to be used as Layout. If nothing else is
95   * # found, return this as the default name for a layout
96   * services.VelocityService.default.layout.template = Default.vm
97   * </pre>
98   * If you want to render a template, a search path is used to find
99   * a Java class which might provide information for the context of
100  * this template.
101  *
102  * If you request e.g. the template screen
103  *
104  * about,directions,Driving.vm
105  *
106  * then the following class names are searched (on the module search
107  * path):
108  *
109  * 1. about.directions.Driving     &lt;- direct matching the template to the class name
110  * 2. about.directions.Default     &lt;- matching the package, class name is Default
111  * 3. about.Default                &lt;- stepping up in the package hierarchy, looking for Default
112  * 4. Default                      &lt;- Class called "Default" without package
113  * 5. VelocityScreen               &lt;- The class configured by the Service (VelocityService) to
114  *
115  * And if you have the following module packages configured:
116  *
117  * module.packages = org.apache.turbine.modules, com.mycorp.modules
118  *
119  * then the class loader will look for
120  *
121  * org.apache.turbine.modules.screens.about.directions.Driving
122  * com.mycorp.modules.screens.about.directions.Driving
123  * org.apache.turbine.modules.screens.about.directions.Default
124  * com.mycorp.modules.screens.about.directions.Default
125  * org.apache.turbine.modules.screens.about.Default
126  * com.mycorp.modules.screens.about.Default
127  * org.apache.turbine.modules.screens.Default
128  * com.mycorp.modules.screens.Default
129  * org.apache.turbine.modules.screens.VelocityScreen
130  * com.mycorp.modules.screens.VelocityScreen
131  *
132  * Most of the times, you don't have any backing Java class for a
133  * template screen, so the first match will be
134  * org.apache.turbine.modules.screens.VelocityScreen
135  * which then renders your screen.
136  *
137  * Please note, that your Screen Template (Driving.vm) must exist!
138  * If it does not exist, the Template Service will report an error.
139  *
140  * Once the screen is found, the template service will look for
141  * the Layout and Navigation templates of your Screen. Here, the
142  * template service looks for matching template names!
143  *
144  * Consider our example:  about,directions,Driving.vm (Screen Name)
145  *
146  * Now the template service will look for the following Navigation
147  * and Layout templates:
148  *
149  * 1. about,directions,Driving.vm      &lt;- exact match
150  * 2. about,directions,Default.vm      &lt;- package match, Default name
151  * 3. about,Default.vm                 &lt;- stepping up in the hierarchy
152  * 4. Default.vm                       &lt;- The name configured as default.layout.template
153  *                                        in the Velocity service.
154  *
155  * And now Hennings' two golden rules for using templates:
156  *
157  * Many examples and docs from older Turbine code show template pathes
158  * with a slashes. Repeat after me: "TEMPLATE NAMES NEVER CONTAIN SLASHES!"
159  *
160  * Many examples and docs from older Turbine code show templates that start
161  * with "/". This is not only a violation of the rule above but actively breaks
162  * things like loading templates from a jar with the velocity jar loader. Repeat
163  * after me: "TEMPLATE NAMES ARE NOT PATHES. THEY'RE NOT ABSOLUTE AND HAVE NO
164  * LEADING /".
165  *
166  * If you now wonder how a template name is mapped to a file name: This is
167  * scope of the templating engine. Velocity e.g. has this wonderful option to
168  * load templates from jar archives. There is no single file but you tell
169  * velocity "get about,directions,Driving.vm" and it returns the rendered
170  * template. This is not the job of the Templating Service but of the Template
171  * rendering services like VelocityService.
172  *
173  * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
174  * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
175  * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
176  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
177  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
178  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
179  * @version $Id: TurbineTemplateService.java 329828 2005-10-31 14:41:10Z epugh $
180  */
181 public class TurbineTemplateService
182     extends TurbineBaseService
183     implements TemplateService
184 {
185     /*** Logging */
186     private static Log log = LogFactory.getLog(TurbineTemplateService.class);
187 
188     /*** Represents Page Objects */
189     public static final int PAGE_KEY = 0;
190 
191     /*** Represents Page Objects */
192     public static final String PAGE_NAME = "page";
193 
194     /*** Represents Screen Objects */
195     public static final int SCREEN_KEY = 1;
196 
197     /*** Represents Screen Objects */
198     public static final String SCREEN_NAME = "screen";
199 
200     /*** Represents Layout Objects */
201     public static final int LAYOUT_KEY = 2;
202 
203     /*** Represents Layout Objects */
204     public static final String LAYOUT_NAME = "layout";
205 
206     /*** Represents Navigation Objects */
207     public static final int NAVIGATION_KEY = 3;
208 
209     /*** Represents Navigation Objects */
210     public static final String NAVIGATION_NAME = "navigation";
211 
212     /*** Represents Layout Template Objects */
213     public static final int LAYOUT_TEMPLATE_KEY = 4;
214 
215     /*** Represents Layout Template Objects */
216     public static final String LAYOUT_TEMPLATE_NAME = "layout.template";
217 
218     /*** Represents Screen Template Objects */
219     public static final int SCREEN_TEMPLATE_KEY = 5;
220 
221     /*** Represents Screen Template Objects */
222     public static final String SCREEN_TEMPLATE_NAME = "screen.template";
223 
224     /*** Represents Navigation Template Objects */
225     public static final int NAVIGATION_TEMPLATE_KEY = 6;
226 
227     /*** Represents Navigation Template Objects */
228     public static final String NAVIGATION_TEMPLATE_NAME = "navigation.template";
229 
230     /*** Number of different Template Types that we know of */
231     public static final int TEMPLATE_TYPES = 7;
232 
233     /*** Here we register the mapper objects for our various object types */
234     private Mapper [] mapperRegistry = null;
235 
236     /***
237      * The default file extension used as a registry key when a
238      * template's file extension cannot be determined.
239      *
240      * @deprecated. Use TemplateService.DEFAULT_EXTENSION_VALUE.
241      */
242     protected static final String NO_FILE_EXT = TemplateService.DEFAULT_EXTENSION_VALUE;
243 
244 
245     /*** Flag set if cache is to be used. */
246     private boolean useCache = false;
247 
248     /*** Default extension for templates. */
249     private String defaultExtension;
250 
251     /*** Default template without the default extension. */
252     private String defaultTemplate;
253 
254     /***
255      * The mappings of template file extensions to {@link
256      * org.apache.turbine.services.template.TemplateEngineService}
257      * implementations. Implementing template engines can locate
258      * templates within the capability of any resource loaders they
259      * may possess, and other template engines are stuck with file
260      * based template hierarchy only.
261      */
262     private Map templateEngineRegistry = null;
263 
264     /***
265      * C'tor
266      */
267     public TurbineTemplateService()
268     {
269     }
270 
271     /***
272      * Called the first time the Service is used.
273      *
274      * @exception InitializationException Something went wrong when
275      *                                     setting up the Template Service.
276      */
277     public void init()
278         throws InitializationException
279     {
280         // Get the configuration for the template service.
281         Configuration config = getConfiguration();
282 
283         // Get the default extension to use if nothing else is applicable.
284         defaultExtension = config.getString(TemplateService.DEFAULT_EXTENSION_KEY,
285             TemplateService.DEFAULT_EXTENSION_VALUE);
286 
287         defaultTemplate =  config.getString(TemplateService.DEFAULT_TEMPLATE_KEY,
288             TemplateService.DEFAULT_TEMPLATE_VALUE);
289 
290         // Check to see if we are going to be caching modules.
291         // Aaargh, who moved this _out_ of the TemplateService package?
292         useCache = Turbine.getConfiguration().getBoolean(TurbineConstants.MODULE_CACHE_KEY,
293             TurbineConstants.MODULE_CACHE_DEFAULT);
294 
295         log.debug("Default Extension: " + defaultExtension);
296         log.debug("Default Template:  " + defaultTemplate);
297         log.debug("Use Caching:       " + useCache);
298 
299         templateEngineRegistry = Collections.synchronizedMap(new HashMap());
300 
301         initMapper(config);
302         setInit(true);
303     }
304 
305     /***
306      * Returns true if the Template Service has caching activated
307      *
308      * @return true if Caching is active.
309      */
310     public boolean isCaching()
311     {
312         return useCache;
313     }
314 
315     /***
316      * Get the default template name extension specified
317      * in the template service properties. If no extension
318      * is defined, return the empty string.
319      *
320      * @return The default extension.
321      */
322     public String getDefaultExtension()
323     {
324         return StringUtils.isNotEmpty(defaultExtension) ? defaultExtension : "";
325     }
326 
327     /***
328      * Return Extension for a supplied template
329      *
330      * @param template The template name
331      *
332      * @return extension The extension for the supplied template
333      */
334     public String getExtension(String template)
335     {
336         if (StringUtils.isEmpty(template))
337         {
338             return getDefaultExtension();
339         }
340 
341         int dotIndex = template.indexOf(EXTENSION_SEPARATOR);
342 
343         return (dotIndex < 0) ? getDefaultExtension() : template.substring(dotIndex + 1);
344     }
345 
346 
347     /***
348      * Returns the Default Template Name with the Default Extension.
349      * If the extension is unset, return only the template name
350      *
351      * @return The default template Name
352      */
353     public String getDefaultTemplate()
354     {
355         StringBuffer sb = new StringBuffer();
356         sb.append(defaultTemplate);
357         if (StringUtils.isNotEmpty(defaultExtension))
358         {
359             sb.append(EXTENSION_SEPARATOR);
360             sb.append(getDefaultExtension());
361         }
362         return sb.toString();
363     }
364 
365     /***
366      * Get the default page module name of the template engine
367      * service corresponding to the default template name extension.
368      *
369      * @return The default page module name.
370      */
371     public String getDefaultPage()
372     {
373         return getDefaultPageName(getDefaultTemplate());
374     }
375 
376     /***
377      * Get the default screen module name of the template engine
378      * service corresponding to the default template name extension.
379      *
380      * @return The default screen module name.
381      */
382     public String getDefaultScreen()
383     {
384         return getDefaultScreenName(getDefaultTemplate());
385     }
386 
387     /***
388      * Get the default layout module name of the template engine
389      * service corresponding to the default template name extension.
390      *
391      * @return The default layout module name.
392      */
393     public String getDefaultLayout()
394     {
395         return getDefaultLayoutName(getDefaultTemplate());
396     }
397 
398     /***
399      * Get the default navigation module name of the template engine
400      * service corresponding to the default template name extension.
401      *
402      * @return The default navigation module name.
403      */
404     public String getDefaultNavigation()
405     {
406         return getDefaultNavigationName(getDefaultTemplate());
407     }
408 
409     /***
410      * Get the default layout template name of the template engine
411      * service corresponding to the default template name extension.
412      *
413      * @return The default layout template name.
414      */
415     public String getDefaultLayoutTemplate()
416     {
417         return getDefaultLayoutTemplateName(getDefaultTemplate());
418     }
419 
420     /***
421      * Get the default page module name of the template engine
422      * service corresponding to the template name extension of
423      * the named template.
424      *
425      * @param template The template name.
426      * @return The default page module name.
427      */
428     public String getDefaultPageName(String template)
429     {
430         return ((Mapper) mapperRegistry[PAGE_KEY]).getDefaultName(template);
431     }
432 
433     /***
434      * Get the default screen module name of the template engine
435      * service corresponding to the template name extension of
436      * the named template.
437      *
438      * @param template The template name.
439      * @return The default screen module name.
440      */
441     public String getDefaultScreenName(String template)
442     {
443         return ((Mapper) mapperRegistry[SCREEN_KEY]).getDefaultName(template);
444     }
445 
446     /***
447      * Get the default layout module name of the template engine
448      * service corresponding to the template name extension of
449      * the named template.
450      *
451      * @param template The template name.
452      * @return The default layout module name.
453      */
454     public String getDefaultLayoutName(String template)
455     {
456         return ((Mapper) mapperRegistry[LAYOUT_KEY]).getDefaultName(template);
457     }
458 
459     /***
460      * Get the default navigation module name of the template engine
461      * service corresponding to the template name extension of
462      * the named template.
463      *
464      * @param template The template name.
465      * @return The default navigation module name.
466      */
467     public String getDefaultNavigationName(String template)
468     {
469         return ((Mapper) mapperRegistry[NAVIGATION_KEY]).getDefaultName(template);
470     }
471 
472     /***
473      * Get the default layout template name of the template engine
474      * service corresponding to the template name extension of
475      * the named template.
476      *
477      * @param template The template name.
478      * @return The default layout template name.
479      */
480     public String getDefaultLayoutTemplateName(String template)
481     {
482         return ((Mapper) mapperRegistry[LAYOUT_TEMPLATE_KEY]).getDefaultName(template);
483     }
484 
485     /***
486      * Find the default page module name for the given request.
487      *
488      * @param data The encapsulation of the request to retrieve the
489      *             default page for.
490      * @return The default page module name.
491      */
492     public String getDefaultPageName(RunData data)
493     {
494         String template = data.getParameters().get(URIConstants.CGI_TEMPLATE_PARAM);
495         return (template != null) ?
496             getDefaultPageName(template) : getDefaultPage();
497     }
498 
499     /***
500      * Find the default layout module name for the given request.
501      *
502      * @param data The encapsulation of the request to retrieve the
503      *             default layout for.
504      * @return The default layout module name.
505      */
506     public String getDefaultLayoutName(RunData data)
507     {
508         String template = data.getParameters().get(URIConstants.CGI_TEMPLATE_PARAM);
509         return (template != null) ?
510             getDefaultLayoutName(template) : getDefaultLayout();
511     }
512 
513     /***
514      * Locate and return the name of the screen module to be used
515      * with the named screen template.
516      *
517      * @param template The screen template name.
518      * @return The found screen module name.
519      * @exception Exception, a generic exception.
520      */
521     public String getScreenName(String template)
522         throws Exception
523     {
524         return ((Mapper) mapperRegistry[SCREEN_KEY]).getMappedName(template);
525     }
526 
527     /***
528      * Locate and return the name of the layout module to be used
529      * with the named layout template.
530      *
531      * @param template The layout template name.
532      * @return The found layout module name.
533      * @exception Exception, a generic exception.
534      */
535     public String getLayoutName(String template)
536         throws Exception
537     {
538         return ((Mapper) mapperRegistry[LAYOUT_KEY]).getMappedName(template);
539     }
540 
541     /***
542      * Locate and return the name of the navigation module to be used
543      * with the named navigation template.
544      *
545      * @param template The navigation template name.
546      * @return The found navigation module name.
547      * @exception Exception, a generic exception.
548      */
549     public String getNavigationName(String template)
550         throws Exception
551     {
552         return ((Mapper) mapperRegistry[NAVIGATION_KEY]).getMappedName(template);
553     }
554 
555     /***
556      * Locate and return the name of the screen template corresponding
557      * to the given template name parameter. This might return null if
558      * the screen is not found!
559      *
560      * @param template The template name parameter.
561      * @return The found screen template name.
562      * @exception Exception, a generic exception.
563      */
564     public String getScreenTemplateName(String template)
565         throws Exception
566     {
567         return ((Mapper) mapperRegistry[SCREEN_TEMPLATE_KEY]).getMappedName(template);
568     }
569 
570     /***
571      * Locate and return the name of the layout template corresponding
572      * to the given screen template name parameter.
573      *
574      * @param template The template name parameter.
575      * @return The found screen template name.
576      * @exception Exception, a generic exception.
577      */
578     public String getLayoutTemplateName(String template)
579         throws Exception
580     {
581         return ((Mapper) mapperRegistry[LAYOUT_TEMPLATE_KEY]).getMappedName(template);
582     }
583 
584     /***
585      * Locate and return the name of the navigation template corresponding
586      * to the given template name parameter. This might return null if
587      * the navigation is not found!
588      *
589      * @param template The template name parameter.
590      * @return The found navigation template name.
591      * @exception Exception, a generic exception.
592      */
593     public String getNavigationTemplateName(String template)
594         throws Exception
595     {
596         return ((Mapper) mapperRegistry[NAVIGATION_TEMPLATE_KEY]).getMappedName(template);
597     }
598 
599     /***
600      * Translates the supplied template paths into their Turbine-canonical
601      * equivalent (probably absolute paths). This is used if the templating
602      * engine (e.g. JSP) does not provide any means to load a page but 
603      * the page path is passed to the servlet container.
604      *
605      * @param templatePaths An array of template paths.
606      * @return An array of translated template paths.
607      * @deprecated Each template engine service should know how to translate
608      *             a request onto a file. 
609      */
610     public String[] translateTemplatePaths(String[] templatePaths)
611     {
612         for (int i = 0; i < templatePaths.length; i++)
613         {
614             templatePaths[i] = TurbineServlet.getRealPath(templatePaths[i]);
615         }
616         return templatePaths;
617     }
618 
619     /***
620      * Delegates to the appropriate {@link
621      * org.apache.turbine.services.template.TemplateEngineService} to
622      * check the existance of the specified template.
623      *
624      * @param template The template to check for the existance of.
625      * @param templatePaths The paths to check for the template.
626      * @deprecated Use templateExists from the various Templating Engines
627      */
628     public boolean templateExists(String template,
629         String[] templatePaths)
630     {
631         for (int i = 0; i < templatePaths.length; i++)
632         {
633             if (new File(templatePaths[i], template).exists())
634             {
635                 return true;
636             }
637         }
638         return false;
639     }
640 
641     /***
642      * Registers the provided template engine for use by the
643      * <code>TemplateService</code>.
644      *
645      * @param service The <code>TemplateEngineService</code> to register.
646      */
647     public synchronized void registerTemplateEngineService(TemplateEngineService service)
648     {
649         String[] exts = service.getAssociatedFileExtensions();
650 
651         for (int i = 0; i < exts.length; i++)
652         {
653             templateEngineRegistry.put(exts[i], service);
654         }
655     }
656 
657     /***
658      * The {@link org.apache.turbine.services.template.TemplateEngineService}
659      * associated with the specified template's file extension.
660      *
661      * @param template The template name.
662      * @return The template engine service.
663      */
664     public TemplateEngineService getTemplateEngineService(String template)
665     {
666         return (TemplateEngineService) templateEngineRegistry.get(getExtension(template));
667     }
668 
669     /***
670      * Register a template Mapper to the service. This Mapper
671      * performs the template mapping and searching for a specific
672      * object type which is managed by the TemplateService.
673      *
674      * @param templateKey  One of the _KEY constants for the Template object types.
675      * @param mapper  An object which implements the Mapper interface.
676      */
677     private void registerMapper(int templateKey, Mapper mapper)
678     {
679         mapper.init();
680         mapperRegistry[templateKey] = mapper;
681     }
682 
683     /***
684      * Load and configure the Template mappers for
685      * the Template Service.
686      *
687      * @param conf The current configuration object.
688      * @throws InitializationException A problem occured trying to set up the mappers.
689      */
690     private void initMapper(Configuration conf)
691             throws InitializationException
692     {
693         // Create a registry with the number of Template Types managed by this service.
694         // We could use a List object here and extend the number of managed objects
695         // dynamically. However, by using an Object Array, we get much more performance
696         // out of the Template Service.
697         mapperRegistry = new Mapper [TEMPLATE_TYPES];
698 
699         String [] mapperNames = new String [] {
700             PAGE_NAME,SCREEN_NAME, LAYOUT_NAME,
701             NAVIGATION_NAME, LAYOUT_TEMPLATE_NAME, SCREEN_TEMPLATE_NAME, NAVIGATION_TEMPLATE_NAME
702         };
703 
704         String [] mapperClasses = new String [] {
705             DirectMapper.class.getName(),
706             ClassMapper.class.getName(),
707             ClassMapper.class.getName(),
708             ClassMapper.class.getName(),
709             LayoutTemplateMapper.class.getName(),
710             ScreenTemplateMapper.class.getName(),
711             DirectTemplateMapper.class.getName()
712         };
713 
714         int [] mapperCacheSize = new int [] {
715             0,
716             conf.getInt(
717                     TurbineConstants.SCREEN_CACHE_SIZE_KEY,
718                     TurbineConstants.SCREEN_CACHE_SIZE_DEFAULT),
719             conf.getInt(
720                     TurbineConstants.LAYOUT_CACHE_SIZE_KEY,
721                     TurbineConstants.LAYOUT_CACHE_SIZE_DEFAULT),
722             conf.getInt(
723                     TurbineConstants.NAVIGATION_CACHE_SIZE_KEY,
724                     TurbineConstants.NAVIGATION_CACHE_SIZE_DEFAULT),
725             conf.getInt(
726                     TurbineConstants.LAYOUT_CACHE_SIZE_KEY,
727                     TurbineConstants.LAYOUT_CACHE_SIZE_DEFAULT),
728             conf.getInt(
729                     TurbineConstants.SCREEN_CACHE_SIZE_KEY,
730                     TurbineConstants.SCREEN_CACHE_SIZE_DEFAULT),
731             conf.getInt(
732                     TurbineConstants.NAVIGATION_CACHE_SIZE_KEY,
733                     TurbineConstants.NAVIGATION_CACHE_SIZE_DEFAULT)
734         };
735 
736         String [] mapperDefaultProperty = new String [] {
737             TemplateEngineService.DEFAULT_PAGE,
738             TemplateEngineService.DEFAULT_SCREEN,
739             TemplateEngineService.DEFAULT_LAYOUT,
740             TemplateEngineService.DEFAULT_NAVIGATION,
741             TemplateEngineService.DEFAULT_LAYOUT_TEMPLATE,
742             TemplateEngineService.DEFAULT_SCREEN_TEMPLATE,
743             TemplateEngineService.DEFAULT_NAVIGATION_TEMPLATE
744         };
745 
746         char [] mapperSeparator = new char [] { '.', '.', '.', '.', '/', '/', '/' };
747 
748         Loader [] mapperLoader = new Loader [] { 
749             PageLoader.getInstance(),
750             ScreenLoader.getInstance(),
751             LayoutLoader.getInstance(),
752             NavigationLoader.getInstance(),
753             null, null, null};
754 
755         String [] mapperPrefix = new String [] { 
756             null, null, null, null,
757             TurbineConstants.LAYOUT_PREFIX,
758             TurbineConstants.SCREEN_PREFIX,
759             TurbineConstants.NAVIGATION_PREFIX  };
760 
761         for (int i = 0; i < TEMPLATE_TYPES; i++)
762         {
763             StringBuffer mapperProperty = new StringBuffer();
764             mapperProperty.append("mapper.");
765             mapperProperty.append(mapperNames[i]);
766             mapperProperty.append(".class");
767 
768             String mapperClass = 
769                     conf.getString(mapperProperty.toString(), mapperClasses[i]);
770 
771             log.info("Using " + mapperClass + " to map " + mapperNames[i] + " elements");
772 
773             Mapper tm = null;
774 
775             try
776             {
777     			   AvalonComponentService acs = (AvalonComponentService) TurbineServices.getInstance().getService(AvalonComponentService.SERVICE_NAME);
778     			   FactoryService factory = (FactoryService)acs.lookup(FactoryService.ROLE);
779     			   tm = (Mapper) factory.getInstance(mapperClass);
780             }
781             catch (FactoryException e) {
782             		throw new InitializationException("", e);
783 		    } 
784             catch (ServiceException se) {
785 				throw new InitializationException("Problem looking up Factory service",se);
786 			}
787 
788             tm.setUseCache(useCache);
789             tm.setCacheSize(mapperCacheSize[i]);
790             tm.setDefaultProperty(mapperDefaultProperty[i]);
791             tm.setSeparator(mapperSeparator[i]);
792 
793             if ((mapperLoader[i] != null) && (tm instanceof ClassMapper))
794             {
795                 ((ClassMapper) tm).setLoader(mapperLoader[i]);
796             }
797 
798             if ((mapperPrefix[i] != null) && (tm instanceof BaseTemplateMapper))
799             {
800                 ((BaseTemplateMapper) tm).setPrefix(mapperPrefix[i]);
801             }
802 
803             registerMapper(i, tm);
804         }
805     }
806 }