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