Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TurbineTemplateService |
|
| 1.8333333333333333;1.833 |
1 | package org.apache.fulcrum.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.io.OutputStream; | |
26 | import java.io.Writer; | |
27 | import java.util.HashMap; | |
28 | ||
29 | import org.apache.avalon.framework.context.Context; | |
30 | import org.apache.avalon.framework.context.ContextException; | |
31 | import org.apache.avalon.framework.context.Contextualizable; | |
32 | import org.apache.avalon.framework.logger.AbstractLogEnabled; | |
33 | import org.apache.avalon.framework.thread.ThreadSafe; | |
34 | ||
35 | /** | |
36 | * This service provides a method for mapping templates to their | |
37 | * appropriate Screens or Navigations. It also allows templates to | |
38 | * define a layout/navigations/screen modularization within the | |
39 | * template structure. It also performs caching if turned on in the | |
40 | * properties file. | |
41 | * | |
42 | * Since everything is keyed off the template variable, | |
43 | * if data.getParameters().getString("template") returns | |
44 | * /about_us/directions/driving.vm, the search for the | |
45 | * Screen class is as follows (in order): | |
46 | * | |
47 | * 1. about_us.directions.Driving | |
48 | * 2. about_us.directions.Default | |
49 | * 3. about_us.Default | |
50 | * 4. Default | |
51 | * 5. VelocityScreen | |
52 | * | |
53 | * If the template variable does not exist, then VelocityScreen will be | |
54 | * executed and templates/screens/index.vm will be executed. | |
55 | * If index.vm is not found or if the template is invalid or Velocity | |
56 | * execution throws an exception of any reason, then | |
57 | * templates/screens/error.vm will be executed. | |
58 | * | |
59 | * For the Layouts and Navigations, the following paths will be | |
60 | * searched in the layouts and navigations template | |
61 | * subdirectories (in order): | |
62 | * | |
63 | * 1./about_us/directions/driving.vm | |
64 | * 2./about_us/directions/default.vm | |
65 | * 3./about_us/default.vm | |
66 | * 4./default.vm | |
67 | * | |
68 | * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a> | |
69 | * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> | |
70 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> | |
71 | * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> | |
72 | * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a> | |
73 | * @version $Id: TurbineTemplateService.java 535465 2007-05-05 06:58:06Z tv $ | |
74 | */ | |
75 | public class TurbineTemplateService | |
76 | extends AbstractLogEnabled | |
77 | implements TemplateService, Contextualizable, ThreadSafe | |
78 | { | |
79 | /** | |
80 | * The default file extension used as a registry key when a | |
81 | * template's file extension cannot be determined. | |
82 | */ | |
83 | protected static final String NO_FILE_EXT = ""; | |
84 | ||
85 | /** | |
86 | * Default extension for templates. | |
87 | */ | |
88 | private String defaultExtension; | |
89 | ||
90 | /** | |
91 | * The application root | |
92 | */ | |
93 | private String applicationRoot; | |
94 | ||
95 | /** | |
96 | * The mappings of template file extensions to {@link | |
97 | * org.apache.fulcrum.template.TemplateEngineService} | |
98 | * implementations. Implementing template engines can locate | |
99 | * templates within the capability of any resource loaders they | |
100 | * may posses, and other template engines are stuck with file | |
101 | * based template hierarchy only. | |
102 | */ | |
103 | private HashMap templateEngineRegistry; | |
104 | ||
105 | public TurbineTemplateService() | |
106 | 0 | { |
107 | 0 | } |
108 | ||
109 | /** | |
110 | * Translates the supplied template paths into their Turbine-canonical | |
111 | * equivalent (probably absolute paths). | |
112 | * | |
113 | * @param templatePaths An array of template paths. | |
114 | * @return An array of translated template paths. | |
115 | */ | |
116 | public String[] translateTemplatePaths(String[] templatePaths) | |
117 | { | |
118 | 0 | for (int i = 0; i < templatePaths.length; i++) |
119 | { | |
120 | 0 | templatePaths[i] = getRealPath(templatePaths[i]); |
121 | } | |
122 | 0 | return templatePaths; |
123 | } | |
124 | ||
125 | /** | |
126 | * Looks for the specified template file in each of the specified paths. | |
127 | * | |
128 | * @param template The template file to check for the existance of. | |
129 | * @param templatePaths The paths to check for the template. | |
130 | * | |
131 | * @return true if a match is found in one of the supplied paths, or false. | |
132 | */ | |
133 | public boolean templateExists(String template, | |
134 | String[] templatePaths) | |
135 | { | |
136 | 0 | for (int i = 0; i < templatePaths.length; i++) |
137 | { | |
138 | 0 | if (new File(templatePaths[i],template).exists()) |
139 | { | |
140 | 0 | return true; |
141 | } | |
142 | } | |
143 | 0 | return false; |
144 | } | |
145 | ||
146 | /** | |
147 | * Determine if a template exists. Delegates to the appropriate {@link | |
148 | * org.apache.fulcrum.template.TemplateEngineService} to check the | |
149 | * existance of the specified template. If no template engine service is | |
150 | * found for the template, false is returned. | |
151 | * | |
152 | * @param template The template file to check for the existence of. | |
153 | * | |
154 | * @return true if there is a template engine service registered for the | |
155 | * given template, and it reports that the template exists, | |
156 | * otherwise false. | |
157 | */ | |
158 | public boolean templateExists(String template) | |
159 | { | |
160 | 0 | TemplateEngineService tes = getTemplateEngineService(template); |
161 | ||
162 | 0 | if (tes != null) |
163 | { | |
164 | 0 | return tes.templateExists(template); |
165 | } | |
166 | else | |
167 | { | |
168 | 0 | return false; |
169 | } | |
170 | } | |
171 | ||
172 | /** | |
173 | * Registers the provided template engine for use by the | |
174 | * <code>TemplateService</code>. | |
175 | * | |
176 | * @param service The <code>TemplateEngineService</code> to register. | |
177 | */ | |
178 | public synchronized void registerTemplateEngineService(TemplateEngineService service) | |
179 | { | |
180 | // Clone the registry to write to non-sync'd | |
181 | // Map implementations. | |
182 | 0 | HashMap registry = templateEngineRegistry != null ? |
183 | (HashMap) templateEngineRegistry.clone() : new HashMap(); | |
184 | ||
185 | 0 | String[] exts = service.getAssociatedFileExtensions(); |
186 | ||
187 | 0 | for (int i = 0; i < exts.length; i++) |
188 | { | |
189 | 0 | registry.put(exts[i], service); |
190 | } | |
191 | 0 | templateEngineRegistry = registry; |
192 | 0 | } |
193 | ||
194 | /** | |
195 | * The {@link org.apache.fulcrum.template.TemplateEngineService} | |
196 | * associated with the specified template's file extension. | |
197 | * | |
198 | * @param template The template name. | |
199 | * @return The template engine service. | |
200 | */ | |
201 | protected TemplateEngineService getTemplateEngineService(String template) | |
202 | { | |
203 | 0 | HashMap registry = templateEngineRegistry; |
204 | 0 | if (registry != null && template != null) |
205 | { | |
206 | 0 | int dotIndex = template.lastIndexOf('.'); |
207 | 0 | String ext = dotIndex == -1 ? |
208 | defaultExtension : template.substring(dotIndex + 1); | |
209 | 0 | return (TemplateEngineService) registry.get(ext); |
210 | } | |
211 | else | |
212 | { | |
213 | 0 | return null; |
214 | } | |
215 | } | |
216 | ||
217 | public String handleRequest(TemplateContext context, String template) | |
218 | throws TemplateException | |
219 | { | |
220 | 0 | TemplateEngineService tes = getTemplateEngineService(template); |
221 | 0 | return tes.handleRequest(context, template); |
222 | } | |
223 | ||
224 | public void handleRequest(TemplateContext context, String template, | |
225 | OutputStream outputStream) | |
226 | throws TemplateException | |
227 | { | |
228 | 0 | TemplateEngineService tes = getTemplateEngineService(template); |
229 | 0 | tes.handleRequest(context, template, outputStream); |
230 | 0 | } |
231 | ||
232 | public void handleRequest(TemplateContext context, String template, | |
233 | Writer writer) | |
234 | throws TemplateException | |
235 | { | |
236 | 0 | TemplateEngineService tes = getTemplateEngineService(template); |
237 | 0 | tes.handleRequest(context, template, writer); |
238 | 0 | } |
239 | ||
240 | public TemplateContext getTemplateContext() | |
241 | { | |
242 | 0 | return new DefaultTemplateContext(); |
243 | } | |
244 | ||
245 | /** | |
246 | * @see org.apache.fulcrum.ServiceBroker#getRealPath(String) | |
247 | */ | |
248 | public String getRealPath(String path) | |
249 | { | |
250 | 0 | String absolutePath = null; |
251 | 0 | if (applicationRoot == null) |
252 | { | |
253 | 0 | absolutePath = new File(path).getAbsolutePath(); |
254 | } | |
255 | else | |
256 | { | |
257 | 0 | absolutePath = new File(applicationRoot, path).getAbsolutePath(); |
258 | } | |
259 | ||
260 | 0 | return absolutePath; |
261 | } | |
262 | ||
263 | // ---------------- Avalon Lifecycle Methods --------------------- | |
264 | ||
265 | public void contextualize(Context context) throws ContextException { | |
266 | 0 | this.applicationRoot = context.get( "urn:avalon:home" ).toString(); |
267 | 0 | } |
268 | ||
269 | ||
270 | } |