    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    }