1 package org.apache.turbine.services.pull.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.InputStream;
23 import java.util.Properties;
24
25 import org.apache.commons.configuration.Configuration;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.turbine.Turbine;
30 import org.apache.turbine.om.security.User;
31 import org.apache.turbine.services.pull.ApplicationTool;
32 import org.apache.turbine.services.pull.TurbinePull;
33 import org.apache.turbine.services.servlet.TurbineServlet;
34 import org.apache.turbine.util.RunData;
35 import org.apache.turbine.util.ServerData;
36 import org.apache.turbine.util.uri.DataURI;
37
38 /***
39 * UIManager.java
40 * <br>
41 * Manages all UI elements for a Turbine Application. Any
42 * UI element can be accessed in any template using the
43 * $ui handle (assuming you use the default PullService
44 * configuration). So, for example, you could access
45 * the background colour for your pages by using
46 * $ui.bgcolor
47 * <p>
48 * <h3>Questions:</h3>
49 * What is the best way to allow an application
50 * to be skinned. And how to allow the flexible
51 * altering of a particular UI element in certain
52 * parts of the template hierarchy. For example
53 * on one section of your site you might like
54 * a certain bgcolor, on another part of your
55 * site you might want another. How can be let
56 * the designer specify these properties and
57 * still use the single $app.ui.bgcolor in
58 * all the templates.
59 * <p>
60 * It would also be very cool to use some form
61 * of inheritence for UI elements. Say a $ui.bgcolor
62 * is used in a template where the bgcolor is not
63 * set for that part of hierarch, it would be cool
64 * if it could find the setting for the bgcolor
65 * in the parent directory. So you could override
66 * a UI element where you wanted and the system
67 * would fall back to the parent when necessary.
68 * <p>
69 * How to specify skins, how to deal with images,
70 * how could this be handled with a web app.
71 * <p>
72 *
73 * This is an application pull tool for the template system. You should <b>not</b>
74 * use it in a normal application!
75 *
76 *
77 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
78 * @author <a href="mailto:james_coltman@majorband.co.uk">James Coltman</a>
79 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
80 * @author <a href="thomas.vandahl@tewisoft.de">Thomas Vandahl</a>
81 * @deprecated Use UITool instead.
82 * @version $Id: UIManager.java 535070 2007-05-04 03:23:22Z seade $
83 */
84 public class UIManager implements ApplicationTool
85 {
86 /*** Logging */
87 private static Log log = LogFactory.getLog(UIManager.class);
88
89 /***
90 * The location of the skins within the application
91 * resources directory.
92 */
93 private static final String SKINS_DIRECTORY = "/ui/skins";
94
95 /***
96 * The name of the directory where images are
97 * stored for this skin.
98 */
99 private static final String IMAGES_DIRECTORY = "/images";
100
101 /***
102 * Property tag for the default skin that is to be
103 * used for the web application.
104 */
105 private static final String SKIN_PROPERTY = "tool.ui.skin";
106
107 /***
108 * Property tag for the image directory inside the skin that is to be
109 * used for the web application.
110 */
111 private static final String IMAGEDIR_PROPERTY = "tool.ui.dir.image";
112
113 /***
114 * Property tag for the skin directory that is to be
115 * used for the web application.
116 */
117 private static final String SKINDIR_PROPERTY = "tool.ui.dir.skin";
118
119 /***
120 * Property tag for the css file that is to be
121 * used for the web application.
122 */
123 private static final String CSS_PROPERTY = "tool.ui.css";
124
125 /***
126 * Property tag for the css file that is to be
127 * used for the web application.
128 */
129 private static final String RELATIVE_PROPERTY = "tool.ui.want.relative";
130
131 /***
132 * Default skin name. This name actually represents
133 * a directory in the WEBAPP/resources/ui/skins
134 * directory. There is a file called skin.props
135 * which actually contains the name/value pairs.
136 */
137 private static final String SKIN_PROPERTY_DEFAULT = "default";
138
139 /***
140 * Attribute name of skinName value in User's temp hashmap.
141 */
142 private static final String SKIN_ATTRIBUTE =
143 UIManager.class.getName()+ ".skin";
144
145 /***
146 * The actual skin being used for the webapp.
147 */
148 private String skinName;
149
150 /***
151 * The skins directory.
152 */
153 private String skinsDirectory;
154
155 /***
156 * The file within the skin directory that actually
157 * contains the name/value pairs for the skin.
158 */
159 private static final String SKIN_PROPS_FILE = "skin.props";
160
161 /***
162 * The file name for the skin style sheet.
163 */
164 private static final String DEFAULT_SKIN_CSS_FILE = "skin.css";
165
166 /***
167 * This the resources directory relative to the
168 * webapp context. Used for constructing correct
169 * URIs for retrieving images in image().
170 */
171 private String resourcesDirectory;
172 private String imagesDirectory;
173 private String cssFile;
174
175 private boolean wantRelative = false;
176
177 /***
178 * Properties to hold the name/value pairs
179 * for the skin.
180 */
181 private Properties skinProperties;
182
183 /***
184 * Initialize the UIManager object.
185 *
186 * @param data This is null, RunData or User depending upon specified tool scope.
187 * @deprecated Use UITool.init() instead.
188 */
189 public void init(Object data)
190 {
191 /***
192 * Store the resources directory for use in image().
193 */
194 Configuration cfg = Turbine.getConfiguration();
195
196 resourcesDirectory = stripSlashes(TurbinePull.getResourcesDirectory());
197
198 if (data == null)
199 {
200 log.debug("UI Manager scope is global");
201 setSkin();
202 }
203 else if (data instanceof RunData)
204 {
205 log.debug("UI Manager scope is request");
206 setSkin((RunData) data);
207 }
208 else if (data instanceof User)
209 {
210 log.debug("UI Manager scope is session");
211 setSkin((User) data);
212 }
213
214 skinsDirectory = stripSlashes(cfg.getString(SKINDIR_PROPERTY, SKINS_DIRECTORY));
215
216 imagesDirectory = stripSlashes(cfg.getString(IMAGEDIR_PROPERTY, IMAGES_DIRECTORY));
217
218 cssFile = cfg.getString(CSS_PROPERTY, DEFAULT_SKIN_CSS_FILE);
219
220 wantRelative = cfg.getBoolean(RELATIVE_PROPERTY, false);
221
222 loadSkin();
223 }
224
225 private String stripSlashes(final String path)
226 {
227 if (StringUtils.isEmpty(path))
228 {
229 return "";
230 }
231
232 String ret = path;
233 int len = ret.length() - 1;
234
235 if (ret.charAt(len) == '/')
236 {
237 ret = ret.substring(0, len);
238 }
239
240 if (len > 0 && ret.charAt(0) == '/')
241 {
242 ret = ret.substring(1);
243 }
244
245 return ret;
246 }
247
248 /***
249 * This lets the tool know that it should be
250 * refreshed. The tool can perform whatever actions
251 * are necessary to refresh itself. This is necessary
252 * for sane development where you probably want the
253 * tools to refresh themselves on every request.
254 *
255 * @deprecated Use UITool.refresh() instead.
256 */
257 public void refresh()
258 {
259 log.debug("Refreshing UI manager");
260
261 loadSkin();
262 }
263
264 /***
265 * Retrieve a property from the properties held
266 * within the properties file for this skin.
267 *
268 * @deprecated Use UITool.get(String key) instead.
269 */
270 public String get(String key)
271 {
272 return skinProperties.getProperty(key);
273 }
274
275 /***
276 * Retrieve the skin name.
277 *
278 * @deprecated Use UITool.getSkin() instead.
279 */
280 public String getSkin()
281 {
282 return skinName;
283 }
284
285 /***
286 * Retrieve the URL for an image that is part
287 * of a skin. The images are stored in the
288 * WEBAPP/resources/ui/skins/<SKIN>/images
289 * directory.
290 *
291 * Use this if for some reason your server name,
292 * server scheme, or server port change on a
293 * per request basis. I'm not sure if this
294 * would happen in a load balanced situation.
295 * I think in most cases the image(String image)
296 * method would probably be enough, but I'm not
297 * absolutely positive.
298 *
299 * @deprecated Use UITool.image(String imageId, RunData data) instead.
300 */
301 public String image(String imageId, RunData data)
302 {
303 DataURI du = new DataURI(data);
304
305 StringBuffer sb = new StringBuffer();
306
307 sb.append(resourcesDirectory).
308 append('/').
309 append(skinsDirectory).
310 append('/').
311 append(getSkin()).
312 append('/').
313 append(imagesDirectory).
314 append('/').
315 append(stripSlashes(imageId));
316
317 du.setScriptName(sb.toString());
318
319 return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
320 }
321
322 /***
323 * Retrieve the URL for an image that is part
324 * of a skin. The images are stored in the
325 * WEBAPP/resources/ui/skins/<SKIN>/images
326 * directory.
327 *
328 * @deprecated Use UITool.image(String imageId) instead.
329 */
330 public String image(String imageId)
331 {
332 ServerData sd = Turbine.getDefaultServerData();
333 DataURI du = new DataURI(sd);
334
335 StringBuffer sb = new StringBuffer();
336
337 sb.append(resourcesDirectory).
338 append('/').
339 append(skinsDirectory).
340 append('/').
341 append(getSkin()).
342 append('/').
343 append(imagesDirectory).
344 append('/').
345 append(stripSlashes(imageId));
346
347 du.setScriptName(sb.toString());
348 return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
349 }
350
351 /***
352 * Retrieve the URL for the style sheet that is part
353 * of a skin. The style is stored in the
354 * WEBAPP/resources/ui/skins/<SKIN> directory with the
355 * filename skin.css
356 *
357 * Use this if for some reason your server name,
358 * server scheme, or server port change on a
359 * per request basis. I'm not sure if this
360 * would happend in a load balanced situation.
361 * I think in most cases the style()
362 * method would probably be enough, but I'm not
363 * absolutely positive.
364 *
365 * @deprecated Use UITool.getStylecss(RunData data) instead.
366 */
367 public String getStylecss(RunData data)
368 {
369 return getScript(cssFile, data);
370 }
371
372 /***
373 * Retrieve the URL for the style sheet that is part
374 * of a skin. The style is stored in the
375 * WEBAPP/resources/ui/skins/<SKIN> directory with the
376 * filename skin.css
377 *
378 * @deprecated Use UITool.getStylecss() instead.
379 */
380 public String getStylecss()
381 {
382 return getScript(cssFile);
383 }
384
385 /***
386 * Retrieve the URL for a given script that is part
387 * of a skin. The script is stored in the
388 * WEBAPP/resources/ui/skins/<SKIN> directory
389 *
390 * @deprecated Use UITool.getScript(String filename, RunData data) instead.
391 */
392 public String getScript(String filename, RunData data)
393 {
394 DataURI du = new DataURI(data);
395
396 StringBuffer sb = new StringBuffer();
397
398 sb.append(resourcesDirectory).
399 append('/').
400 append(skinsDirectory).
401 append('/').
402 append(getSkin()).
403 append('/').
404 append(stripSlashes(filename));
405
406 du.setScriptName(sb.toString());
407 return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
408 }
409
410 /***
411 * Retrieve the URL for a given script that is part
412 * of a skin. The script is stored in the
413 * WEBAPP/resources/ui/skins/<SKIN> directory
414 *
415 * @deprecated Use UITool.getScript(String filename) instead.
416 */
417 public String getScript(String filename)
418 {
419 ServerData sd = Turbine.getDefaultServerData();
420 DataURI du = new DataURI(sd);
421
422 StringBuffer sb = new StringBuffer();
423
424 sb.append(resourcesDirectory).
425 append('/').
426 append(skinsDirectory).
427 append('/').
428 append(getSkin()).
429 append('/').
430 append(stripSlashes(filename));
431
432 du.setScriptName(sb.toString());
433 return wantRelative ? du.getRelativeLink() : du.getAbsoluteLink();
434 }
435
436 /***
437 * Load the specified skin. In development mode
438 * this may occur frequently as the skin properties
439 * are being changed.
440 */
441 private void loadSkin()
442 {
443 skinProperties = new Properties();
444
445 try
446 {
447 StringBuffer sb = new StringBuffer();
448
449 sb.append(resourcesDirectory).
450 append('/').
451 append(skinsDirectory).
452 append('/').
453 append(getSkin()).
454 append('/').
455 append(SKIN_PROPS_FILE);
456
457 InputStream is = TurbineServlet.getResourceAsStream(sb.toString());
458
459 skinProperties.load(is);
460 }
461 catch (Exception e)
462 {
463 log.error("Cannot load skin: " + skinName);
464 }
465 }
466
467 /***
468 * Set the skin name to the skin from the TR.props
469 * file. If the property is not present use the
470 * default skin.
471 *
472 * @deprecated Use UITool.setSkin() instead.
473 */
474 public void setSkin()
475 {
476 this.skinName = Turbine.getConfiguration()
477 .getString(SKIN_PROPERTY,
478 SKIN_PROPERTY_DEFAULT);
479 }
480
481 /***
482 * Set the skin name to the specified skin.
483 *
484 * @param skinName the skin name to use.
485 * @deprecated Use UITool.setSkin(String skinName) instead.
486 */
487 public void setSkin(String skinName)
488 {
489 this.skinName = skinName;
490 }
491
492 /***
493 * Set the skin name when the tool is configured to be
494 * loaded on a per-request basis. By default it calls getSkin
495 * to return the skin specified in TR.properties. Developers can
496 * write a subclass of UIManager that overrides this method to
497 * determine the skin to use based on information held in the request.
498 *
499 * @param data a RunData instance
500 * @deprecated Use UITool.setSkin(RunData data) instead.
501 */
502 protected void setSkin(RunData data)
503 {
504 setSkin();
505 }
506
507 /***
508 * Set the skin name when the tool is configured to be
509 * loaded on a per-session basis. It the user's temp hashmap contains
510 * a value in the attribute specified by the String constant SKIN_ATTRIBUTE
511 * then that is returned. Otherwise it calls getSkin to return the skin
512 * specified in TR.properties.
513 *
514 * @param user a User instance
515 * @deprecated Use UITool.setSkin(User user) instead.
516 */
517 protected void setSkin(User user)
518 {
519 if (user.getTemp(SKIN_ATTRIBUTE) == null)
520 {
521 setSkin();
522 }
523 else
524 {
525 setSkin((String) user.getTemp(SKIN_ATTRIBUTE));
526 }
527 }
528
529 /***
530 * Set the skin name user's temp hashmap for the current session.
531 *
532 * @param user a User instance
533 * @param skin the skin name for the session
534 * @deprecated Use UITool.setSkin(User user, String skin) instead.
535 */
536 public static void setSkin(User user, String skin)
537 {
538 user.setTemp(SKIN_ATTRIBUTE, skin);
539 }
540 }