View Javadoc

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