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.concurrent.ConcurrentHashMap; 026import java.util.concurrent.ConcurrentMap; 027 028import org.apache.commons.configuration.Configuration; 029import org.apache.commons.lang.StringUtils; 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.apache.fulcrum.factory.FactoryException; 033import org.apache.fulcrum.factory.FactoryService; 034import org.apache.fulcrum.parser.ParameterParser; 035import org.apache.turbine.Turbine; 036import org.apache.turbine.TurbineConstants; 037import org.apache.turbine.modules.Assembler; 038import org.apache.turbine.modules.Layout; 039import org.apache.turbine.modules.Loader; 040import org.apache.turbine.modules.Navigation; 041import org.apache.turbine.modules.Page; 042import org.apache.turbine.modules.Screen; 043import org.apache.turbine.pipeline.PipelineData; 044import org.apache.turbine.services.InitializationException; 045import org.apache.turbine.services.TurbineBaseService; 046import org.apache.turbine.services.TurbineServices; 047import org.apache.turbine.services.assemblerbroker.AssemblerBrokerService; 048import org.apache.turbine.services.servlet.ServletService; 049import org.apache.turbine.services.template.mapper.BaseTemplateMapper; 050import org.apache.turbine.services.template.mapper.ClassMapper; 051import org.apache.turbine.services.template.mapper.DirectMapper; 052import org.apache.turbine.services.template.mapper.DirectTemplateMapper; 053import org.apache.turbine.services.template.mapper.LayoutTemplateMapper; 054import org.apache.turbine.services.template.mapper.Mapper; 055import org.apache.turbine.services.template.mapper.ScreenTemplateMapper; 056import org.apache.turbine.util.uri.URIConstants; 057 058/** 059 * This service provides a method for mapping templates to their 060 * appropriate Screens or Navigations. It also allows templates to 061 * define a layout/navigations/screen modularization within the 062 * template structure. It also performs caching if turned on in the 063 * properties file. 064 * 065 * This service is not bound to a specific templating engine but we 066 * will use the Velocity templating engine for the examples. It is 067 * available by using the VelocityService. 068 * 069 * This assumes the following properties in the Turbine configuration: 070 * 071 * <pre> 072 * # Register the VelocityService for the "vm" extension. 073 * services.VelocityService.template.extension=vm 074 * 075 * # Default Java class for rendering a Page in this service 076 * # (must be found on the class path (org.apache.turbine.modules.page.VelocityPage)) 077 * services.VelocityService.default.page = VelocityPage 078 * 079 * # Default Java class for rendering a Screen in this service 080 * # (must be found on the class path (org.apache.turbine.modules.screen.VelocityScreen)) 081 * services.VelocityService.default.screen=VelocityScreen 082 * 083 * # Default Java class for rendering a Layout in this service 084 * # (must be found on the class path (org.apache.turbine.modules.layout.VelocityOnlyLayout)) 085 * services.VelocityService.default.layout = VelocityOnlyLayout 086 * 087 * # Default Java class for rendering a Navigation in this service 088 * # (must be found on the class path (org.apache.turbine.modules.navigation.VelocityNavigation)) 089 * services.VelocityService.default.navigation=VelocityNavigation 090 * 091 * # Default Template Name to be used as Layout. If nothing else is 092 * # found, return this as the default name for a layout 093 * services.VelocityService.default.layout.template = Default.vm 094 * </pre> 095 * If you want to render a template, a search path is used to find 096 * a Java class which might provide information for the context of 097 * this template. 098 * 099 * 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 <- direct matching the template to the class name 107 * 2. about.directions.Default <- matching the package, class name is Default 108 * 3. about.Default <- stepping up in the package hierarchy, looking for Default 109 * 4. Default <- Class called "Default" without package 110 * 5. VelocityScreen <- 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 <- exact match 149 * 2. about,directions,Default.vm <- package match, Default name 150 * 3. about,Default.vm <- stepping up in the hierarchy 151 * 4. Default.vm <- 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 1773378 2016-12-09 13:19:59Z tv $ 179 */ 180public class TurbineTemplateService 181 extends TurbineBaseService 182 implements TemplateService 183{ 184 /** Logging */ 185 private static Log log = LogFactory.getLog(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 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 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 private ConcurrentMap<String, TemplateEngineService> templateEngineRegistry = null; 256 257 /** 258 * C'tor 259 */ 260 public TurbineTemplateService() 261 { 262 // empty 263 } 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 Configuration config = getConfiguration(); 277 278 servletService = (ServletService)TurbineServices.getInstance().getService(ServletService.SERVICE_NAME); 279 280 // Get the default extension to use if nothing else is applicable. 281 defaultExtension = config.getString(TemplateService.DEFAULT_EXTENSION_KEY, 282 TemplateService.DEFAULT_EXTENSION_VALUE); 283 284 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 useCache = Turbine.getConfiguration().getBoolean(TurbineConstants.MODULE_CACHE_KEY, 290 TurbineConstants.MODULE_CACHE_DEFAULT); 291 292 log.debug("Default Extension: " + defaultExtension); 293 log.debug("Default Template: " + defaultTemplate); 294 log.debug("Use Caching: " + useCache); 295 296 templateEngineRegistry = new ConcurrentHashMap<String, TemplateEngineService>(); 297 298 initMapper(config); 299 setInit(true); 300 } 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 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 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 if (StringUtils.isEmpty(template)) 337 { 338 return getDefaultExtension(); 339 } 340 341 int dotIndex = template.lastIndexOf(EXTENSION_SEPARATOR); 342 343 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 StringBuilder sb = new StringBuilder(); 357 sb.append(defaultTemplate); 358 if (StringUtils.isNotEmpty(defaultExtension)) 359 { 360 sb.append(EXTENSION_SEPARATOR); 361 sb.append(getDefaultExtension()); 362 } 363 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 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 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 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 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 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 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 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 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 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 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 ParameterParser pp = pipelineData.get(Turbine.class, ParameterParser.class); 507 String template = pp.get(URIConstants.CGI_TEMPLATE_PARAM); 508 return (template != null) ? 509 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) ? 525 getDefaultLayoutName(template) : getDefaultLayout(); 526 } 527 528 /** 529 * Locate and return the name of the screen module to be used 530 * with the named screen template. 531 * 532 * @param template The screen template name. 533 * @return The found screen module name. 534 * @throws Exception a generic exception. 535 */ 536 @Override 537 public String getScreenName(String template) 538 throws Exception 539 { 540 return (mapperRegistry[SCREEN_KEY]).getMappedName(template); 541 } 542 543 /** 544 * Locate and return the name of the layout module to be used 545 * with the named layout template. 546 * 547 * @param template The layout template name. 548 * @return The found layout module name. 549 * @throws Exception a generic exception. 550 */ 551 @Override 552 public String getLayoutName(String template) 553 throws Exception 554 { 555 return (mapperRegistry[LAYOUT_KEY]).getMappedName(template); 556 } 557 558 /** 559 * Locate and return the name of the navigation module to be used 560 * with the named navigation template. 561 * 562 * @param template The navigation template name. 563 * @return The found navigation module name. 564 * @throws Exception a generic exception. 565 */ 566 @Override 567 public String getNavigationName(String template) 568 throws Exception 569 { 570 return (mapperRegistry[NAVIGATION_KEY]).getMappedName(template); 571 } 572 573 /** 574 * Locate and return the name of the screen template corresponding 575 * to the given template name parameter. This might return null if 576 * the screen is not found! 577 * 578 * @param template The template name parameter. 579 * @return The found screen template name. 580 * @throws Exception a generic exception. 581 */ 582 @Override 583 public String getScreenTemplateName(String template) 584 throws Exception 585 { 586 return (mapperRegistry[SCREEN_TEMPLATE_KEY]).getMappedName(template); 587 } 588 589 /** 590 * Locate and return the name of the layout template corresponding 591 * to the given screen template name parameter. 592 * 593 * @param template The template name parameter. 594 * @return The found screen template name. 595 * @throws Exception a generic exception. 596 */ 597 @Override 598 public String getLayoutTemplateName(String template) 599 throws Exception 600 { 601 return (mapperRegistry[LAYOUT_TEMPLATE_KEY]).getMappedName(template); 602 } 603 604 /** 605 * Locate and return the name of the navigation template corresponding 606 * to the given template name parameter. This might return null if 607 * the navigation is not found! 608 * 609 * @param template The template name parameter. 610 * @return The found navigation template name. 611 * @throws Exception a generic exception. 612 */ 613 @Override 614 public String getNavigationTemplateName(String template) 615 throws Exception 616 { 617 return (mapperRegistry[NAVIGATION_TEMPLATE_KEY]).getMappedName(template); 618 } 619 620 /** 621 * Translates the supplied template paths into their Turbine-canonical 622 * equivalent (probably absolute paths). This is used if the templating 623 * engine (e.g. JSP) does not provide any means to load a page but 624 * the page path is passed to the servlet container. 625 * 626 * @param templatePaths An array of template paths. 627 * @return An array of translated template paths. 628 * @deprecated Each template engine service should know how to translate 629 * a request onto a file. 630 */ 631 @Override 632 @Deprecated 633 public String[] translateTemplatePaths(String[] templatePaths) 634 { 635 for (int i = 0; i < templatePaths.length; i++) 636 { 637 templatePaths[i] = servletService.getRealPath(templatePaths[i]); 638 } 639 return templatePaths; 640 } 641 642 /** 643 * Delegates to the appropriate {@link 644 * org.apache.turbine.services.template.TemplateEngineService} to 645 * check the existence of the specified template. 646 * 647 * @param template The template to check for the existence of. 648 * @param templatePaths The paths to check for the template. 649 * @deprecated Use templateExists from the various Templating Engines 650 */ 651 @Override 652 @Deprecated 653 public boolean templateExists(String template, String[] templatePaths) 654 { 655 for (String templatePath : templatePaths) 656 { 657 if (new File(templatePath, template).exists()) 658 { 659 return true; 660 } 661 } 662 return false; 663 } 664 665 /** 666 * Registers the provided template engine for use by the 667 * <code>TemplateService</code>. 668 * 669 * @param service The <code>TemplateEngineService</code> to register. 670 */ 671 @Override 672 public void registerTemplateEngineService(TemplateEngineService service) 673 { 674 String[] exts = service.getAssociatedFileExtensions(); 675 676 for (String ext : exts) 677 { 678 templateEngineRegistry.put(ext, service); 679 } 680 } 681 682 /** 683 * The {@link org.apache.turbine.services.template.TemplateEngineService} 684 * associated with the specified template's file extension. 685 * 686 * @param template The template name. 687 * @return The template engine service. 688 */ 689 @Override 690 public TemplateEngineService getTemplateEngineService(String template) 691 { 692 return templateEngineRegistry.get(getExtension(template)); 693 } 694 695 /** 696 * Register a template Mapper to the service. This Mapper 697 * performs the template mapping and searching for a specific 698 * object type which is managed by the TemplateService. 699 * 700 * @param templateKey One of the _KEY constants for the Template object types. 701 * @param mapper An object which implements the Mapper interface. 702 */ 703 private void registerMapper(int templateKey, Mapper mapper) 704 { 705 mapper.init(); 706 mapperRegistry[templateKey] = mapper; 707 } 708 709 /** 710 * Load and configure the Template mappers for 711 * the Template Service. 712 * 713 * @param conf The current configuration object. 714 * @throws InitializationException A problem occurred trying to set up the mappers. 715 */ 716 @SuppressWarnings("unchecked") 717 private void initMapper(Configuration conf) 718 throws InitializationException 719 { 720 // Create a registry with the number of Template Types managed by this service. 721 // We could use a List object here and extend the number of managed objects 722 // dynamically. However, by using an Object Array, we get much more performance 723 // out of the Template Service. 724 mapperRegistry = new Mapper[TEMPLATE_TYPES]; 725 726 String [] mapperNames = new String [] { 727 Page.NAME, Screen.NAME, Layout.NAME, Navigation.NAME, 728 LAYOUT_TEMPLATE_NAME, SCREEN_TEMPLATE_NAME, NAVIGATION_TEMPLATE_NAME 729 }; 730 731 Class<?> [] mapperKeys = new Class<?> [] { 732 Page.class, Screen.class, Layout.class, Navigation.class, 733 Layout.class, Screen.class, Navigation.class 734 }; 735 736 String [] mapperClasses = new String [] { 737 DirectMapper.class.getName(), 738 ClassMapper.class.getName(), 739 ClassMapper.class.getName(), 740 ClassMapper.class.getName(), 741 LayoutTemplateMapper.class.getName(), 742 ScreenTemplateMapper.class.getName(), 743 DirectTemplateMapper.class.getName() 744 }; 745 746 AssemblerBrokerService ab = (AssemblerBrokerService)TurbineServices.getInstance() 747 .getService(AssemblerBrokerService.SERVICE_NAME); 748 749 int [] mapperCacheSize = new int [mapperKeys.length]; 750 Loader<? extends Assembler> [] mapperLoader = new Loader<?>[mapperKeys.length]; 751 752 for (int i = 0; i < mapperKeys.length; i++) 753 { 754 mapperLoader[i] = ab.getLoader((Class<? extends Assembler>)mapperKeys[i]); 755 mapperCacheSize[i] = (mapperLoader[i] != null) ? mapperLoader[i].getCacheSize() : 0; 756 } 757 758 // HACK: to achieve the same behavior as before 759 mapperLoader[LAYOUT_TEMPLATE_KEY] = null; 760 mapperLoader[SCREEN_TEMPLATE_KEY] = null; 761 mapperLoader[NAVIGATION_TEMPLATE_KEY] = null; 762 763 String [] mapperDefaultProperty = new String [] { 764 TemplateEngineService.DEFAULT_PAGE, 765 TemplateEngineService.DEFAULT_SCREEN, 766 TemplateEngineService.DEFAULT_LAYOUT, 767 TemplateEngineService.DEFAULT_NAVIGATION, 768 TemplateEngineService.DEFAULT_LAYOUT_TEMPLATE, 769 TemplateEngineService.DEFAULT_SCREEN_TEMPLATE, 770 TemplateEngineService.DEFAULT_NAVIGATION_TEMPLATE 771 }; 772 773 char [] mapperSeparator = new char [] { '.', '.', '.', '.', '/', '/', '/' }; 774 775 String [] mapperPrefix = new String [] { 776 null, null, null, null, 777 Layout.PREFIX, 778 Screen.PREFIX, 779 Navigation.PREFIX }; 780 781 for (int i = 0; i < TEMPLATE_TYPES; i++) 782 { 783 StringBuilder mapperProperty = new StringBuilder(); 784 mapperProperty.append("mapper."); 785 mapperProperty.append(mapperNames[i]); 786 mapperProperty.append(".class"); 787 788 String mapperClass = 789 conf.getString(mapperProperty.toString(), mapperClasses[i]); 790 791 log.info("Using " + mapperClass + " to map " + mapperNames[i] + " elements"); 792 793 Mapper tm = null; 794 795 try 796 { 797 FactoryService factory = (FactoryService)TurbineServices.getInstance().getService(FactoryService.ROLE); 798 tm = factory.getInstance(mapperClass); 799 } 800 catch (FactoryException e) 801 { 802 throw new InitializationException("", e); 803 } 804 805 tm.setUseCache(useCache); 806 tm.setCacheSize(mapperCacheSize[i]); 807 tm.setDefaultProperty(mapperDefaultProperty[i]); 808 tm.setSeparator(mapperSeparator[i]); 809 810 if ((mapperLoader[i] != null) && (tm instanceof ClassMapper)) 811 { 812 ((ClassMapper) tm).setLoader(mapperLoader[i]); 813 } 814 815 if ((mapperPrefix[i] != null) && (tm instanceof BaseTemplateMapper)) 816 { 817 ((BaseTemplateMapper) tm).setPrefix(mapperPrefix[i]); 818 } 819 820 registerMapper(i, tm); 821 } 822 } 823}