Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/argouml/configuration/ConfigurationHandler.java


1   // Copyright (c) 1996-2001 The Regents of the University of California. All
2   // Rights Reserved. Permission to use, copy, modify, and distribute this
3   // software and its documentation without fee, and without a written
4   // agreement is hereby granted, provided that the above copyright notice
5   // and this paragraph appear in all copies.  This software program and
6   // documentation are copyrighted by The Regents of the University of
7   // California. The software program and documentation are supplied "AS
8   // IS", without any accompanying services from The Regents. The Regents
9   // does not warrant that the operation of the program will be
10  // uninterrupted or error-free. The end-user understands that the program
11  // was developed for research purposes and is advised not to rely
12  // exclusively on the program for any reason.  IN NO EVENT SHALL THE
13  // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
14  // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
15  // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
16  // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
17  // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
18  // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
20  // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
21  // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
22  // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  
24  //
25  //  This code is originally from the open source UML editor argouml.
26  //  Information on argouml can be found at: http://argouml.tigris.org/
27  //
28  //  The original author is Thierry Lach  
29  //
30  //  Adopted by Matthieu Cormier on Fri June 27 2003.
31  
32  package org.argouml.configuration;
33  
34  import java.beans.*;
35  import java.io.*;
36  import java.util.*;
37  import java.net.*;
38  
39  import simple.logging.*;
40  
41  /**
42   *   This class provides a user configuration based upon properties.
43   *   This provides an implementation-free interface to a configuration
44   *   repository.  Any classes which need to implement a configuration
45   *   datastore must extend this class.
46   *
47   *   All of the required behavioral logic for the configuration is
48   *   contained within this class, as public final methods.  Any
49   *   storage-related logic must be handled by the extending class.
50   *   These methods are abstract.
51   *
52   *   This class is intimately related to
53   *   {@link org.argouml.configuration.Configuration}.
54   *   
55   */
56  public abstract class ConfigurationHandler {
57  
58    /** Internal storage for the <code>File</code> the configuration was
59     *  loaded from, otherwise null.
60     */
61    private File _loadedFromFile = null;
62  
63    /** Internal storage for the <code>URL</code> the configuration was
64     *  loaded from, otherwise null.
65     */ 
66    private URL _loadedFromURL = null;
67  
68    /** Internal flag indicating whether the configuration can be updated.
69     */
70    private boolean _changeable = false;
71  
72    /** Internal flag indicating whether the configuration has been loaded.
73     *  Configuration rules allow a single load, whether manual or automatic.
74     */
75    private boolean _loaded = false;
76  
77    /** Internal flag indicating whether the configuration has been modified
78     *  after it was loaded.
79     */
80    private boolean _changed = false;
81  
82    /** Internal worker for property change.
83     */
84    private static PropertyChangeSupport _pcl = null; 
85  
86    /** Anonymous constructor allows configuration changes.
87     */
88    public ConfigurationHandler() {
89        this(true);
90    }
91  
92    /** Constructor which optionally allows configuration changes.
93     */
94    public ConfigurationHandler(boolean changeable) {
95        super();
96        _changeable = changeable;
97    }
98  
99    /** Returns a default configuration path.  This could be a filename
100    *  or a URL.  It is not guaranteed to be usable across different
101    *  implementations of ConfigurationHandler.
102    *
103    *  @return the default configuration path or url.
104    */
105   public abstract String getDefaultPath();
106 
107   /** Internal worker which is called prior to any getValue
108    *  or setValue to ensure that the default load is done if it was not
109    *  loaded previously.
110    */
111   private void loadIfNecessary() {
112       if (!_loaded) loadDefault();
113   }
114 
115   /** Load the configuration from the default location.
116    *
117    *  @return true if this call loaded the configuration,
118    *  otherwise false, not distinguishing between a load
119    *  error or a previously loaded configuration.
120    *
121    *  @see #isLoaded
122    */
123     public final boolean loadDefault() 
124     {
125         // Only allow one load
126         if (_loaded) return false;
127     
128         Log.out("Loading " + getDefaultPath() );
129         
130         boolean status = load(new File(getDefaultPath()));
131         if (!status) status = loadUnspecified();
132         _loaded = true;
133         return status;
134     }
135 
136   /** Save the configuration to the location it was loaded from.
137    *  Do not force it if the configuration was not loaded already.
138    *
139    *  @return true if the save was successful, false if it was not
140    *  attempted or encountered an error.
141    */
142   public final boolean saveDefault() {
143       return saveDefault(false);
144   }
145 
146   /** Save the configuration to the location it was loaded from.
147    *
148    *  @return true if the save was successful, false if it was not
149    *  attempted or encountered an error.
150    */
151   public final boolean saveDefault(boolean force) {
152       if (force) {
153           File toFile = new File(getDefaultPath());
154           boolean saved = saveFile(toFile);
155     if (saved) {
156         _loadedFromFile = toFile;
157     }
158     return saved;
159       }
160       if (! _loaded) return false;
161 
162       if (_loadedFromFile != null) {
163           return saveFile(_loadedFromFile);
164       }
165       if (_loadedFromURL != null) {
166           return saveURL(_loadedFromURL);
167       }
168       return false;
169   }
170 
171   /** Indicates whether the configuration can be saved.
172    *
173    *  @return true if the configuration can be saved.
174    */
175   public final boolean isChangeable() { return _changeable; }
176 
177   /** Indicates whether the configuration can be saved.
178    *
179    *  @return true if the configuration has been changed after load.
180    */
181   public final boolean isChanged() { return _changed; }
182 
183   /** Indicates whether the configuration has been loaded.
184    *
185    *  @return true if the configuration has been loaded.
186    */
187   public final boolean isLoaded() { return _loaded; }
188 
189   /** Load the configuration from a <code>File</code>.
190    *
191    *  @return true if this call loaded the configuration,
192    *  otherwise false, not distinguishing between a load
193    *  error or a previously loaded configuration.
194    */
195 
196   public final boolean load(File file) {
197       boolean status = loadFile(file);
198       if (status) {
199           if (_pcl != null) {
200               _pcl.firePropertyChange(Configuration.FILE_LOADED, null, file);
201           }
202           _loadedFromFile = file;
203       }
204       return status;
205   }
206 
207   /** Load the configuration from a <code>URL</code>.
208    *
209    *  @return true if this call loaded the configuration,
210    *  otherwise false, not distinguishing between a load
211    *  error or a previously loaded configuration.
212    */ 
213   public final boolean load(URL url) {
214       boolean status = loadURL(url);
215       if (status) {
216           if (_pcl != null) {
217               _pcl.firePropertyChange(Configuration.URL_LOADED, null, url);
218           }
219           _loadedFromURL = url;
220       }
221       return status;
222   }
223 
224   /** Save the configuration to a <code>File</code>.
225    *
226    *  @return true if this call saved the configuration,
227    *  otherwise false.
228    */ 
229   public final boolean save(File file) {
230       if (! _loaded) {
231           return false;
232       }
233       boolean status = saveFile(file);
234       if (status) {
235           if (_pcl != null) {
236               _pcl.firePropertyChange(Configuration.FILE_SAVED, null, file);
237           }
238       }
239       return status;
240   }
241 
242   /** Save the configuration to a <code>URL</code>.
243    *
244    *  @return true if this call saved the configuration,
245    *  otherwise false.
246    */ 
247   public final boolean save(URL url) {
248       if (! _loaded) {
249           return false;
250       }
251       boolean status = saveURL(url);
252       if (status) {
253           if (_pcl != null) {
254               _pcl.firePropertyChange(Configuration.URL_SAVED, null, url);
255           }
256       }
257       return status;
258   }
259 
260   /** Returns the string value of a configuration property.
261    *
262    *  @param key the configuration key to return.
263    *  @param defaultValue the default value key to return
264    *  if the key is not found.
265    *
266    *  @return the value of the key or the default value
267    *  if the key does not exist.
268    */
269   public final String getString(ConfigurationKey key, String defaultValue) {
270       loadIfNecessary();
271       return getValue(key.getKey(), defaultValue);
272   }
273 
274   /** Returns the numeric value of a configuration property.
275    *
276    *  @param key the configuration key to return.
277    *  @param defaultValue the default value key to return
278    *  if the key is not found.
279    *
280    *  @return the value of the key or the default value
281    *  if the key does not exist.
282    */
283   public final int getInteger(ConfigurationKey key, int defaultValue) {
284       loadIfNecessary();
285       try {
286           String s = getValue(key.getKey(), Integer.toString(defaultValue));
287           return Integer.parseInt(s);
288       }
289       catch (NumberFormatException nfe) {
290           return defaultValue;
291       }
292   }
293 
294   /** Returns the numeric value of a configuration property.
295    *
296    *  @param key the configuration key to return.
297    *  @param defaultValue the default value key to return
298    *  if the key is not found.
299    *
300    *  @return the value of the key or the default value
301    *  if the key does not exist.
302    */
303   public final double getDouble(ConfigurationKey key, double defaultValue) {
304       loadIfNecessary();
305       try {
306           String s = getValue(key.getKey(), Double.toString(defaultValue));
307           return Double.parseDouble(s);
308       }
309       catch (NumberFormatException nfe) {
310           return defaultValue;
311       }
312   }
313 
314   /** Returns the boolean value of a configuration property.
315    *
316    *  @param key the configuration key to return.
317    *  @param defaultValue the default value key to return
318    *  if the key is not found.
319    *
320    *  @return the value of the key or the default value
321    *  if the key does not exist.
322    */
323   public final boolean getBoolean(ConfigurationKey key, boolean defaultValue) {
324       loadIfNecessary();
325       Boolean dflt = new Boolean(defaultValue);
326       Boolean b = new Boolean(getValue(key.getKey(), dflt.toString()));
327       return b.booleanValue();
328   }
329 
330   /** Internal routine which calls the abstract setValue and handles
331    *  all necessary functionality including firing property change
332    *  notifications and tracing.  
333    *
334    *  @param key the configuration key to modify.
335    *  @param newValue the new value of the key.
336    */
337   private synchronized final void workerSetValue(ConfigurationKey key, String newValue) {
338       loadIfNecessary();
339 
340       String oldValue = getValue(key.getKey(), "");
341       setValue(key.getKey(), newValue);
342       if (_pcl != null) {
343           _pcl.firePropertyChange(key.getKey(), oldValue, newValue);
344       }
345   }
346 
347   /** Sets the string value of a configuration property.
348    *
349    *  @param key the configuration key to modify.
350    *  @param newValue the value to set the key to.
351    */
352   public final void setString(ConfigurationKey key, String newValue) {
353       workerSetValue(key, newValue);
354   }
355 
356   /** Sets the numeric value of a configuration property.
357    *
358    *  @param key the configuration key to modify.
359    *  @param value the value to set the key to.
360    */
361   public final void setInteger(ConfigurationKey key, int value) {
362       workerSetValue(key, Integer.toString(value));
363   }
364 
365   /** Sets the numeric value of a configuration property.
366    *
367    *  @param key the configuration key to modify.
368    *  @param value the value to set the key to.
369    */
370   public final void setDouble(ConfigurationKey key, double value) {
371       workerSetValue(key, Double.toString(value));
372   }
373 
374   /** Sets the boolean value of a configuration property.
375    *
376    *  @param key the configuration key to modify.
377    *  @param value the value to set the key to.
378    */
379   public final void setBoolean(ConfigurationKey key, boolean value) {
380       Boolean bool = new Boolean(value);
381       workerSetValue(key, bool.toString());
382   }
383 
384   /** Adds a property change listener.
385    *
386    *  @param pcl The class which will listen for property changes.
387    */
388   public final void addListener(PropertyChangeListener pcl) {
389       if (_pcl == null) {
390           _pcl = new PropertyChangeSupport(this);
391       }
392      
393       _pcl.addPropertyChangeListener(pcl);
394   }
395 
396   /** Removes a property change listener.
397    *
398    *  @param pcl The class to remove as a property change listener.
399    */
400   public final void removeListener(PropertyChangeListener pcl) {
401       if (_pcl != null) {
402          
403           _pcl.removePropertyChangeListener(pcl);
404       }
405   }
406 
407   /** Adds a property change listener.Static for simplicity of use.
408    *
409    *  @param key The specific key to listen for.
410    *  @param pcl The class which will listen for property changes.
411    */
412   public final void addListener(ConfigurationKey key, PropertyChangeListener pcl) {
413       if (_pcl == null) {
414           _pcl = new PropertyChangeSupport(this);
415       }
416       
417       _pcl.addPropertyChangeListener(key.getKey(), pcl);
418   }
419 
420   /** Removes a property change listener.
421    *
422    *  @param key The specific key being listened for.
423    *  @param pcl The class to remove as a property change listener.
424    */
425   public final void removeListener(ConfigurationKey key, PropertyChangeListener pcl) {
426       if (_pcl != null) {
427           
428           _pcl.removePropertyChangeListener(key.getKey(), pcl);
429       }
430   }
431 
432   /** Internal processing to load from an unspecified source.
433    *
434    *  @return true if the load was successful, otherwise false.
435    */
436   boolean loadUnspecified() {
437       return false;
438   }
439 
440   /** Internal processing to save to an unspecified source.
441    *
442    *  @return true if the save was successful, otherwise false.
443    */
444   boolean saveUnspecified() {
445       return false;
446   }
447 
448   /** Internal processing to load a <code>File</code>.
449    *
450    *  @param file the file to load.
451    *
452    *  @return true if the load was successful, otherwise false.
453    */
454   abstract boolean loadFile(File file);
455 
456   /** Internal processing to load a <code>URL</code>.
457    *
458    *  @param url the url to load.
459    *
460    *  @return true if the load was successful, otherwise false.
461    */
462   abstract boolean loadURL(URL url);
463 
464   /** Internal processing to save a <code>File</code>.
465    *
466    *  @param file the file to save.
467    *
468    *  @return true if the save was successful, otherwise false.
469    */
470   abstract boolean saveFile(File file);
471 
472   /** Internal processing to save a <code>URL</code>.
473    *
474    *  @param url the url to save.
475    *
476    *  @return true if the save was successful, otherwise false.
477    */
478   abstract boolean saveURL(URL url);
479 
480   /** Allows query for the existence of a configuration property.
481    *  This may be overridden if the implementation has a
482    *  more efficient method.
483    * 
484    *  @param key  the property being checked.
485    *
486    *  @return true if the key exists, otherwise false.
487    */
488   public boolean hasKey(ConfigurationKey key) {
489       return getValue(key.getKey(), "true").equals(getValue(key.getKey(), "false"));
490   }
491 
492   /** Returns the string value of a configuration property.
493    *
494    *  @param key the configuration key to return.
495    *  @param defaultValue the configuration key to return.
496    *
497    *  @return the value of the key or the default value
498    *  if the key does not exist.
499    */
500   public abstract String getValue(String key, String defaultValue);
501 
502   /** Sets the string value of a configuration property.
503    *
504    *  @param key the configuration key to modify.
505    *  @param value the value to set the key to.
506    */
507   public abstract void setValue(String key, String value);
508 }
509 
510