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 }