View Javadoc

1   /*
2    * WebFlow Navigation Manager: webflow definiton, server side navigation history and automatic session cleaning.
3    * Distributed under LGPL license at web site http://wfnm.sourceforge.net .
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 }