/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.avlist; import gov.nasa.worldwind.exception.WWRuntimeException; import gov.nasa.worldwind.util.Logging; import java.util.*; import java.util.logging.Level; /** * An implementation class for the {@link AVList} interface. Classes implementing <code>AVList</code> can subclass or * aggreate this class to provide default <code>AVList</code> functionality. This class maintains a hash table of * attribute-value pairs. * <p/> * This class implements a notification mechanism for attribute-value changes. The mechanism provides a means for * objects to observe attribute changes or queries for certain keys without explicitly monitoring all keys. See {@link * java.beans.PropertyChangeSupport}. * * @author Tom Gaskins * @version $Id: AVListImpl.java 4816 2008-03-26 19:46:19Z tgaskins $ */ public class AVListImpl implements AVList { // TODO: Make thread-safe /** * Available to sub-classes for further exposure of property-change functionality. */ protected final java.beans.PropertyChangeSupport changeSupport;// = new java.beans.PropertyChangeSupport(this); // To avoid unnecessary overhead, this object's hash map is created only if needed. private Map<String, Object> avList; /** * Creates an empty attribute-value list. */ public AVListImpl() { this.changeSupport = new java.beans.PropertyChangeSupport(this); } /** * Constructor enabling aggregation * @param sourceBean The bean to be given as the soruce for any events. */ public AVListImpl(Object sourceBean) { // TODO: check arg for non-null this.changeSupport = new java.beans.PropertyChangeSupport(sourceBean); } private boolean hasAvList() { return this.avList != null; } private Map<String, Object> createAvList() { if (!this.hasAvList()) { this.avList = new java.util.HashMap<String, Object>(); } return this.avList; } private Map<String, Object> avList(boolean createIfNone) { if (createIfNone && !this.hasAvList()) this.createAvList(); return this.avList; } public final Object getValue(String key) { if (key == null) { String message = Logging.getMessage("nullValue.AttributeKeyIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.hasAvList()) return this.avList.get(key); return null; } public final Collection<Object> getValues() { return this.hasAvList() ? this.avList.values() : this.createAvList().values(); } public Set<Map.Entry<String, Object>> getEntries() { return this.hasAvList() ? this.avList.entrySet() : this.createAvList().entrySet(); } public final String getStringValue(String key) { if (key == null) { String msg = Logging.getMessage("nullValue.AttributeKeyIsNull"); Logging.logger().severe(msg); throw new IllegalStateException(msg); } try { return (String) this.getValue(key); } catch (ClassCastException e) { String msg = Logging.getMessage("AVAAccessibleImpl.AttributeValueForKeyIsNotAString", key); Logging.logger().severe(msg); throw new WWRuntimeException(msg, e); } } public final void setValue(String key, Object value) { if (key == null) { String message = Logging.getMessage("nullValue.AttributeKeyIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Capture the existing value if there is one, then set the new value. this.avList(true).put(key, value); } public final void setValues(AVList list) { if (list == null) { String message = Logging.getMessage("nullValue.AttributesIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } Set<Map.Entry<String, Object>> entries = list.getEntries(); for (Map.Entry<String, Object> entry : entries) this.setValue(entry.getKey(), entry.getValue()); } public final boolean hasKey(String key) { if (key == null) { String message = Logging.getMessage("nullValue.KeyIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } return this.hasAvList() && this.avList.containsKey(key); } public final void removeKey(String key) { if (key == null) { String message = Logging.getMessage("nullValue.KeyIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.hasKey(key)) this.avList.remove(key); } public AVList copy() { AVListImpl clone = new AVListImpl(); clone.createAvList(); clone.avList.putAll(this.avList); return clone; } public final AVList clearList() { if (this.hasAvList()) this.avList.clear(); return this; } public void addPropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) { if (propertyName == null) { String msg = Logging.getMessage("nullValue.PropertyNameIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (listener == null) { String msg = Logging.getMessage("nullValue.ListenerIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, java.beans.PropertyChangeListener listener) { if (propertyName == null) { String msg = Logging.getMessage("nullValue.PropertyNameIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (listener == null) { String msg = Logging.getMessage("nullValue.ListenerIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.removePropertyChangeListener(propertyName, listener); } public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) { if (listener == null) { String msg = Logging.getMessage("nullValue.ListenerIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) { if (listener == null) { String msg = Logging.getMessage("nullValue.ListenerIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.removePropertyChangeListener(listener); } public void firePropertyChange(java.beans.PropertyChangeEvent propertyChangeEvent) { if (propertyChangeEvent == null) { String msg = Logging.getMessage("nullValue.PropertyChangeEventIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.firePropertyChange(propertyChangeEvent); } public void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (propertyName == null) { String msg = Logging.getMessage("nullValue.PropertyNameIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.changeSupport.firePropertyChange(propertyName, oldValue, newValue); } // Static AVList utilities. public static String getStringValue(AVList avList, String key, String defaultValue) { String v = getStringValue(avList, key); return v != null ? v : defaultValue; } public static String getStringValue(AVList avList, String key) { try { return avList.getStringValue(key); } catch (Exception e) { return null; } } public static Integer getIntegerValue(AVList avList, String key, Integer defaultValue) { Integer v = getIntegerValue(avList, key); return v != null ? v : defaultValue; } public static Integer getIntegerValue(AVList avList, String key) { Object o = avList.getValue(key); if (o == null) return null; if (o instanceof Integer) return (Integer) o; String v = getStringValue(avList, key); if (v == null) return null; try { return Integer.parseInt(v); } catch (NumberFormatException e) { Logging.logger().log(Level.SEVERE, "Configuration.ConversionError", v); return null; } } public static Long getLongValue(AVList avList, String key, Long defaultValue) { Long v = getLongValue(avList, key); return v != null ? v : defaultValue; } public static Long getLongValue(AVList avList, String key) { Object o = avList.getValue(key); if (o == null) return null; if (o instanceof Long) return (Long) o; String v = getStringValue(avList, key); if (v == null) return null; try { return Long.parseLong(v); } catch (NumberFormatException e) { Logging.logger().log(Level.SEVERE, "Configuration.ConversionError", v); return null; } } public static Double getDoubleValue(AVList avList, String key, Double defaultValue) { Double v = getDoubleValue(avList, key); return v != null ? v : defaultValue; } public static Double getDoubleValue(AVList avList, String key) { Object o = avList.getValue(key); if (o == null) return null; if (o instanceof Double) return (Double) o; String v = getStringValue(avList, key); if (v == null) return null; try { return Double.parseDouble(v); } catch (NumberFormatException e) { Logging.logger().log(Level.SEVERE, "Configuration.ConversionError", v); return null; } } }