001: /*
002: * <copyright>
003: *
004: * Copyright 1997-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:
027: package org.cougaar.core.qos.frame;
028:
029: import java.util.Iterator;
030: import java.util.Map;
031: import java.util.Properties;
032:
033: import org.cougaar.core.blackboard.OverrideChangeReport;
034: import org.cougaar.core.qos.metrics.VariableEvaluator;
035: import org.cougaar.core.util.UID;
036: import org.cougaar.core.util.UniqueObject;
037: import org.cougaar.util.log.Logger;
038: import org.cougaar.util.log.Logging;
039:
040: /**
041: * This class is the most abstract representation of a frame and includes almost
042: * all of the generic implementation.
043: */
044: abstract public class Frame implements UniqueObject, Cloneable,
045: VariableEvaluator {
046: private final UID uid;
047:
048: protected transient FrameSet frameSet;
049:
050: private static Logger log = Logging
051: .getLogger(org.cougaar.core.qos.frame.Frame.class);
052:
053: Frame(FrameSet frameSet, UID uid) {
054: this .frameSet = frameSet;
055: this .uid = uid;
056: }
057:
058: /**
059: *
060: * @return The name of the prototype if this frame is a DataFrame, or
061: * the name of the base prototype if this frame is a
062: * PrototypeFrame
063: */
064: abstract public String getKind();
065:
066: /**
067: *
068: * @return Name/value pairs for the local slots of this frame
069: */
070: abstract public Properties getLocalSlots();
071:
072: /**
073: * Updates the value of the given slot
074: */
075: abstract public void setValue(String slot, Object value);
076:
077: /**
078: *
079: * @param kind
080: * The name of a prototype
081: * @return True iff this frame is of that prototype
082: */
083: abstract public boolean isa(String kind);
084:
085: abstract Object getValue(Frame origin, String slot);
086:
087: public Frame copy() {
088: try {
089: Frame copy = (Frame) this .clone();
090: copy.frameSet = null;
091: return copy;
092: } catch (CloneNotSupportedException ex) {
093: log.error(null, ex);
094: return null;
095: }
096: }
097:
098: public PrototypeFrame getPrototype() {
099: if (frameSet == null)
100: return null;
101: PrototypeFrame result = frameSet.getPrototype(this );
102: return result;
103: }
104:
105: public FrameSet getFrameSet() {
106: return frameSet;
107: }
108:
109: boolean matchesSlots(Properties slot_value_pairs) {
110: Iterator itr = slot_value_pairs.entrySet().iterator();
111: while (itr.hasNext()) {
112: Map.Entry entry = (Map.Entry) itr.next();
113: String slot = (String) entry.getKey();
114: Object value = getValue(slot);
115: if (value == null)
116: return false;
117: if (!value.equals(entry.getValue()))
118: return false;
119: }
120: return true;
121: }
122:
123: // These should only be called from the FrameSet owning the
124: // frame.
125:
126: protected Object getInheritedValue(Frame origin, String slot) {
127: if (frameSet == null)
128: return null;
129: Frame prototype = frameSet.getPrototype(this );
130: if (prototype == null)
131: return null;
132: return prototype.getValue(origin, slot);
133: }
134:
135: // org.cougaar.core.qos.metrics.VariableEvaluator
136: public String evaluateVariable(String var) {
137: return getValue(var).toString();
138: }
139:
140: public Object getValue(String slot) {
141: return getValue(this , slot);
142: }
143:
144: // UniqueObject
145: public UID getUID() {
146: return uid;
147: }
148:
149: public void setUID(UID uid) {
150: if (!uid.equals(this .uid))
151: throw new RuntimeException("UID already set");
152: }
153:
154: /**
155: * Frames are equal iff they have the same UID
156: */
157: public boolean equals(Object o) {
158: return ((o == this ) || ((o instanceof Frame) && uid
159: .equals(((Frame) o).uid)));
160: }
161:
162: public int hashCode() {
163: return uid.hashCode();
164: }
165:
166: /**
167: * This trivial extension of Properties has a bean-ish reader method
168: * listing the contents as a string (handy for the
169: * {@link FrameViewerServlet}).
170: */
171: public static class VisibleProperties extends Properties {
172: VisibleProperties() {
173: super ();
174: }
175:
176: VisibleProperties(Properties properties) {
177: super ();
178: putAll(properties);
179: }
180:
181: public String getContents() {
182: return this .toString();
183: }
184: }
185:
186: /**
187: * This extension of ChangeReport is used to describe a change to a
188: * Frame. Collections of these are included with frame changes published
189: * to the Blackboard.
190: */
191: public static class Change implements OverrideChangeReport {
192: private final String slot;
193:
194: private final Object value;
195:
196: private final UID frame_uid;
197:
198: public Change(UID frame_uid, String attr, Object val) {
199: this .slot = attr;
200: this .value = val;
201: this .frame_uid = frame_uid;
202: }
203:
204: public String toString() {
205: return "[" + frame_uid + " " + slot + "->" + value + "]";
206: }
207:
208: public String getSlotName() {
209: return slot;
210: }
211:
212: public Object getValue() {
213: return value;
214: }
215:
216: public UID getFrameUID() {
217: return frame_uid;
218: }
219:
220: // Object
221: public boolean equals(Object o) {
222: return ((o == this ) || ((o instanceof Change)
223: && slot.equals((((Change) o).slot)) && frame_uid
224: .equals((((Change) o).frame_uid))));
225: }
226:
227: public int hashCode() {
228: return slot.hashCode() ^ frame_uid.hashCode();
229: }
230: }
231:
232: }
|