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