View Javadoc

1   /*
2    * $Id: TemplateEngineManager.java 651946 2008-04-27 13:41:38Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts2.components.template;
23  
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import com.opensymphony.xwork2.config.ConfigurationException;
30  import com.opensymphony.xwork2.inject.Container;
31  import com.opensymphony.xwork2.inject.Inject;
32  
33  /***
34   * The TemplateEngineManager will return a template engine for the template
35   */
36  public class TemplateEngineManager {
37      public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix";
38  
39      /*** The default template extenstion is <code>ftl</code>. */
40      public static final String DEFAULT_TEMPLATE_TYPE = "ftl";
41  
42      
43      Map<String,EngineFactory> templateEngines = new HashMap<String,EngineFactory>();
44      Container container;
45      String defaultTemplateType;
46      
47      @Inject(DEFAULT_TEMPLATE_TYPE_CONFIG_KEY)
48      public void setDefaultTemplateType(String type) {
49          this.defaultTemplateType = type;
50      }
51      
52      @Inject
53      public void setContainer(Container container) {
54          this.container = container;
55          Map<String,EngineFactory> map = new HashMap<String,EngineFactory>();
56          Set<String> prefixes = container.getInstanceNames(TemplateEngine.class);
57          for (String prefix : prefixes) {
58              map.put(prefix, new LazyEngineFactory(prefix));
59          }
60          this.templateEngines = Collections.unmodifiableMap(map);
61          
62      }
63      
64      /***
65       * Registers the given template engine.
66       * <p/>
67       * Will add the engine to the existing list of known engines.
68       * @param templateExtension  filename extension (eg. .jsp, .ftl, .vm).
69       * @param templateEngine     the engine.
70       */
71      public void registerTemplateEngine(String templateExtension, final TemplateEngine templateEngine) {
72          templateEngines.put(templateExtension, new EngineFactory() {
73              public TemplateEngine create() {
74                  return templateEngine;
75              }
76          });
77      }
78  
79      /***
80       * Gets the TemplateEngine for the template name. If the template name has an extension (for instance foo.jsp), then
81       * this extension will be used to look up the appropriate TemplateEngine. If it does not have an extension, it will
82       * look for a Configuration setting "struts.ui.templateSuffix" for the extension, and if that is not set, it
83       * will fall back to "ftl" as the default.
84       *
85       * @param template               Template used to determine which TemplateEngine to return
86       * @param templateTypeOverride Overrides the default template type
87       * @return the engine.
88       */
89      public TemplateEngine getTemplateEngine(Template template, String templateTypeOverride) {
90          String templateType = DEFAULT_TEMPLATE_TYPE;
91          String templateName = template.toString();
92          if (templateName.indexOf(".") > 0) {
93              templateType = templateName.substring(templateName.indexOf(".") + 1);
94          } else if (templateTypeOverride !=null && templateTypeOverride.length() > 0) {
95              templateType = templateTypeOverride;
96          } else {
97              String type = defaultTemplateType;
98              if (type != null) {
99                  templateType = type;
100             }
101         }
102         return templateEngines.get(templateType).create();
103     }
104 
105     /*** Abstracts loading of the template engine */
106     interface EngineFactory {
107         public TemplateEngine create();
108     }    
109 
110     /*** 
111      * Allows the template engine to be loaded at request time, so that engines that are missing
112      * dependencies aren't accessed if never used.
113      */
114     class LazyEngineFactory implements EngineFactory {
115         private String name;
116         public LazyEngineFactory(String name) {
117             this.name = name;
118         }    
119         public TemplateEngine create() {
120             TemplateEngine engine = container.getInstance(TemplateEngine.class, name);
121             if (engine == null) {
122                 throw new ConfigurationException("Unable to locate template engine: "+name);
123             }
124             return engine;
125         }    
126     }    
127 }