1 /*
2 * Copyright (c) 2001, 2002 The XDoclet team
3 * All rights reserved.
4 */
5 package xdoclet.util.velocity;
6
7 import org.apache.commons.logging.LogFactory;
8 import org.apache.velocity.app.Velocity;
9 import org.apache.velocity.app.VelocityEngine;
10 import org.apache.velocity.runtime.RuntimeConstants;
11 import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
12 import org.apache.velocity.runtime.resource.loader.JarResourceLoader;
13 import org.apache.velocity.runtime.resource.loader.ResourceLoader;
14
15 import xdoclet.util.ClasspathManager;
16
17 import java.io.File;
18
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Properties;
24
25 /***
26 * Utility class that supports dynamic configuration of Velocity's ResourceLoaders.
27 * This is necessary because templates will be read from jar files (plugin jars) and
28 * possibly also directories, and these are discovered at runtime by looking at the classpath.
29 *
30 * @author <a href="mailto:aslak.hellesoy at netcom.no">Aslak Hellesøy</a>
31 * @version $Revision: 1.5 $
32 */
33 public class VelocityConfigurer {
34 private static final Map _resourceLoaders = new HashMap(2);
35
36 static {
37 _resourceLoaders.put(JarResourceLoader.class, new String[] { "jar", "jar:file:" });
38 _resourceLoaders.put(FileResourceLoader.class, new String[] { "file", "" });
39 }
40
41 private final Properties _properties = new Properties();
42
43 /*** The velocity engine to configure. */
44 private final VelocityEngine _velocityEngine = new VelocityEngine();
45
46 /*** Comma-separated list of loaders, built incrementally for each invocation of addLoader(). */
47 private final StringBuffer _loaders = new StringBuffer();
48
49 /***
50 * Constructs a new VelocityConfigurer.
51 *
52 * @param classpathManager holds the classpath
53 */
54 public VelocityConfigurer(ClasspathManager classpathManager) {
55 // Add standard resource loaders
56 addLoader(FileResourceLoader.class, classpathManager.getDirectories());
57 addLoader(JarResourceLoader.class, classpathManager.getJars());
58 }
59
60 /***
61 * Returns a Map that should have java.lang.Class objects as keys and a 2-dimensional
62 * String[] as value. The class should be of type org.apache.velocity.runtime.resource.loader.ResourceLoader,
63 * and the String array should be {name, pathPrefix}. Name is the logical name for the loader, and
64 * pathPerfix is the required prefix for path entries. The map is preconfigured with
65 *
66 * <ul>
67 * <li>org.apache.velocity.runtime.resource.loader.JarResourceLoader -> {"jar", "jar:file:"}</li>
68 * <li>org.apache.velocity.runtime.resource.loader.FileResourceLoader -> {"file", ""}</li>
69 * </ul>
70 *
71 * If you need to configure VelocityConfigurer to handle additional Resource loader types.
72 *
73 * @return a Map as described above.
74 */
75 public static Map getResourceLoaderMap() {
76 return _resourceLoaders;
77 }
78
79 /***
80 * Adds a Velocity ResourceLoader.
81 *
82 * @param resourceLoaderClass resource loader class
83 * @param files Files to put on resource loader's path
84 */
85 public void addLoader(Class resourceLoaderClass, Collection files) {
86 if (resourceLoaderClass == null) {
87 throw new IllegalArgumentException("resourceLoaderClass cannot be null");
88 }
89
90 if (files == null) {
91 throw new IllegalArgumentException("files cannot be null");
92 }
93
94 // sanity check
95 if (!ResourceLoader.class.isAssignableFrom(resourceLoaderClass)) {
96 throw new IllegalArgumentException(resourceLoaderClass.getName() + " isn't of type "
97 + ResourceLoader.class.getName());
98 }
99
100 // Setup the loader. See Javadocs for JarResourceLoader or
101 // http://jakarta.apache.org/velocity/developer-guide.html
102 String[] config = (String[]) _resourceLoaders.get(resourceLoaderClass);
103
104 _properties.setProperty(config[0] + '.' + Velocity.RESOURCE_LOADER + ".class", resourceLoaderClass.getName());
105
106 // Register all the files.
107 StringBuffer fileList = new StringBuffer();
108 boolean comma = false;
109
110 if (!files.isEmpty()) {
111 for (Iterator filesIter = files.iterator(); filesIter.hasNext();) {
112 if (comma) {
113 fileList.append(',');
114 }
115
116 File file = (File) filesIter.next();
117
118 fileList.append(config[1]).append(file.getAbsolutePath());
119 comma = true;
120 }
121
122 String property = config[0] + '.' + Velocity.RESOURCE_LOADER + ".path";
123 String value = fileList.toString();
124
125 _properties.setProperty(property, value);
126
127 // Add to the list of loaders
128 if (_loaders.length() != 0) {
129 _loaders.append(",");
130 }
131
132 _loaders.append(config[0]);
133
134 _properties.setProperty(Velocity.RESOURCE_LOADER, _loaders.toString());
135 } else {
136 LogFactory.getLog(getClass()).debug("No " + config[0] + " resources.");
137 }
138 }
139
140 /***
141 * Configures a VelocityEngine and returns it.
142 *
143 * <p>If you need to configure the VelocityEngine beyond the standard configuration, call
144 * {@link #addLoader} to add additional loaders.</p>
145 *
146 * <p>It's also possible to set additional Velocity properties in the Properties object returned
147 * by {@link #getProperties}.</p>
148 */
149 public VelocityEngine initVelocity()
150 throws Exception {
151 assert getProperties() != null : "getProperties() returns null";
152
153 // Use our own log system that doesn't close the appenders upon gc() (the velocity one does)
154 getProperties().setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
155 DontCloseLog4JLogSystem.class.getName());
156
157 // We want ${velocityCount} to start on 0 instead of 1.
158 getProperties().setProperty(RuntimeConstants.COUNTER_INITIAL_VALUE, "0");
159 _velocityEngine.init(_properties);
160
161 return _velocityEngine;
162 }
163
164 /***
165 * Gets the additional Velocity properties.
166 * @return the additional Velocity properties
167 */
168 public Properties getProperties() {
169 return _properties;
170 }
171 }
This page was automatically generated by Maven