Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
WM |
|
| 1.4761904761904763;1.476 |
1 | /* | |
2 | * Copyright (C) 1998-2000 Semiotek Inc. All Rights Reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted under the terms of either of the following | |
6 | * Open Source licenses: | |
7 | * | |
8 | * The GNU General Public License, version 2, or any later version, as | |
9 | * published by the Free Software Foundation | |
10 | * (http://www.fsf.org/copyleft/gpl.html); | |
11 | * | |
12 | * or | |
13 | * | |
14 | * The Semiotek Public License (http://webmacro.org/LICENSE.) | |
15 | * | |
16 | * This software is provided "as is", with NO WARRANTY, not even the | |
17 | * implied warranties of fitness to purpose, or merchantability. You | |
18 | * assume all risks and liabilities associated with its use. | |
19 | * | |
20 | * See www.webmacro.org for more information on the WebMacro project. | |
21 | */ | |
22 | ||
23 | ||
24 | package org.webmacro; | |
25 | ||
26 | import java.io.OutputStream; | |
27 | import java.io.UnsupportedEncodingException; | |
28 | import java.util.Properties; | |
29 | ||
30 | import javax.servlet.Servlet; | |
31 | import javax.servlet.ServletContext; | |
32 | import javax.servlet.http.HttpServletRequest; | |
33 | import javax.servlet.http.HttpServletResponse; | |
34 | ||
35 | import org.slf4j.Logger; | |
36 | import org.slf4j.LoggerFactory; | |
37 | ||
38 | import org.webmacro.servlet.ServletBroker; | |
39 | import org.webmacro.servlet.WebContext; | |
40 | ||
41 | ||
42 | /** | |
43 | * This class implements the WebMacro Manager interface. You can instantiate | |
44 | * this yourself if you want to use WebMacro in standalone mode, rather than | |
45 | * subclassing from org.webmacro.servlet.WMServlet. This is actually the | |
46 | * same class used by the servlet framework to manage access to the broker | |
47 | * there, so you really don't lose much of anything by choosing to go | |
48 | * standalone by using this object. All you have to do is come up with | |
49 | * your own context objects. | |
50 | */ | |
51 | public class WM implements WebMacro | |
52 | { | |
53 | 2 | static Logger _log = LoggerFactory.getLogger(WM.class); |
54 | ||
55 | // INIT METHODS--MANAGE ACCESS TO THE BROKER | |
56 | ||
57 | final private Broker _broker; // cache for rapid access | |
58 | ||
59 | final private Provider _tmplProvider; | |
60 | final private Provider _urlProvider; | |
61 | ||
62 | ||
63 | /** | |
64 | * Constructs a WM which gets its properties (optionally) from the | |
65 | * file WebMacro.properties, as found on the class path. No servlet | |
66 | * integration. Templates will be loaded from the class path or from | |
67 | * TemplatePath. Most users will want to use the WM(Servlet) constructor. | |
68 | */ | |
69 | public WM () throws InitException | |
70 | { | |
71 | 224 | this(Broker.getBroker()); |
72 | 224 | } |
73 | ||
74 | /** | |
75 | * Constructs a WM which gets its properties (optionally) from the | |
76 | * file WebMacro.properties, as found on the class path, and from properties | |
77 | * specified in a provided Properties. No servlet | |
78 | * integration. Templates will be loaded from the class path or from | |
79 | * TemplatePath. Most users will want to use the WM(Servlet) constructor. | |
80 | */ | |
81 | public WM (Properties p) throws InitException | |
82 | { | |
83 | 0 | this(Broker.getBroker(p)); |
84 | 0 | } |
85 | ||
86 | /** | |
87 | * Constructs a WM which gets its properties from the file specified, | |
88 | * which must exist on the class path or be an absolute path. No servlet | |
89 | * integration. Templates will be loaded from the class path or from | |
90 | * TemplatePath. Most users will want to use the WM(Servlet) constructor. | |
91 | */ | |
92 | public WM (String config) throws InitException | |
93 | { | |
94 | 0 | this(Broker.getBroker(config)); |
95 | 0 | } |
96 | ||
97 | /** | |
98 | * Constructs a WM tied to a Servlet broker. Depending on the | |
99 | * servlet container's level of servlet support, property fetching, | |
100 | * logging, and template fetching will be managed by the servlet broker. | |
101 | */ | |
102 | public WM (Servlet s) throws InitException | |
103 | { | |
104 | 32 | this(ServletBroker.getBroker(s)); |
105 | 32 | } |
106 | ||
107 | /** | |
108 | * Constructs a WM is tied to a Servlet broker, with an additional set of | |
109 | * properties passed in from the caller. | |
110 | */ | |
111 | public WM (Servlet s, Properties additionalProperties) throws InitException | |
112 | { | |
113 | 0 | this(ServletBroker.getBroker(s, additionalProperties)); |
114 | 0 | } |
115 | ||
116 | /** | |
117 | * Constructs a WM is tied to a Servlet broker, | |
118 | * with an additional set of | |
119 | * properties passed in from the caller, using the ServletContext | |
120 | * and ClassLoader provided. | |
121 | * @since 2.1 | |
122 | */ | |
123 | public WM (ServletContext sc, ClassLoader cl, | |
124 | Properties additionalProperties) throws InitException | |
125 | { | |
126 | 0 | this(ServletBroker.getBroker(sc, cl, additionalProperties)); |
127 | 0 | } |
128 | ||
129 | /** | |
130 | * Constructs a WM from an arbitrary Broker. Don't use this unless | |
131 | * you have very specific needs and know what you are doing; constructing | |
132 | * a properly functioning broker is not obvious. | |
133 | */ | |
134 | public WM (Broker broker) throws InitException | |
135 | 256 | { |
136 | 256 | if (broker == null) |
137 | 0 | throw new InitException("No Broker passed to WM()"); |
138 | ||
139 | 256 | _broker = broker; |
140 | 256 | _log.info("new " + this + " v" + WebMacro.VERSION); |
141 | ||
142 | try | |
143 | { | |
144 | 256 | _tmplProvider = _broker.getProvider("template"); |
145 | 256 | _urlProvider = _broker.getProvider("url"); |
146 | } | |
147 | 0 | catch (NotFoundException nfe) |
148 | { | |
149 | 0 | _log.error("Could not load configuration", nfe); |
150 | 0 | throw new InitException("Could not locate provider; " |
151 | + "This implies that WebMacro is badly misconfigured, you\n" | |
152 | + "should double check that all configuration files and\n" | |
153 | + "options are set up correctly. In a default install of\n" | |
154 | + "WebMacro this likely means your WebMacro.properties file\n" | |
155 | + "was not found on your CLASSPATH.", nfe); | |
156 | 256 | } |
157 | 256 | } |
158 | ||
159 | public String toString () | |
160 | { | |
161 | 256 | return "WebMacro(" + _broker.getName() + ")"; |
162 | } | |
163 | ||
164 | ||
165 | /** | |
166 | * This object is used to access components that have been plugged | |
167 | * into WebMacro; it is shared between all instances of this class and | |
168 | * its subclasses. It is created when the first instance is initialized, | |
169 | * and deleted when the last instance is shut down. If you attempt to | |
170 | * access it after the last servlet has been shutdown, it will either | |
171 | * be in a shutdown state or else null. | |
172 | */ | |
173 | final public Broker getBroker () | |
174 | { | |
175 | // this method can be unsynch. because the broker manages its own | |
176 | // state, plus the only time the _broker will be shutdown or null | |
177 | // is after the last servlet has shutdown--so why would anyone be | |
178 | // accessing us then? if they do the _broker will throw exceptions | |
179 | // complaining that it has been shut down, or they'll get a null here. | |
180 | 2977 | return _broker; |
181 | } | |
182 | ||
183 | /** | |
184 | * Get a new FastWriter. | |
185 | * A FastWriter is used when writing templates to an output stream | |
186 | * | |
187 | * @param out The output stream the FastWriter should write to. Typically | |
188 | * this will be your ServletOutputStream. It can be null if | |
189 | * only want the fast writer to buffer the output. | |
190 | * @param enctype the Encoding type to use | |
191 | * @deprecated | |
192 | */ | |
193 | final public FastWriter getFastWriter (OutputStream out, String enctype) | |
194 | throws UnsupportedEncodingException | |
195 | { | |
196 | 0 | return FastWriter.getInstance(_broker, out, enctype); |
197 | } | |
198 | ||
199 | ||
200 | /** | |
201 | * Instantiate a new context. | |
202 | */ | |
203 | final public Context getContext () | |
204 | { | |
205 | 2 | return new Context(_broker); |
206 | } | |
207 | ||
208 | /** | |
209 | * Instantiate a new webcontext. | |
210 | */ | |
211 | final public WebContext getWebContext (HttpServletRequest req, | |
212 | HttpServletResponse resp) | |
213 | { | |
214 | 0 | return new WebContext(_broker, req, resp); |
215 | } | |
216 | ||
217 | ||
218 | /** | |
219 | * Retrieve a template from the "template" provider. | |
220 | * @exception NotFoundException if the template could not be found | |
221 | * @exception ResourceException if the template could not be loaded | |
222 | */ | |
223 | final public Template getTemplate (String key) | |
224 | throws ResourceException | |
225 | { | |
226 | 1542 | return (Template) _tmplProvider.get(key); |
227 | } | |
228 | ||
229 | /** | |
230 | * Retrieve a URL from the "url" provider. Equivalent to | |
231 | * getBroker().getValue("url",url) | |
232 | * @exception NotFoundException if the template could not be found | |
233 | * @exception ResourceException if the template could not be loaded | |
234 | */ | |
235 | final public String getURL (String url) | |
236 | throws ResourceException | |
237 | { | |
238 | 0 | return (String) _urlProvider.get(url); |
239 | } | |
240 | ||
241 | /** | |
242 | * Retrieve configuration information from the "config" provider. | |
243 | * Equivalent to getBroker().get("config",key) | |
244 | * @exception NotFoundException could not locate requested information | |
245 | */ | |
246 | final public String getConfig (String key) | |
247 | throws NotFoundException | |
248 | { | |
249 | try | |
250 | { | |
251 | 0 | return (String) _broker.get("config", key); |
252 | } | |
253 | 0 | catch (NotFoundException e) |
254 | { | |
255 | 0 | throw e; |
256 | } | |
257 | 0 | catch (ResourceException e) |
258 | { | |
259 | 0 | throw new NotFoundException(e.toString(), e); |
260 | } | |
261 | } | |
262 | ||
263 | /** | |
264 | * Get a log to write information to. Logger type names should be lower | |
265 | * case and short. They may be printed on every line of the log | |
266 | * file. The description is a longer explanation of the type of | |
267 | * log messages you intend to produce with this Logger object. | |
268 | */ | |
269 | final public Logger getLog (String type, String description) | |
270 | { | |
271 | 0 | return _log; |
272 | } | |
273 | ||
274 | /** | |
275 | * Get a log using the type as the description | |
276 | */ | |
277 | final public Logger getLog (String type) | |
278 | { | |
279 | 0 | return _log; |
280 | } | |
281 | ||
282 | /** | |
283 | * Convenience method for writing a template to an OutputStream. | |
284 | * This method takes care of all the typical work involved | |
285 | * in writing a template.<p> | |
286 | * | |
287 | * This method uses the default <code>TemplateOutputEncoding</code> specified in | |
288 | * WebMacro.defaults or your custom WebMacro.properties. | |
289 | * | |
290 | * @param templateName name of Template to write. Must be accessible | |
291 | * via TemplatePath | |
292 | * @param out where the output of the template should go | |
293 | * @param context The Context (can be a WebContext too) used | |
294 | * during the template evaluation phase | |
295 | * @throws java.io.IOException if the template cannot be written to the | |
296 | * specified output stream | |
297 | * @throws ResourceException if the template name specified cannot be found | |
298 | * @throws PropertyException if a fatal error occured during the Template | |
299 | * evaluation phase | |
300 | */ | |
301 | final public void writeTemplate (String templateName, java.io.OutputStream out, | |
302 | Context context) | |
303 | throws java.io.IOException, ResourceException, PropertyException | |
304 | { | |
305 | ||
306 | 0 | writeTemplate(templateName, out, |
307 | getConfig(WMConstants.TEMPLATE_OUTPUT_ENCODING), context); | |
308 | 0 | } |
309 | ||
310 | /** | |
311 | * Convienence method for writing a template to an OutputStream. | |
312 | * This method takes care of all the typical work involved | |
313 | * in writing a template. | |
314 | * | |
315 | * @param templateName name of Template to write. Must be accessible | |
316 | * via TemplatePath | |
317 | * @param out where the output of the template should go | |
318 | * @param encoding character encoding to use when writing the template | |
319 | * if the encoding is <code>null</code>, the default | |
320 | * <code>TemplateOutputEncoding</code> is used | |
321 | * @param context The Context (can be a WebContext too) used | |
322 | * during the template evaluation phase | |
323 | * @throws java.io.IOException if the template cannot be written to the | |
324 | * specified output stream | |
325 | * @throws ResourceException if the template name specified cannot be found | |
326 | * @throws PropertyException if a fatal error occured during the Template | |
327 | * evaluation phase | |
328 | */ | |
329 | final public void writeTemplate (String templateName, java.io.OutputStream out, | |
330 | String encoding, Context context) | |
331 | throws java.io.IOException, ResourceException, PropertyException | |
332 | { | |
333 | ||
334 | 0 | if (encoding == null) |
335 | 0 | encoding = getConfig(WMConstants.TEMPLATE_OUTPUT_ENCODING); |
336 | ||
337 | 0 | Template tmpl = getTemplate(templateName); |
338 | 0 | tmpl.write(out, encoding, context); |
339 | 0 | } |
340 | ||
341 | /** | |
342 | * Print the version, and quit | |
343 | */ | |
344 | public static void main (String[] args) | |
345 | { | |
346 | 0 | System.out.println("WebMacro v" + WebMacro.VERSION + ". Built " + WebMacro.BUILD_DATE); |
347 | 0 | } |
348 | ||
349 | /** | |
350 | * Close down this WM. This will invoke destroy() on the Broker. | |
351 | * @see Broker#destroy() | |
352 | **/ | |
353 | public void destroy() | |
354 | { | |
355 | 0 | getBroker().destroy(); |
356 | 0 | } |
357 | } |