001    package org.apache.turbine.services.template;
002    
003    
004    /*
005     * Licensed to the Apache Software Foundation (ASF) under one
006     * or more contributor license agreements.  See the NOTICE file
007     * distributed with this work for additional information
008     * regarding copyright ownership.  The ASF licenses this file
009     * to you under the Apache License, Version 2.0 (the
010     * "License"); you may not use this file except in compliance
011     * with the License.  You may obtain a copy of the License at
012     *
013     *   http://www.apache.org/licenses/LICENSE-2.0
014     *
015     * Unless required by applicable law or agreed to in writing,
016     * software distributed under the License is distributed on an
017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018     * KIND, either express or implied.  See the License for the
019     * specific language governing permissions and limitations
020     * under the License.
021     */
022    
023    
024    import java.io.File;
025    import java.util.Collections;
026    import java.util.HashMap;
027    import java.util.Map;
028    
029    import org.apache.commons.configuration.Configuration;
030    import org.apache.commons.lang.StringUtils;
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    import org.apache.fulcrum.factory.FactoryException;
034    import org.apache.fulcrum.factory.FactoryService;
035    import org.apache.turbine.Turbine;
036    import org.apache.turbine.TurbineConstants;
037    import org.apache.turbine.modules.Layout;
038    import org.apache.turbine.modules.Loader;
039    import org.apache.turbine.modules.Navigation;
040    import org.apache.turbine.modules.Page;
041    import org.apache.turbine.modules.Screen;
042    import org.apache.turbine.services.InitializationException;
043    import org.apache.turbine.services.TurbineBaseService;
044    import org.apache.turbine.services.TurbineServices;
045    import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
046    import org.apache.turbine.services.servlet.TurbineServlet;
047    import org.apache.turbine.services.template.mapper.BaseTemplateMapper;
048    import org.apache.turbine.services.template.mapper.ClassMapper;
049    import org.apache.turbine.services.template.mapper.DirectMapper;
050    import org.apache.turbine.services.template.mapper.DirectTemplateMapper;
051    import org.apache.turbine.services.template.mapper.LayoutTemplateMapper;
052    import org.apache.turbine.services.template.mapper.Mapper;
053    import org.apache.turbine.services.template.mapper.ScreenTemplateMapper;
054    import org.apache.turbine.util.RunData;
055    import org.apache.turbine.util.uri.URIConstants;
056    
057    /**
058     * This service provides a method for mapping templates to their
059     * appropriate Screens or Navigations.  It also allows templates to
060     * define a layout/navigations/screen modularization within the
061     * template structure.  It also performs caching if turned on in the
062     * properties file.
063     *
064     * This service is not bound to a specific templating engine but we
065     * will use the Velocity templating engine for the examples. It is
066     * available by using the VelocityService.
067     *
068     * This assumes the following properties in the Turbine configuration:
069     *
070     * <pre>
071     * # Register the VelocityService for the "vm" extension.
072     * services.VelocityService.template.extension=vm
073     *
074     * # Default Java class for rendering a Page in this service
075     * # (must be found on the class path (org.apache.turbine.modules.page.VelocityPage))
076     * services.VelocityService.default.page = VelocityPage
077     *
078     * # Default Java class for rendering a Screen in this service
079     * # (must be found on the class path (org.apache.turbine.modules.screen.VelocityScreen))
080     * services.VelocityService.default.screen=VelocityScreen
081     *
082     * # Default Java class for rendering a Layout in this service
083     * # (must be found on the class path (org.apache.turbine.modules.layout.VelocityOnlyLayout))
084     * services.VelocityService.default.layout = VelocityOnlyLayout
085     *
086     * # Default Java class for rendering a Navigation in this service
087     * # (must be found on the class path (org.apache.turbine.modules.navigation.VelocityNavigation))
088     * services.VelocityService.default.navigation=VelocityNavigation
089     *
090     * # Default Template Name to be used as Layout. If nothing else is
091     * # found, return this as the default name for a layout
092     * services.VelocityService.default.layout.template = Default.vm
093     * </pre>
094     * If you want to render a template, a search path is used to find
095     * a Java class which might provide information for the context of
096     * this template.
097     *
098     * If you request e.g. the template screen
099     *
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 1078552 2011-03-06 19:58:46Z 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 Screen Objects */
188        public static final int SCREEN_KEY = 1;
189    
190        /** Represents Layout Objects */
191        public static final int LAYOUT_KEY = 2;
192    
193        /** Represents Navigation Objects */
194        public static final int NAVIGATION_KEY = 3;
195    
196        /** Represents Layout Template Objects */
197        public static final int LAYOUT_TEMPLATE_KEY = 4;
198    
199        /** Represents Layout Template Objects */
200        public static final String LAYOUT_TEMPLATE_NAME = "layout.template";
201    
202        /** Represents Screen Template Objects */
203        public static final int SCREEN_TEMPLATE_KEY = 5;
204    
205        /** Represents Screen Template Objects */
206        public static final String SCREEN_TEMPLATE_NAME = "screen.template";
207    
208        /** Represents Navigation Template Objects */
209        public static final int NAVIGATION_TEMPLATE_KEY = 6;
210    
211        /** Represents Navigation Template Objects */
212        public static final String NAVIGATION_TEMPLATE_NAME = "navigation.template";
213    
214        /** Number of different Template Types that we know of */
215        public static final int TEMPLATE_TYPES = 7;
216    
217        /** Here we register the mapper objects for our various object types */
218        private Mapper [] mapperRegistry = null;
219    
220        /**
221         * The default file extension used as a registry key when a
222         * template's file extension cannot be determined.
223         *
224         * @deprecated. Use TemplateService.DEFAULT_EXTENSION_VALUE.
225         */
226        protected static final String NO_FILE_EXT = TemplateService.DEFAULT_EXTENSION_VALUE;
227    
228    
229        /** Flag set if cache is to be used. */
230        private boolean useCache = false;
231    
232        /** Default extension for templates. */
233        private String defaultExtension;
234    
235        /** Default template without the default extension. */
236        private String defaultTemplate;
237    
238        /**
239         * The mappings of template file extensions to {@link
240         * org.apache.turbine.services.template.TemplateEngineService}
241         * implementations. Implementing template engines can locate
242         * templates within the capability of any resource loaders they
243         * may possess, and other template engines are stuck with file
244         * based template hierarchy only.
245         */
246        private Map<String, TemplateEngineService> templateEngineRegistry = null;
247    
248        /**
249         * C'tor
250         */
251        public TurbineTemplateService()
252        {
253            // empty
254        }
255    
256        /**
257         * Called the first time the Service is used.
258         *
259         * @exception InitializationException Something went wrong when
260         *                                     setting up the Template Service.
261         */
262        @Override
263        public void init()
264            throws InitializationException
265        {
266            // Get the configuration for the template service.
267            Configuration config = getConfiguration();
268    
269            // Get the default extension to use if nothing else is applicable.
270            defaultExtension = config.getString(TemplateService.DEFAULT_EXTENSION_KEY,
271                TemplateService.DEFAULT_EXTENSION_VALUE);
272    
273            defaultTemplate =  config.getString(TemplateService.DEFAULT_TEMPLATE_KEY,
274                TemplateService.DEFAULT_TEMPLATE_VALUE);
275    
276            // Check to see if we are going to be caching modules.
277            // Aaargh, who moved this _out_ of the TemplateService package?
278            useCache = Turbine.getConfiguration().getBoolean(TurbineConstants.MODULE_CACHE_KEY,
279                TurbineConstants.MODULE_CACHE_DEFAULT);
280    
281            log.debug("Default Extension: " + defaultExtension);
282            log.debug("Default Template:  " + defaultTemplate);
283            log.debug("Use Caching:       " + useCache);
284    
285            templateEngineRegistry = Collections.synchronizedMap(new HashMap<String, TemplateEngineService>());
286    
287            initMapper(config);
288            setInit(true);
289        }
290    
291        /**
292         * Returns true if the Template Service has caching activated
293         *
294         * @return true if Caching is active.
295         */
296        public boolean isCaching()
297        {
298            return useCache;
299        }
300    
301        /**
302         * Get the default template name extension specified
303         * in the template service properties. If no extension
304         * is defined, return the empty string.
305         *
306         * @return The default extension.
307         */
308        public String getDefaultExtension()
309        {
310            return StringUtils.isNotEmpty(defaultExtension) ? defaultExtension : "";
311        }
312    
313        /**
314         * Return Extension for a supplied template
315         *
316         * @param template The template name
317         *
318         * @return extension The extension for the supplied template
319         */
320        public String getExtension(String template)
321        {
322            if (StringUtils.isEmpty(template))
323            {
324                return getDefaultExtension();
325            }
326    
327            int dotIndex = template.indexOf(EXTENSION_SEPARATOR);
328    
329            return (dotIndex < 0) ? getDefaultExtension() : template.substring(dotIndex + 1);
330        }
331    
332    
333        /**
334         * Returns the Default Template Name with the Default Extension.
335         * If the extension is unset, return only the template name
336         *
337         * @return The default template Name
338         */
339        public String getDefaultTemplate()
340        {
341            StringBuffer sb = new StringBuffer();
342            sb.append(defaultTemplate);
343            if (StringUtils.isNotEmpty(defaultExtension))
344            {
345                sb.append(EXTENSION_SEPARATOR);
346                sb.append(getDefaultExtension());
347            }
348            return sb.toString();
349        }
350    
351        /**
352         * Get the default page module name of the template engine
353         * service corresponding to the default template name extension.
354         *
355         * @return The default page module name.
356         */
357        public String getDefaultPage()
358        {
359            return getDefaultPageName(getDefaultTemplate());
360        }
361    
362        /**
363         * Get the default screen module name of the template engine
364         * service corresponding to the default template name extension.
365         *
366         * @return The default screen module name.
367         */
368        public String getDefaultScreen()
369        {
370            return getDefaultScreenName(getDefaultTemplate());
371        }
372    
373        /**
374         * Get the default layout module name of the template engine
375         * service corresponding to the default template name extension.
376         *
377         * @return The default layout module name.
378         */
379        public String getDefaultLayout()
380        {
381            return getDefaultLayoutName(getDefaultTemplate());
382        }
383    
384        /**
385         * Get the default navigation module name of the template engine
386         * service corresponding to the default template name extension.
387         *
388         * @return The default navigation module name.
389         */
390        public String getDefaultNavigation()
391        {
392            return getDefaultNavigationName(getDefaultTemplate());
393        }
394    
395        /**
396         * Get the default layout template name of the template engine
397         * service corresponding to the default template name extension.
398         *
399         * @return The default layout template name.
400         */
401        public String getDefaultLayoutTemplate()
402        {
403            return getDefaultLayoutTemplateName(getDefaultTemplate());
404        }
405    
406        /**
407         * Get the default page module name of the template engine
408         * service corresponding to the template name extension of
409         * the named template.
410         *
411         * @param template The template name.
412         * @return The default page module name.
413         */
414        public String getDefaultPageName(String template)
415        {
416            return (mapperRegistry[PAGE_KEY]).getDefaultName(template);
417        }
418    
419        /**
420         * Get the default screen module name of the template engine
421         * service corresponding to the template name extension of
422         * the named template.
423         *
424         * @param template The template name.
425         * @return The default screen module name.
426         */
427        public String getDefaultScreenName(String template)
428        {
429            return (mapperRegistry[SCREEN_KEY]).getDefaultName(template);
430        }
431    
432        /**
433         * Get the default layout module name of the template engine
434         * service corresponding to the template name extension of
435         * the named template.
436         *
437         * @param template The template name.
438         * @return The default layout module name.
439         */
440        public String getDefaultLayoutName(String template)
441        {
442            return (mapperRegistry[LAYOUT_KEY]).getDefaultName(template);
443        }
444    
445        /**
446         * Get the default navigation module name of the template engine
447         * service corresponding to the template name extension of
448         * the named template.
449         *
450         * @param template The template name.
451         * @return The default navigation module name.
452         */
453        public String getDefaultNavigationName(String template)
454        {
455            return (mapperRegistry[NAVIGATION_KEY]).getDefaultName(template);
456        }
457    
458        /**
459         * Get the default layout template name of the template engine
460         * service corresponding to the template name extension of
461         * the named template.
462         *
463         * @param template The template name.
464         * @return The default layout template name.
465         */
466        public String getDefaultLayoutTemplateName(String template)
467        {
468            return (mapperRegistry[LAYOUT_TEMPLATE_KEY]).getDefaultName(template);
469        }
470    
471        /**
472         * Find the default page module name for the given request.
473         *
474         * @param data The encapsulation of the request to retrieve the
475         *             default page for.
476         * @return The default page module name.
477         */
478        public String getDefaultPageName(RunData data)
479        {
480            String template = data.getParameters().get(URIConstants.CGI_TEMPLATE_PARAM);
481            return (template != null) ?
482                getDefaultPageName(template) : getDefaultPage();
483        }
484    
485        /**
486         * Find the default layout module name for the given request.
487         *
488         * @param data The encapsulation of the request to retrieve the
489         *             default layout for.
490         * @return The default layout module name.
491         */
492        public String getDefaultLayoutName(RunData data)
493        {
494            String template = data.getParameters().get(URIConstants.CGI_TEMPLATE_PARAM);
495            return (template != null) ?
496                getDefaultLayoutName(template) : getDefaultLayout();
497        }
498    
499        /**
500         * Locate and return the name of the screen module to be used
501         * with the named screen template.
502         *
503         * @param template The screen template name.
504         * @return The found screen module name.
505         * @exception Exception, a generic exception.
506         */
507        public String getScreenName(String template)
508            throws Exception
509        {
510            return (mapperRegistry[SCREEN_KEY]).getMappedName(template);
511        }
512    
513        /**
514         * Locate and return the name of the layout module to be used
515         * with the named layout template.
516         *
517         * @param template The layout template name.
518         * @return The found layout module name.
519         * @exception Exception, a generic exception.
520         */
521        public String getLayoutName(String template)
522            throws Exception
523        {
524            return (mapperRegistry[LAYOUT_KEY]).getMappedName(template);
525        }
526    
527        /**
528         * Locate and return the name of the navigation module to be used
529         * with the named navigation template.
530         *
531         * @param template The navigation template name.
532         * @return The found navigation module name.
533         * @exception Exception, a generic exception.
534         */
535        public String getNavigationName(String template)
536            throws Exception
537        {
538            return (mapperRegistry[NAVIGATION_KEY]).getMappedName(template);
539        }
540    
541        /**
542         * Locate and return the name of the screen template corresponding
543         * to the given template name parameter. This might return null if
544         * the screen is not found!
545         *
546         * @param template The template name parameter.
547         * @return The found screen template name.
548         * @exception Exception, a generic exception.
549         */
550        public String getScreenTemplateName(String template)
551            throws Exception
552        {
553            return (mapperRegistry[SCREEN_TEMPLATE_KEY]).getMappedName(template);
554        }
555    
556        /**
557         * Locate and return the name of the layout template corresponding
558         * to the given screen template name parameter.
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 getLayoutTemplateName(String template)
565            throws Exception
566        {
567            return (mapperRegistry[LAYOUT_TEMPLATE_KEY]).getMappedName(template);
568        }
569    
570        /**
571         * Locate and return the name of the navigation template corresponding
572         * to the given template name parameter. This might return null if
573         * the navigation is not found!
574         *
575         * @param template The template name parameter.
576         * @return The found navigation template name.
577         * @exception Exception, a generic exception.
578         */
579        public String getNavigationTemplateName(String template)
580            throws Exception
581        {
582            return (mapperRegistry[NAVIGATION_TEMPLATE_KEY]).getMappedName(template);
583        }
584    
585        /**
586         * Translates the supplied template paths into their Turbine-canonical
587         * equivalent (probably absolute paths). This is used if the templating
588         * engine (e.g. JSP) does not provide any means to load a page but
589         * the page path is passed to the servlet container.
590         *
591         * @param templatePaths An array of template paths.
592         * @return An array of translated template paths.
593         * @deprecated Each template engine service should know how to translate
594         *             a request onto a file.
595         */
596        @Deprecated
597        public String[] translateTemplatePaths(String[] templatePaths)
598        {
599            for (int i = 0; i < templatePaths.length; i++)
600            {
601                templatePaths[i] = TurbineServlet.getRealPath(templatePaths[i]);
602            }
603            return templatePaths;
604        }
605    
606        /**
607         * Delegates to the appropriate {@link
608         * org.apache.turbine.services.template.TemplateEngineService} to
609         * check the existance of the specified template.
610         *
611         * @param template The template to check for the existance of.
612         * @param templatePaths The paths to check for the template.
613         * @deprecated Use templateExists from the various Templating Engines
614         */
615        @Deprecated
616        public boolean templateExists(String template,
617            String[] templatePaths)
618        {
619            for (int i = 0; i < templatePaths.length; i++)
620            {
621                if (new File(templatePaths[i], template).exists())
622                {
623                    return true;
624                }
625            }
626            return false;
627        }
628    
629        /**
630         * Registers the provided template engine for use by the
631         * <code>TemplateService</code>.
632         *
633         * @param service The <code>TemplateEngineService</code> to register.
634         */
635        public synchronized void registerTemplateEngineService(TemplateEngineService service)
636        {
637            String[] exts = service.getAssociatedFileExtensions();
638    
639            for (int i = 0; i < exts.length; i++)
640            {
641                templateEngineRegistry.put(exts[i], service);
642            }
643        }
644    
645        /**
646         * The {@link org.apache.turbine.services.template.TemplateEngineService}
647         * associated with the specified template's file extension.
648         *
649         * @param template The template name.
650         * @return The template engine service.
651         */
652        public TemplateEngineService getTemplateEngineService(String template)
653        {
654            return templateEngineRegistry.get(getExtension(template));
655        }
656    
657        /**
658         * Register a template Mapper to the service. This Mapper
659         * performs the template mapping and searching for a specific
660         * object type which is managed by the TemplateService.
661         *
662         * @param templateKey  One of the _KEY constants for the Template object types.
663         * @param mapper  An object which implements the Mapper interface.
664         */
665        private void registerMapper(int templateKey, Mapper mapper)
666        {
667            mapper.init();
668            mapperRegistry[templateKey] = mapper;
669        }
670    
671        /**
672         * Load and configure the Template mappers for
673         * the Template Service.
674         *
675         * @param conf The current configuration object.
676         * @throws InitializationException A problem occured trying to set up the mappers.
677         */
678        private void initMapper(Configuration conf)
679                throws InitializationException
680        {
681            // Create a registry with the number of Template Types managed by this service.
682            // We could use a List object here and extend the number of managed objects
683            // dynamically. However, by using an Object Array, we get much more performance
684            // out of the Template Service.
685            mapperRegistry = new Mapper[TEMPLATE_TYPES];
686    
687            String [] mapperNames = new String [] {
688                Page.NAME, Screen.NAME, Layout.NAME, Navigation.NAME,
689                LAYOUT_TEMPLATE_NAME, SCREEN_TEMPLATE_NAME, NAVIGATION_TEMPLATE_NAME
690            };
691    
692            String [] mapperKeys = new String [] {
693                Page.NAME, Screen.NAME, Layout.NAME, Navigation.NAME,
694                Layout.NAME, Screen.NAME, Navigation.NAME
695            };
696    
697            String [] mapperClasses = new String [] {
698                DirectMapper.class.getName(),
699                ClassMapper.class.getName(),
700                ClassMapper.class.getName(),
701                ClassMapper.class.getName(),
702                LayoutTemplateMapper.class.getName(),
703                ScreenTemplateMapper.class.getName(),
704                DirectTemplateMapper.class.getName()
705            };
706    
707            AssemblerBrokerService ab = (AssemblerBrokerService)TurbineServices.getInstance()
708                                            .getService(AssemblerBrokerService.SERVICE_NAME);
709    
710            int [] mapperCacheSize = new int [mapperKeys.length];
711            Loader [] mapperLoader = new Loader [mapperKeys.length];
712    
713            for (int i = 0; i < mapperKeys.length; i++)
714            {
715                mapperLoader[i] = ab.getLoader(mapperKeys[i]);
716                mapperCacheSize[i] = (mapperLoader[i] != null) ? mapperLoader[i].getCacheSize() : 0;
717            }
718    
719            // HACK: to achieve the same behaviour as before
720            mapperLoader[LAYOUT_TEMPLATE_KEY] = null;
721            mapperLoader[SCREEN_TEMPLATE_KEY] = null;
722            mapperLoader[NAVIGATION_TEMPLATE_KEY] = null;
723    
724            String [] mapperDefaultProperty = new String [] {
725                TemplateEngineService.DEFAULT_PAGE,
726                TemplateEngineService.DEFAULT_SCREEN,
727                TemplateEngineService.DEFAULT_LAYOUT,
728                TemplateEngineService.DEFAULT_NAVIGATION,
729                TemplateEngineService.DEFAULT_LAYOUT_TEMPLATE,
730                TemplateEngineService.DEFAULT_SCREEN_TEMPLATE,
731                TemplateEngineService.DEFAULT_NAVIGATION_TEMPLATE
732            };
733    
734            char [] mapperSeparator = new char [] { '.', '.', '.', '.', '/', '/', '/' };
735    
736            String [] mapperPrefix = new String [] {
737                null, null, null, null,
738                Layout.PREFIX,
739                Screen.PREFIX,
740                Navigation.PREFIX  };
741    
742            for (int i = 0; i < TEMPLATE_TYPES; i++)
743            {
744                StringBuffer mapperProperty = new StringBuffer();
745                mapperProperty.append("mapper.");
746                mapperProperty.append(mapperNames[i]);
747                mapperProperty.append(".class");
748    
749                String mapperClass =
750                        conf.getString(mapperProperty.toString(), mapperClasses[i]);
751    
752                log.info("Using " + mapperClass + " to map " + mapperNames[i] + " elements");
753    
754                Mapper tm = null;
755    
756                try
757                {
758                        FactoryService factory = (FactoryService)TurbineServices.getInstance().getService(FactoryService.ROLE);
759                        tm = (Mapper) factory.getInstance(mapperClass);
760                }
761                catch (FactoryException e)
762                {
763                            throw new InitializationException("", e);
764                        }
765    
766                tm.setUseCache(useCache);
767                tm.setCacheSize(mapperCacheSize[i]);
768                tm.setDefaultProperty(mapperDefaultProperty[i]);
769                tm.setSeparator(mapperSeparator[i]);
770    
771                if ((mapperLoader[i] != null) && (tm instanceof ClassMapper))
772                {
773                    ((ClassMapper) tm).setLoader(mapperLoader[i]);
774                }
775    
776                if ((mapperPrefix[i] != null) && (tm instanceof BaseTemplateMapper))
777                {
778                    ((BaseTemplateMapper) tm).setPrefix(mapperPrefix[i]);
779                }
780    
781                registerMapper(i, tm);
782            }
783        }
784    }