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.ArrayList;
030: import java.util.HashMap;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.Map;
034: import java.util.Properties;
035:
036: import org.cougaar.core.util.UID;
037: import org.cougaar.util.log.Logger;
038: import org.cougaar.util.log.Logging;
039: import org.xml.sax.Attributes;
040: import org.xml.sax.helpers.AttributesImpl;
041:
042: /**
043: * This extension to {@link Frame} is the runtime representation of a
044: * prototype. It's main job at runtime is to hold non-static default
045: * values (static defaults are code-generated into constants) and to
046: * process {@link Path} slot values.
047: */
048: public class PrototypeFrame extends Frame {
049: private final String prototype_name;
050: private final String parent_prototype;
051: private final transient List<String> inheritableSlots;
052: private transient Logger log = Logging.getLogger(getClass()
053: .getName());
054: private final transient Map<String, Object> dynamic_values;
055: private final Attributes attrs;
056: private final Map<String, Path> path_cache;
057: private final Map<String, Attributes> slots;
058:
059: PrototypeFrame(FrameSet frameSet, String prototype_name,
060: String parent, UID uid, Attributes attrs,
061: Map<String, Attributes> slots) {
062: super (frameSet, uid);
063: this .inheritableSlots = new ArrayList<String>();
064: for (Map.Entry<String, Attributes> entry : slots.entrySet()) {
065: String inheritance = entry.getValue().getValue(
066: "inheritable-through");
067: if (inheritance == null || inheritance.equals("all")) {
068: inheritableSlots.add(entry.getKey());
069: }
070: }
071: this .parent_prototype = parent;
072: this .prototype_name = prototype_name;
073: this .slots = slots;
074: this .dynamic_values = new HashMap<String, Object>();
075: this .attrs = attrs;
076: this .path_cache = new HashMap<String, Path>();
077: }
078:
079: public String getKind() {
080: return parent_prototype;
081: }
082:
083: public Properties getSlotDefinitions() {
084: // return a copy
085: Properties defs = new Properties();
086: Iterator itr = slots.entrySet().iterator();
087: while (itr.hasNext()) {
088: Map.Entry entry = (Map.Entry) itr.next();
089: Object key = entry.getKey();
090: Attributes attrs = (Attributes) entry.getValue();
091: defs.put(key, new AttributesImpl(attrs));
092: }
093: return defs;
094: }
095:
096: public List<String> getInheritedSlots() {
097: return inheritableSlots;
098: }
099:
100: public Properties getLocalSlots() {
101: Properties result = new VisibleProperties();
102: Iterator itr = slots.entrySet().iterator();
103: while (itr.hasNext()) {
104: Map.Entry entry = (Map.Entry) itr.next();
105: String slot_name = (String) entry.getKey();
106: Attributes attrs = (Attributes) entry.getValue();
107: Object slot_value = dynamic_values.get(slot_name);
108: if (slot_value != null) {
109: result.put(slot_name, slot_value);
110: } else {
111: slot_value = attrs.getValue("default-value");
112: if (slot_value != null)
113: result.put(slot_name, slot_value);
114: }
115: }
116: return result;
117: }
118:
119: public void setValue(String slot, Object value) {
120: dynamic_values.put(slot, value);
121: }
122:
123: Object getValue(Frame origin, String slot_name) {
124: // Look for a dynamically set default first.
125: Object slot_value = dynamic_values.get(slot_name);
126: if (slot_value != null)
127: return slot_value;
128:
129: Attributes attrs = slots.get(slot_name);
130: if (attrs != null) {
131: // Declared at this level -- either get a real value or
132: // complain and return null.
133: Object result = null;
134: String value = attrs.getValue("default-value");
135: String warnp = attrs.getValue("warn");
136: String path_name = attrs.getValue("path");
137: if (value != null) {
138: result = value;
139: } else if (path_name != null) {
140: if (origin instanceof PrototypeFrame) {
141: // Makes no sense to follow a path in this case.
142: return null;
143: }
144: Path path;
145: synchronized (path_cache) {
146: path = path_cache.get(path_name);
147: if (path == null) {
148: path = getFrameSet().findPath(path_name);
149: path_cache.put(path_name, path);
150: }
151: }
152: result = path.getValue((DataFrame) origin, slot_name);
153: } else if (warnp == null || warnp.equalsIgnoreCase("true")) {
154: if (log.isWarnEnabled())
155: log.warn("Slot " + slot_name
156: + " is required by prototype "
157: + prototype_name
158: + " but was never provided in frame "
159: + origin);
160: }
161: return result;
162: } else {
163: // Not owned by us, check super
164: return getInheritedValue(origin, slot_name);
165: }
166: }
167:
168: public String getName() {
169: return prototype_name;
170: }
171:
172: public String getPrototypeName() {
173: return prototype_name;
174: }
175:
176: public String getAttribute(String key) {
177: return attrs.getValue(key);
178: }
179:
180: public String toString() {
181: return "<Prototype " + prototype_name + " " + getUID() + ">";
182: }
183:
184: public boolean isa(String kind) {
185: if (frameSet == null)
186: return kind.equals(prototype_name);
187: return frameSet.descendsFrom(this, kind);
188: }
189:
190: }
|