001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.tools.csmart.util;
027:
028: import java.io.IOException;
029: import java.io.ObjectInputStream;
030: import java.io.Serializable;
031: import java.util.Iterator;
032: import java.util.Map;
033: import java.util.Observer;
034: import java.util.Properties;
035: import java.util.Set;
036:
037: public class ReadOnlyProperties extends Properties implements
038: Serializable {
039: protected Set readOnlyKeys = null;
040: private PropertiesObservable observable;
041:
042: public ReadOnlyProperties() {
043: super ();
044: init();
045: }
046:
047: public ReadOnlyProperties(Set readOnlyKeys) {
048: super ();
049: this .readOnlyKeys = readOnlyKeys;
050: init();
051: }
052:
053: public ReadOnlyProperties(Set readOnlyKeys, Properties defaults) {
054: super (defaults);
055: this .readOnlyKeys = readOnlyKeys;
056: init();
057: }
058:
059: private void init() {
060: if (observable == null)
061: observable = new PropertiesObservable();
062: }
063:
064: public void addObserver(Observer o) {
065: observable.addObserver(o);
066: }
067:
068: public void deleteObserver(Observer o) {
069: observable.deleteObserver(o);
070: }
071:
072: private void fireChange() {
073: if (observable == null)
074: observable = new PropertiesObservable();
075: observable.fireChange();
076: }
077:
078: public void setReadOnlyProperty(String key, String newValue) {
079: Object o = get(key);
080: if (o != null && o.equals(newValue))
081: return; // no change
082: super .put(key, newValue);
083: // System.out.println("Setting read only property: " + key);
084: fireChange();
085: }
086:
087: public Object setProperty(String key, String newValue) {
088: // System.out.println("Setting property: " + key);
089: // fireChange(); // change is fired in put if necessary
090:
091: // Dont call super.setProperty which is synchronized
092: // Wait to let super.put do the synchronization
093: // return super.setProperty(key, newValue);
094: return put(key, newValue);
095: }
096:
097: public boolean isReadOnly(Object key) {
098: if (readOnlyKeys == null)
099: return false;
100: if (readOnlyKeys.contains(key))
101: return true;
102: if (defaults instanceof ReadOnlyProperties) {
103: return ((ReadOnlyProperties) defaults).isReadOnly(key);
104: }
105: return false;
106: }
107:
108: // Override the Property interface implementation to enforce read-only keys
109:
110: public Object put(Object key, Object val) {
111: if (isReadOnly(key))
112: return null;
113: Object o = get(key);
114: if (o != null && o.equals(val))
115: return val; // no change
116: fireChange();
117: return super .put(key, val);
118: }
119:
120: public void putAll(Map map) {
121: boolean changeHappened = false;
122: for (Iterator entries = map.entrySet().iterator(); entries
123: .hasNext();) {
124: Map.Entry entry = (Map.Entry) entries.next();
125: Object key = entry.getKey();
126: if (isReadOnly(key))
127: continue;
128: Object o = get(key);
129: if (o != null && o.equals(entry.getValue()))
130: continue;
131: super .put(key, entry.getValue());
132: changeHappened = true;
133: }
134: // System.out.println("Put all");
135: if (changeHappened)
136: fireChange();
137: }
138:
139: public Object remove(Object key) {
140: if (isReadOnly(key))
141: return null;
142: if (!super .containsKey(key))
143: return null; // no change
144: fireChange();
145: return super .remove(key);
146: }
147:
148: public void clear() {
149: for (Iterator keys = keySet().iterator(); keys.hasNext();) {
150: Object key = keys.next();
151: if (isReadOnly(key))
152: continue;
153: keys.remove();
154: }
155: // System.out.println("Clearing");
156: fireChange();
157: }
158:
159: private void readObject(ObjectInputStream ois) throws IOException,
160: ClassNotFoundException {
161: ois.defaultReadObject();
162: }
163:
164: }
|