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.configuration.Configuration;
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.fulcrum.factory.FactoryException;
33 import org.apache.fulcrum.factory.FactoryService;
34 import org.apache.fulcrum.parser.ParameterParser;
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: TurbineTemplateService.java 1773378 2016-12-09 13:19:59Z tv $
179 */
180 public 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 }