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 <- 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$ 179 */ 180 public class TurbineTemplateService 181 extends TurbineBaseService 182 implements TemplateService 183 { 184 /** Logging */ 185 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 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: {}", Boolean.valueOf(useCache)); 295 296 templateEngineRegistry = new ConcurrentHashMap<>(); 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 ? 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 ParameterParser pp = pipelineData.get(Turbine.class, ParameterParser.class); 522 String template = pp.get(URIConstants.CGI_TEMPLATE_PARAM); 523 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 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 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 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 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 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 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 for (int i = 0; i < templatePaths.length; i++) 634 { 635 templatePaths[i] = servletService.getRealPath(templatePaths[i]); 636 } 637 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 for (String templatePath : templatePaths) 654 { 655 if (new File(templatePath, template).exists()) 656 { 657 return true; 658 } 659 } 660 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 String[] exts = service.getAssociatedFileExtensions(); 673 674 for (String ext : exts) 675 { 676 templateEngineRegistry.put(ext, service); 677 } 678 } 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 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 mapper.init(); 704 mapperRegistry[templateKey] = mapper; 705 } 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 mapperRegistry = new Mapper[TEMPLATE_TYPES]; 723 724 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 Class<?> [] mapperKeys = new Class<?> [] { 730 Page.class, Screen.class, Layout.class, Navigation.class, 731 Layout.class, Screen.class, Navigation.class 732 }; 733 734 String [] mapperClasses = new String [] { 735 DirectMapper.class.getName(), 736 ClassMapper.class.getName(), 737 ClassMapper.class.getName(), 738 ClassMapper.class.getName(), 739 LayoutTemplateMapper.class.getName(), 740 ScreenTemplateMapper.class.getName(), 741 DirectTemplateMapper.class.getName() 742 }; 743 744 AssemblerBrokerService../org/apache/turbine/services/assemblerbroker/AssemblerBrokerService.html#AssemblerBrokerService">AssemblerBrokerService ab = (AssemblerBrokerService)TurbineServices.getInstance() 745 .getService(AssemblerBrokerService.SERVICE_NAME); 746 747 int [] mapperCacheSize = new int [mapperKeys.length]; 748 Loader<? extends Assembler> [] mapperLoader = new Loader<?>[mapperKeys.length]; 749 750 for (int i = 0; i < mapperKeys.length; i++) 751 { 752 mapperLoader[i] = ab.getLoader((Class<? extends Assembler>)mapperKeys[i]); 753 mapperCacheSize[i] = (mapperLoader[i] != null) ? mapperLoader[i].getCacheSize() : 0; 754 } 755 756 // HACK: to achieve the same behavior as before 757 mapperLoader[LAYOUT_TEMPLATE_KEY] = null; 758 mapperLoader[SCREEN_TEMPLATE_KEY] = null; 759 mapperLoader[NAVIGATION_TEMPLATE_KEY] = null; 760 761 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 char [] mapperSeparator = new char [] { '.', '.', '.', '.', '/', '/', '/' }; 772 773 String [] mapperPrefix = new String [] { 774 null, null, null, null, 775 Layout.PREFIX, 776 Screen.PREFIX, 777 Navigation.PREFIX }; 778 779 for (int i = 0; i < TEMPLATE_TYPES; i++) 780 { 781 StringBuilder mapperProperty = new StringBuilder(); 782 mapperProperty.append("mapper."); 783 mapperProperty.append(mapperNames[i]); 784 mapperProperty.append(".class"); 785 786 String mapperClass = 787 conf.getString(mapperProperty.toString(), mapperClasses[i]); 788 789 log.info("Using {} to map {} elements", mapperClass, mapperNames[i]); 790 791 Mapper tm = null; 792 793 try 794 { 795 FactoryService factory = (FactoryService)TurbineServices.getInstance().getService(FactoryService.ROLE); 796 tm = factory.getInstance(mapperClass); 797 } 798 catch (FactoryException e) 799 { 800 throw new InitializationException("", e); 801 } 802 803 tm.setUseCache(useCache); 804 tm.setCacheSize(mapperCacheSize[i]); 805 tm.setDefaultProperty(mapperDefaultProperty[i]); 806 tm.setSeparator(mapperSeparator[i]); 807 808 if (mapperLoader[i] != null && tm instanceof ClassMapper) 809 { 810 ((ClassMapper) tm).setLoader(mapperLoader[i]); 811 } 812 813 if (mapperPrefix[i] != null && tm instanceof BaseTemplateMapper) 814 { 815 ((BaseTemplateMapper) tm).setPrefix(mapperPrefix[i]); 816 } 817 818 registerMapper(i, tm); 819 } 820 } 821 }