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