View Javadoc

    1   package org.apache.turbine.services.template;
    2
    3
    4   /*
    5    * Licensed to the Apache Software Foundation (ASF) under one
    6    * or more contributor license agreements.  See the NOTICE file
    7    * distributed with this work for additional information
    8    * regarding copyright ownership.  The ASF licenses this file
    9    * to you under the Apache License, Version 2.0 (the
    10   * "License"); you may not use this file except in compliance
    11   * with the License.  You may obtain a copy of the License at
    12   *
    13   *   http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing,
    16   * software distributed under the License is distributed on an
    17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    18   * KIND, either express or implied.  See the License for the
    19   * specific language governing permissions and limitations
    20   * under the License.
    21   */
    22
    23
    24  import java.io.File;
    25  import java.util.Collections;
    26  import java.util.HashMap;
    27  import java.util.Map;
    28
    29  import org.apache.commons.configuration.Configuration;
    30  import org.apache.commons.lang.StringUtils;
    31  import org.apache.commons.logging.Log;
    32  import org.apache.commons.logging.LogFactory;
    33  import org.apache.fulcrum.factory.FactoryException;
    34  import org.apache.fulcrum.factory.FactoryService;
    35  import org.apache.turbine.Turbine;
    36  import org.apache.turbine.TurbineConstants;
    37  import org.apache.turbine.modules.Layout;
    38  import org.apache.turbine.modules.Loader;
    39  import org.apache.turbine.modules.Navigation;
    40  import org.apache.turbine.modules.Page;
    41  import org.apache.turbine.modules.Screen;
    42  import org.apache.turbine.services.InitializationException;
    43  import org.apache.turbine.services.TurbineBaseService;
    44  import org.apache.turbine.services.TurbineServices;
    45  import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService;
    46  import org.apache.turbine.services.servlet.TurbineServlet;
    47  import org.apache.turbine.services.template.mapper.BaseTemplateMapper;
    48  import org.apache.turbine.services.template.mapper.ClassMapper;
    49  import org.apache.turbine.services.template.mapper.DirectMapper;
    50  import org.apache.turbine.services.template.mapper.DirectTemplateMapper;
    51  import org.apache.turbine.services.template.mapper.LayoutTemplateMapper;
    52  import org.apache.turbine.services.template.mapper.Mapper;
    53  import org.apache.turbine.services.template.mapper.ScreenTemplateMapper;
    54  import org.apache.turbine.util.RunData;
    55  import org.apache.turbine.util.uri.URIConstants;
    56
    57  /**
    58   * This service provides a method for mapping templates to their
    59   * appropriate Screens or Navigations.  It also allows templates to
    60   * define a layout/navigations/screen modularization within the
    61   * template structure.  It also performs caching if turned on in the
    62   * properties file.
    63   *
    64   * This service is not bound to a specific templating engine but we
    65   * will use the Velocity templating engine for the examples. It is
    66   * available by using the VelocityService.
    67   *
    68   * This assumes the following properties in the Turbine configuration:
    69   *
    70   * <pre>
    71   * # Register the VelocityService for the "vm" extension.
    72   * services.VelocityService.template.extension=vm
    73   *
    74   * # Default Java class for rendering a Page in this service
    75   * # (must be found on the class path (org.apache.turbine.modules.page.VelocityPage))
    76   * services.VelocityService.default.page = VelocityPage
    77   *
    78   * # Default Java class for rendering a Screen in this service
    79   * # (must be found on the class path (org.apache.turbine.modules.screen.VelocityScreen))
    80   * services.VelocityService.default.screen=VelocityScreen
    81   *
    82   * # Default Java class for rendering a Layout in this service
    83   * # (must be found on the class path (org.apache.turbine.modules.layout.VelocityOnlyLayout))
    84   * services.VelocityService.default.layout = VelocityOnlyLayout
    85   *
    86   * # Default Java class for rendering a Navigation in this service
    87   * # (must be found on the class path (org.apache.turbine.modules.navigation.VelocityNavigation))
    88   * services.VelocityService.default.navigation=VelocityNavigation
    89   *
    90   * # Default Template Name to be used as Layout. If nothing else is
    91   * # found, return this as the default name for a layout
    92   * services.VelocityService.default.layout.template = Default.vm
    93   * </pre>
    94   * If you want to render a template, a search path is used to find
    95   * a Java class which might provide information for the context of
    96   * this template.
    97   *
    98   * If you request e.g. the template screen
    99   *
    100  * about,directions,Driving.vm
    101  *
    102  * then the following class names are searched (on the module search
    103  * path):
    104  *
    105  * 1. about.directions.Driving     &lt;- direct matching the template to the class name
    106  * 2. about.directions.Default     &lt;- matching the package, class name is Default
    107  * 3. about.Default                &lt;- stepping up in the package hierarchy, looking for Default
    108  * 4. Default                      &lt;- Class called "Default" without package
    109  * 5. VelocityScreen               &lt;- The class configured by the Service (VelocityService) to
    110  *
    111  * And if you have the following module packages configured:
    112  *
    113  * module.packages = org.apache.turbine.modules, com.mycorp.modules
    114  *
    115  * then the class loader will look for
    116  *
    117  * org.apache.turbine.modules.screens.about.directions.Driving
    118  * com.mycorp.modules.screens.about.directions.Driving
    119  * org.apache.turbine.modules.screens.about.directions.Default
    120  * com.mycorp.modules.screens.about.directions.Default
    121  * org.apache.turbine.modules.screens.about.Default
    122  * com.mycorp.modules.screens.about.Default
    123  * org.apache.turbine.modules.screens.Default
    124  * com.mycorp.modules.screens.Default
    125  * org.apache.turbine.modules.screens.VelocityScreen
    126  * com.mycorp.modules.screens.VelocityScreen
    127  *
    128  * Most of the times, you don't have any backing Java class for a
    129  * template screen, so the first match will be
    130  * org.apache.turbine.modules.screens.VelocityScreen
    131  * which then renders your screen.
    132  *
    133  * Please note, that your Screen Template (Driving.vm) must exist!
    134  * If it does not exist, the Template Service will report an error.
    135  *
    136  * Once the screen is found, the template service will look for
    137  * the Layout and Navigation templates of your Screen. Here, the
    138  * template service looks for matching template names!
    139  *
    140  * Consider our example:  about,directions,Driving.vm (Screen Name)
    141  *
    142  * Now the template service will look for the following Navigation
    143  * and Layout templates:
    144  *
    145  * 1. about,directions,Driving.vm      &lt;- exact match
    146  * 2. about,directions,Default.vm      &lt;- package match, Default name
    147  * 3. about,Default.vm                 &lt;- stepping up in the hierarchy
    148  * 4. Default.vm                       &lt;- The name configured as default.layout.template
    149  *                                        in the Velocity service.
    150  *
    151  * And now Hennings' two golden rules for using templates:
    152  *
    153  * Many examples and docs from older Turbine code show template pathes
    154  * with a slashes. Repeat after me: "TEMPLATE NAMES NEVER CONTAIN SLASHES!"
    155  *
    156  * Many examples and docs from older Turbine code show templates that start
    157  * with "/". This is not only a violation of the rule above but actively breaks
    158  * things like loading templates from a jar with the velocity jar loader. Repeat
    159  * after me: "TEMPLATE NAMES ARE NOT PATHES. THEY'RE NOT ABSOLUTE AND HAVE NO
    160  * LEADING /".
    161  *
    162  * If you now wonder how a template name is mapped to a file name: This is
    163  * scope of the templating engine. Velocity e.g. has this wonderful option to
    164  * load templates from jar archives. There is no single file but you tell
    165  * velocity "get about,directions,Driving.vm" and it returns the rendered
    166  * template. This is not the job of the Templating Service but of the Template
    167  * rendering services like VelocityService.
    168  *
    169  * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
    170  * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a>
    171  * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    172  * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
    173  * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
    174  * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    175  * @version $Id: TurbineTemplateService.java 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 }