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