ucar.util.prefs.PreferencesExt Maven / Gradle / Ivy
Show all versions of netcdf Show documentation
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.util.prefs;
import java.util.*;
import java.util.prefs.*;
/**
* An extension of java.util.prefs.Preferences (jdk 1.4) that provides a
* platform-independent implementation using XML files as backing store.
* To save Java beans, use putBean() and putBeanCollection(). This uses
* reflection to get/set properties that have simple single-valued accessor methods
* of primitive and String type.
*
For arbitrary objects, use putBeanObject(), which uses the
* XMLEncode/XMLDecode API (jdk 1.4).
*
* To obtain a PreferencesExt object, instantiate an XMLStore object and
* call XMLStore.getPreferences().
*
* @see ucar.util.prefs.XMLStore
* @see java.util.prefs.Preferences
* @author John Caron
*/
public class PreferencesExt extends java.util.prefs.AbstractPreferences implements ucar.util.prefs.PersistenceManager {
static Preferences userRoot = new PreferencesExt(null, ""); // ??
static Preferences systemRoot = new PreferencesExt(null, "");
/** Set the user root you get when you call Preferences.userRoot(). */
static public void setUserRoot( PreferencesExt prefs) { userRoot = prefs; }
/** Set the system root you get when you call Preferences.systemRoot(). */
static public void setSystemRoot( PreferencesExt prefs) {
systemRoot = prefs;
}
private boolean isBackingStoreAvailable = true;
private PreferencesExt parent;
private HashMap keyValues, children;
private PreferencesExt storedDefaults = null;
/**
* Constructor. Usually you get a PreferencesExt object from XMLStore.getPrefs(),
* rather than constructing one directly.
* For the root node, parent = null and name = "".
*/
public PreferencesExt(PreferencesExt parent, String name) {
super(parent, name);
this.parent = parent;
keyValues = new HashMap(20);
children = new HashMap(10);
}
void setStoredDefaults( PreferencesExt storedDefaults) {
this.storedDefaults = storedDefaults;
}
private PreferencesExt getStoredDefaults() {
return (parent == null) ? storedDefaults : parent.getStoredDefaults();
}
/** return true unless this is the systemRoot node */
public boolean isUserNode() { return this != systemRoot; } // ??
////////////////////////////////////////////////////////
// get/put beans
/**
* Get the object that has the specified key.
* This returns the object itself, not a copy, so
* if you change the bean and call store.save(), any changes to the object will be saved,
* even without calling putBean(). If you want to change the object without saving the
* changes, you must make a copy of the object yourself.
*
* @param key get the object with this key.
* @param def the default value to be returned in the event that this
* preference node has no value associated with key.
* @return the value associated with key, or def
* if no value is associated with key.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
* @throws NullPointerException if key is null. (A
* null default is permitted.)
*/
public Object getBean(String key, Object def) {
if (key==null)
throw new NullPointerException("Null key");
if (isRemoved())
throw new IllegalStateException("Node has been removed.");
synchronized(lock) {
Object result = null;
try {
result = _getObject( key);
if (result != null) {
if (result instanceof Bean.Collection)
result = ((Bean.Collection)result).getCollection();
else if (result instanceof Bean)
result = ((Bean)result).getObject();
}
} catch (Exception e) {
// Ignoring exception causes default to be returned
}
return (result==null ? def : result);
}
}
/**
* Stores an object using simple bean properties.
* If the exact key and value are already in
* the storedDefaults (using equals() to test for equality), then it is not
* stored.
*
* @param key key with which the specified value is to be associated.
* @param newValue store this bean.
* @throws NullPointerException if key or value is null.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public void putBean(String key, Object newValue) {
// if matches a stored Default, dont store
Object oldValue = getBean(key, null);
if ((oldValue == null) || !oldValue.equals( newValue))
keyValues.put( key, new Bean(newValue));
}
/**
* Stores a Collection of beans. The beans are stored using simple bean properties.
* The collection of beans must all be of the same class.
*
* @param key key with which the specified collection is to be associated.
* @param newValue store this collection of beans.
* @throws NullPointerException if key or value is null.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public void putBeanCollection(String key, Collection newValue) {
// if matches a stored Default, dont store
Object oldValue = getBean(key, null);
if ((oldValue == null) || !oldValue.equals( newValue))
keyValues.put( key, new Bean.Collection(newValue));
}
/**
* Stores an object using XMLEncoder/XMLDecoder. Use this for arbitrary objects.
* If the exact key and value are already in
* the storedDefaults (using equals() to test for equality), then it is not
* stored.
*
* @param key key with which the specified value is to be associated.
* @param newValue store this bean object.
* @throws NullPointerException if key or value is null.
* @throws IllegalStateException if this node (or an ancestor) has been
* removed with the {@link #removeNode()} method.
*/
public void putBeanObject(String key, Object newValue) {
// if matches a stored Default, dont store
Object oldValue = getBean(key, null);
if ((oldValue == null) || !oldValue.equals( newValue))
keyValues.put( key, newValue);
}
////////////////////////////////////////////////////////
// get/put list
/**
* Get an arrayList. This returns a copy of the stored list.
*
* @param key key whose associated value is to be returned.
* @param def the value to be returned in the event that this
* preference node has no value associated with key.
* @return the value associated with key, or def
* if no value is associated with key.
*/
public List getList(String key, List def) {
try {
Object bean = getBean(key, def);
return (List) bean;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Stores the value with this key, if the exact key and value are not already in
* the storedDefaults (using equals() to test for equality).
* "Two lists are defined to be equal if they contain the same elements in the same order."
*
* @param key key with which the specified value is to be associated.
* @param newValue value to be associated with the specified key.
*/
public void putList(String key, List newValue) {
putBeanObject(key, newValue);
}
/////// the SPI interface
/**
* Implements AbstractPreferences childrenNamesSpi() method.
* Find all children nodes of this node (or of identically named nodes in
* storedDefaults)
*/
protected String[] childrenNamesSpi() {
HashSet allKids = new HashSet(children.keySet());
PreferencesExt sd = getStoredDefaults();
if (sd != null)
allKids.addAll( sd.childrenNamesSpi(absolutePath()));
ArrayList list = new ArrayList( allKids);
Collections.sort(list);
String result[] = new String[list.size()];
for (int i=0; i