1
2
3
4
5 package net.sf.wfnm;
6
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 import java.util.Arrays;
11 import java.util.Properties;
12
13
14 /***
15 * The WebFlow Navigation Manager configuration.<br> The unique JVM instance of this class configure the WFMN:
16 *
17 * <ul>
18 * <li>
19 * enable/disable the framework
20 * </li>
21 * <li>
22 * enable/disable the automatic cleaning subsystem
23 * </li>
24 * <li>
25 * enable/disable session size statistics
26 * </li>
27 * <li>
28 * enable/disable the "no cache" option
29 * </li>
30 * <li>
31 * sets the webflows default ownership
32 * </li>
33 * <li>
34 * the url rewriter implementation used by the NoMultipleSubmitFilter filter
35 * </li>
36 * <li>
37 * set url calculator implementation used by the NotifyFactory
38 * </li>
39 * <li>
40 * set the concrete implementation of the navigation manager class
41 * </li>
42 * <li>
43 * set the concrete implementation of the navigation context class
44 * </li>
45 * <li>
46 * the page change listener
47 * </li>
48 * <li>
49 * the webflow change listener
50 * </li>
51 * </ul>
52 *
53 *
54 * @author <a href="mailto:malbari@users.sourceforge.net">Maurizio Albari</a>
55 * @version 1.0.6
56 */
57 public class Config {
58 /***
59 * A sychronization lock.
60 */
61 private static Object synchLock = new Object();
62
63 /***
64 * The default configuration file name.
65 */
66 private static final String WFNM_DEFAULT_PROPERTIES = "wfnm.properties";
67
68 /***
69 * The key that indicates the manager implementation.
70 */
71 private static final String WFNM_MANAGER_KEY = "net.sf.wfnm.MANAGER";
72
73 /***
74 * The key that indicates the context implementation.
75 */
76 private static final String WFNM_CONTEXT_KEY = "net.sf.wfnm.CONTEXT";
77
78 /***
79 * The key that indicates if the framework is enabled.
80 */
81 private static final String WFNM_ENABLED_KEY = "net.sf.wfnm.ENABLED";
82
83 /***
84 * The key that indicates if the cleaner is enabled.
85 */
86 private static final String WFNM_CLEANER_ENABLED_KEY = "net.sf.wfnm.CLEANER_ENABLED";
87
88 /***
89 * The key that indicates the default webflows ownership.
90 */
91 private static final String WFNM_DEFAULT_OWNERSHIP_KEY = "net.sf.wfnm.DEFAULT_OWNERSHIP";
92
93 /***
94 * The key that indicates if the statistics are enabled.
95 */
96 private static final String WFNM_STATS_ENABLED_KEY = "net.sf.wfnm.STATS_ENABLED";
97
98 /***
99 * The key that indicates if the no cache option is enabled
100 */
101 private static final String WFNM_NO_CACHE_ENABLED_KEY = "net.sf.wfnm.NO_CACHE_ENABLED";
102
103 /***
104 * The key that indicates the implementation of the UrlRewriter for the NoMultipleSubmitFilter
105 */
106 private static final String WFNM_URL_REWRITER_KEY = "net.sf.wfnm.URL_REWRITER";
107
108 /***
109 * The key that indicates which is the page changed listener
110 */
111 private static final String WFNM_PAGE_CHANGED_LISTENER_KEY = "net.sf.wfnm.PAGE_CHANGED_LISTENER";
112
113 /***
114 * The key that indicates which is the webflow changed listener
115 */
116 private static final String WFNM_WEBFLOW_CHANGED_LISTENER_KEY = "net.sf.wfnm.WEBFLOW_CHANGED_LISTENER";
117
118 /***
119 * The key that indicates which is the class that calculate the URLs
120 */
121 private static final String WFNM_URL_CALCULAOR_KEY = "net.sf.wfnm.URL_CALCULATOR";
122
123 /***
124 * The unique instance of the configuration.
125 */
126 private static Config instance;
127
128 /***
129 * The the class that implements the NavigationContext interface.
130 *
131 * @see NavigationContext
132 */
133 private Class context;
134
135 /***
136 * The the class that implements the NavigationManager interface.
137 *
138 * @see NavigationManager
139 */
140 private Class manager;
141
142 /***
143 * The class that implements the page changed listener interface.
144 */
145 private Class pageChangedListener;
146
147 /***
148 * The URL calculator class
149 */
150 private Class urlCalculator;
151
152 /***
153 * The URL rewriter class
154 */
155 private Class urlRewriter;
156
157 /***
158 * The class that implements the webflow changed listener interface.
159 */
160 private Class webflowChangedListener;
161
162 /***
163 * The configuration exception.
164 */
165 private ConfigException exception = null;
166
167 /***
168 * True if the cleaner is enabled.
169 */
170 private boolean cleanerEnabled;
171
172 /***
173 * True if the webflow navigation manager is enabled.
174 */
175 private boolean enabled;
176
177 /***
178 * True if the no cache option has been enabled
179 */
180 private boolean noCacheEnabled;
181
182 /***
183 * True if the clestatistics are enabled.
184 */
185 private boolean statsEnabled;
186
187 /***
188 * The default webflows ownership.
189 */
190 private int defaultOwnership;
191
192 /***
193 * Creates a new Config object.
194 *
195 * @param enabled true if the cleaner is enabled
196 * @param cleanerEnabled true if the webflow navigation manager is enabled
197 * @param statsEnabled true if the statistics are enabled
198 * @param defaultOwnership the default webflows ownership
199 * @param urlRewriter the url rewriter class
200 * @param urlCalculator the url calculator class
201 */
202 public Config(boolean enabled, boolean cleanerEnabled, boolean statsEnabled, int defaultOwnership,
203 Class urlRewriter, Class urlCalculator) {
204 this(enabled, cleanerEnabled, statsEnabled, true, defaultOwnership, urlRewriter, NavigationManagerImpl.class,
205 NavigationContextImpl.class, null, null, urlCalculator);
206 }
207
208 /***
209 * Creates a new Config object.
210 *
211 * @param enabled true if the cleaner is enabled
212 * @param cleanerEnabled true if the webflow navigation manager is enabled
213 * @param statsEnabled true if the statistics are enabled
214 * @param noCacheEnabled true if the no cache option is enabled
215 * @param defaultOwnership the default webflows ownership
216 * @param urlRewriter the url rewriter class
217 * @param manager the manager implementation to use
218 * @param context the context implementation to use
219 * @param pageChangedListener the page changed listener to use
220 * @param webflowChangedListener the webflow changed listener to use
221 * @param urlCalculator the url calculator class
222 */
223 public Config(boolean enabled, boolean cleanerEnabled, boolean statsEnabled, boolean noCacheEnabled,
224 int defaultOwnership, Class urlRewriter, Class manager, Class context, Class pageChangedListener,
225 Class webflowChangedListener, Class urlCalculator) {
226 this.enabled = enabled;
227 this.cleanerEnabled = cleanerEnabled;
228 this.statsEnabled = statsEnabled;
229 this.noCacheEnabled = noCacheEnabled;
230 this.defaultOwnership = defaultOwnership;
231 this.urlRewriter = urlRewriter;
232 this.manager = manager;
233 this.context = context;
234 this.pageChangedListener = pageChangedListener;
235 this.webflowChangedListener = webflowChangedListener;
236 this.urlCalculator = urlCalculator;
237 }
238
239 /***
240 * Creates a new Config object.
241 */
242 public Config() {
243 this(Config.class, WFNM_DEFAULT_PROPERTIES);
244 }
245
246 /***
247 * Creates a new Config object.
248 *
249 * @param loaderClass the loader class
250 * @param fileName the file name to load
251 */
252 public Config(Class loaderClass, String fileName) {
253 this(loaderClass.getResourceAsStream(fileName));
254 }
255
256 /***
257 * Creates a new Config object.
258 *
259 * @param loaderClass the loader class
260 */
261 public Config(Class loaderClass) {
262 this(loaderClass.getResourceAsStream(WFNM_DEFAULT_PROPERTIES));
263 }
264
265 /***
266 * Creates a new Config object.
267 *
268 * @param is the input stream
269 */
270 public Config(InputStream is) {
271 super();
272
273 Properties props = new Properties();
274
275 try {
276 props.load(is);
277 } catch (IOException ioe) {
278 this.exception = new ConfigException("Unable to read configuration file", ioe);
279
280 return;
281 }
282
283 String isEnabledString = props.getProperty(WFNM_ENABLED_KEY);
284 this.enabled = (isEnabledString != null) && Boolean.valueOf(isEnabledString).booleanValue();
285
286 String isCleanerEnabledString = props.getProperty(WFNM_CLEANER_ENABLED_KEY);
287 this.cleanerEnabled = (isCleanerEnabledString != null) &&
288 Boolean.valueOf(isCleanerEnabledString).booleanValue();
289
290 String isStatsEnabledString = props.getProperty(WFNM_STATS_ENABLED_KEY);
291 this.statsEnabled = (isStatsEnabledString != null) && Boolean.valueOf(isStatsEnabledString).booleanValue();
292
293 String defaultOwnershipString = props.getProperty(WFNM_DEFAULT_OWNERSHIP_KEY);
294 this.defaultOwnership = StringUtils.findIgnoreCase(defaultOwnershipString, NavigationManager.OWNERSHIP_DESC);
295
296 if (defaultOwnership < 0) {
297 this.exception = new ConfigException("The ownership must be included in " +
298 Arrays.asList(NavigationManager.OWNERSHIP_DESC).toString());
299 }
300
301 String noCacheEnabledString = props.getProperty(WFNM_NO_CACHE_ENABLED_KEY);
302 this.noCacheEnabled = (noCacheEnabledString != null) && Boolean.valueOf(noCacheEnabledString).booleanValue();
303
304 try {
305 this.urlRewriter = loadClass(props.getProperty(WFNM_URL_REWRITER_KEY));
306 this.manager = loadClass(props.getProperty(WFNM_MANAGER_KEY));
307 this.context = loadClass(props.getProperty(WFNM_CONTEXT_KEY));
308
309 String pageChangedListenerString = props.getProperty(WFNM_PAGE_CHANGED_LISTENER_KEY);
310
311 if ((pageChangedListenerString != null) && (pageChangedListenerString.length() > 0)) {
312 this.pageChangedListener = loadClass(pageChangedListenerString);
313 }
314
315 String webflowChangedListenerString = props.getProperty(WFNM_WEBFLOW_CHANGED_LISTENER_KEY);
316
317 if ((webflowChangedListenerString != null) && (webflowChangedListenerString.length() > 0)) {
318 this.webflowChangedListener = loadClass(webflowChangedListenerString);
319 }
320
321 this.urlCalculator = loadClass(props.getProperty(WFNM_URL_CALCULAOR_KEY));
322 } catch (ConfigException ce) {
323 this.exception = ce;
324 }
325 }
326
327 /***
328 * Sets the unique instance of the configuration.
329 *
330 * @param theInstance the instance of the configuration
331 */
332 public static void setInstance(Config theInstance) {
333 instance = theInstance;
334 }
335
336 /***
337 * Gets the unique instance of the configuration.
338 *
339 * @return the unique instance of the configuration
340 */
341 public static Config getInstance() {
342 if (instance == null) {
343 synchronized (synchLock) {
344 if (instance == null) {
345 instance = new Config();
346 }
347 }
348 }
349
350 if (instance.getException() != null) {
351 throw instance.getException();
352 }
353
354 return instance;
355 }
356
357 /***
358 * Indicates whether the cleaner is enabled.
359 *
360 * @return true if the cleaner is enabled
361 */
362 public boolean isCleanerEnabled() {
363 return cleanerEnabled;
364 }
365
366 /***
367 * Returns the context implementation.
368 *
369 * @return the context implementation
370 */
371 public Class getContext() {
372 return context;
373 }
374
375 /***
376 * Gets the default ownership.
377 *
378 * @return the default ownership
379 */
380 public int getDefaultOwnership() {
381 return defaultOwnership;
382 }
383
384 /***
385 * Indicates whether the Webflow Navigation Manager is enabled.
386 *
387 * @return true if the Webflow Navigation Manager is enabled
388 */
389 public boolean isEnabled() {
390 return enabled;
391 }
392
393 /***
394 * Gets the exception, if occurred.
395 *
396 * @return the exception, if occurred
397 */
398 public ConfigException getException() {
399 return exception;
400 }
401
402 /***
403 * Returns the class that implements the NavigationManager interface.
404 *
405 * @return the class that implements the NavigationManager interface
406 *
407 * @see NavigationManager
408 */
409 public Class getManager() {
410 return manager;
411 }
412
413 /***
414 * Returns true if the no cache option is enabled.
415 *
416 * @return true if the no cache option is enabled
417 */
418 public boolean isNoCacheEnabled() {
419 return noCacheEnabled;
420 }
421
422 /***
423 * Returns the page changed listener class.
424 *
425 * @return the page changed listener class
426 */
427 public Class getPageChangedListener() {
428 return pageChangedListener;
429 }
430
431 /***
432 * Returns true if statistics are enabled.
433 *
434 * @return true if statistics are enabled
435 */
436 public boolean isStatsEnabled() {
437 return statsEnabled;
438 }
439
440 /***
441 * Returns the URL calculator class.
442 *
443 * @return the URL calculator class
444 */
445 public Class getUrlCalculator() {
446 return urlCalculator;
447 }
448
449 /***
450 * Returns the URL rewriter.
451 *
452 * @return the URL rewriter
453 */
454 public Class getUrlRewriter() {
455 return urlRewriter;
456 }
457
458 /***
459 * Returns the webflow changed listener class.
460 *
461 * @return the webflow changed listener class
462 */
463 public Class getWebflowChangedListener() {
464 return webflowChangedListener;
465 }
466
467 /***
468 * Load a class given its name.
469 *
470 * @param className the class name
471 *
472 * @return the class
473 */
474 private static Class loadClass(String className) {
475 Class result = null;
476
477 if ((className != null) && (className.trim().length() > 0)) {
478 try {
479 result = Class.forName(className);
480 } catch (Exception e) {
481 throw new ConfigException("Unable to load class " + className, e);
482 }
483 }
484
485 return result;
486 }
487 }