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.io.File;
030: import java.io.IOException;
031: import java.net.URL;
032: import java.util.Collection;
033: import java.util.Map;
034: import java.util.Observer;
035: import java.util.Properties;
036: import java.util.Set;
037:
038: import org.cougaar.core.qos.frame.aggregator.SlotAggregator;
039: import org.cougaar.core.qos.metrics.Metric;
040: import org.cougaar.core.util.UID;
041: import org.xml.sax.Attributes;
042:
043: /**
044: * This interface is an abstract specification of an organized
045: * collection of {@link Frame}s. The main job of a FrameSet is to
046: * handle inter-Frame relationships.
047: */
048:
049: public interface FrameSet {
050: /**
051: * One of two constants for the roles of frame relationship.
052: * This one if something like the mathematical "domain".
053: * @see #CHILD
054: */
055: public static final String PARENT = "parent";
056:
057: /**
058: * One of two constants for the roles of frame relationship.
059: * This one if something like the mathematical "range".
060: * @see #PARENT
061: */
062: public static final String CHILD = "child";
063:
064: /**
065: * Returns the name of the FrameSet.
066: */
067: public String getName();
068:
069: /**
070: * Returns the package used by the code generator
071: * when it writes Java classes for prototypes.
072: */
073: public String getPackageName();
074:
075: /**
076: * Returns true iff the given frame matches the given prototype,
077: * directly or indirectly.
078: */
079: public boolean descendsFrom(DataFrame frame, String prototype);
080:
081: /**
082: * Returns true iff the first prototype frame is an extension
083: * of the second one, directly or indirectly.
084: */
085: public boolean descendsFrom(PrototypeFrame frame, String prototype);
086:
087: /**
088: * Returns the DataFrame that matches the given triple, ie, whose
089: * prototype matches the given kind and whose value for the given
090: * slot matches the given value. If more than one frame matches,
091: * the first match is returned.
092: */
093: public DataFrame findFrame(String kind, String slot, Object value);
094:
095: /**
096: *
097: * @param name The name of a prototype
098: * @return the corresponding PrototypeFrame
099: */
100: public PrototypeFrame findPrototypeFrame(String name);
101:
102: /**
103: * Returns the frame with the given UID. There can be at most one.
104: */
105: public Frame findFrame(UID uid);
106:
107: /**
108: * Returns the path with the given name. There can be at most one.
109: */
110: public Path findPath(String name);
111:
112: /**
113: * Returns the path with the given UID. There can be at most one.
114: */
115: public Path findPath(UID uid);
116:
117: /**
118: * Returns a collection of DataFrames that match the given prototype and
119: * whose slots match all the given pairs.
120: */
121: public Set<DataFrame> findFrames(String kind,
122: Properties slot_value_pairs);
123:
124: /**
125: *
126: * @return true iff the relationship's {@link #PARENT}
127: * and {@link #CHILD} frame references are resolvable.
128: */
129: public boolean isResolved(RelationFrame frame);
130:
131: /**
132: * Returns a collection of {@link DataFrame}s representing frames
133: * related to the given one via a relationship matching the given
134: * prototype, and in which the given frame plays the given role
135: * @see #PARENT
136: * @see #CHILD
137: */
138: public Set<DataFrame> findRelations(Frame frame, // should be DataFrame
139: String role, String relation_proto);
140:
141: /**
142: * Returns a {@link DataFrame} that's related to the given one
143: * via a relationship matching the given prototype, and in which
144: * the given frame plays the given role.
145: *
146: * If there's more than one such frame, a random one will be
147: * returne. If there are no such frames, the return value
148: * is null.
149: *
150: * @see #PARENT
151: * @see #CHILD
152: */
153: public DataFrame findFirstRelation(Frame frame, // should be DataFrame
154: String role, String relation_proto);
155:
156: /**
157: * Returns a count of frames that are related to the given one
158: * via a relationship matching the given prototype, and in which
159: * the given frame plays the given role.
160: * @see #PARENT
161: * @see #CHILD
162: *
163: */
164: public int countRelations(Frame frame, // should be DataFrame
165: String role, String relation_proto);
166:
167: /**
168: * Returns a collection of {@link RelationFrame}s representing
169: * relationships of the given prototype in which the given frame
170: * plays the given role.
171: * @see #PARENT
172: * @see #CHILD
173: *
174: */
175: public Map<RelationFrame, DataFrame> findRelationshipFrames(
176: DataFrame frame, String role, String relation_proto);
177:
178: /**
179: * Adds a previously constucted DataFrame to this FrameSet. The
180: * Frame's current frameSet should be null. As a result of this
181: * operation the Frame will be published to the Blackboard.
182: */
183: public DataFrame makeFrame(DataFrame frame);
184:
185: /**
186: * Creates a DataFrame of the given kind and with the given intial
187: * values, and adds it to this FrameSet. A UID for the frame will
188: * be generated automatically. As a result of this operation the
189: * Frame will be published to the Blackboard.
190: */
191: public DataFrame makeFrame(String kind, Properties slots);
192:
193: /**
194: * Creates a DataFrame of the given kind and with the given intial
195: * values, and adds it to this FrameSet. The UID for the frame as
196: * specified. As a result of this operation the Frame will be
197: * published to the Blackboard.
198: */
199: public DataFrame makeFrame(String kind, Properties slots, UID uid);
200:
201: /**
202: * Optimized way to create a new relationship that avoids the lookup
203: * of the parent and child.
204: */
205: public RelationFrame makeRelationship(String kind,
206: Properties slots, DataFrame parent, DataFrame child);
207:
208: /**
209: * Creates a PrototypeFrame with the given name and default slot values,
210: * and that extends the given base prototype. A UID for the frame will
211: * be generated automatically. As a result of this operation the Frame
212: * will be published to the Blackboard.
213: */
214: public PrototypeFrame makePrototype(String kind, String base,
215: Attributes attrs, Map<String, Attributes> slots);
216:
217: /**
218: * Creates a PrototypeFrame with the given name UID, and intial values,
219: * and that extends the given pase prototype. As a result of this
220: * operation the Frame will be published to the Blackboard.
221: */
222: public PrototypeFrame makePrototype(String kind, String base,
223: Attributes attrs, Map<String, Attributes> slots, UID uid);
224:
225: /**
226: * Creates a Path and adds it to the FrameSet As a result of this
227: * operation the Path will be published to the Blackboard.
228: */
229: public Path makePath(String name, Path.Fork[] forks, String slot);
230:
231: /**
232: * Removes the given Frame from the FrameSet. As a result of this
233: * operation the Frame will also be removed from the Blackboard.
234: */
235: public void removeFrame(DataFrame frame);
236:
237: /**
238: * Removes the given Frame and all its relationships from the FrameSet.
239: * As a result of this
240: * operation the Frame will also be removed from the Blackboard.
241: */
242: public void removeFrameAndRelations(DataFrame frame);
243:
244: /**
245: * Returns the container of the given frame, if any. The
246: * exact meaning of 'containment' is specific to the FrameSet
247: * instance.
248: */
249: public DataFrame getContainer(DataFrame frame);
250:
251: /**
252: * Returns the given DataFrame's PrototypeFrame.
253: */
254: public PrototypeFrame getPrototype(Frame frame);
255:
256: /**
257: * Returns the matching {@link #PARENT} Frame in the given relationship.
258: */
259: public DataFrame getRelationshipParent(RelationFrame relationship);
260:
261: /**
262: * Returns the matching {@link #CHILD} Frame in the given relationship.
263: */
264: public DataFrame getRelationshipChild(RelationFrame relationship);
265:
266: /**
267: * Informs the FrameSet that the given frame was changed in the
268: * given way. As a result of this operation, a change will be
269: * published to the Blackboard.
270: */
271: public void valueUpdated(DataFrame frame, String slot, Object value);
272:
273: /**
274: * Forces the FrameSet to process any queued Blackboard operations.
275: * This call will block if a transaction is in progress.
276: *
277: * @see #runInTransaction(Runnable)
278: */
279: public void processQueue();
280:
281: /**
282: * Runs a body of code using a lock that prevents a
283: * simultaneous invocation of {@link #processQueue}.
284: * The runnable is executed in the caller's thread.
285: */
286: public void runInTransaction(Runnable r);
287:
288: /**
289: * Returns a collection of all PrototypeFrames in the FrameSet,
290: */
291: public Collection<PrototypeFrame> getPrototypes();
292:
293: /**
294: * Returns the generated class for the given prototype
295: */
296: public Class classForPrototype(String prototypeName);
297:
298: /**
299: * Return the generated Java class for the given prototype
300: */
301: public Class classForPrototype(PrototypeFrame prototype);
302:
303: /**
304: * Writes the frameset data as xml.
305: *
306: * For each DataFrame in the frameset, writes the current value of
307: * any slot in that frame that is either defined locally or inherited via
308: * the prototype hierarchy.
309: *
310: * @param file The name of xml file to which the data will be written.
311: */
312: public void exportFrames(File file) throws IOException;
313:
314: /**
315: * Writes a subset of the frameset data as xml.
316: *
317: * For each DataFrame of the given prototypes, writes the current value of
318: * any slot in that frame that is either defined locally or inherited via
319: * the prototype hierarchy.
320: *
321: * @param file The name of xml file to which the data will be written.
322: *
323: * @param prototypes Names of the prototypes whose frames should be written.
324: * If null, this method is equivalent to {@link #exportFrames}.
325: */
326: public void exportFrames(File file, Set<String> prototypes)
327: throws IOException;
328:
329: /**
330: * Write a subset of the frameset data as xml, optionally including
331: * slot values inherited via containment.
332: *
333: * @param file
334: * The name of the xml file to which the data will be
335: * written.
336: *
337: * @param prototypes
338: * Names of the prototypes whose frames should be
339: * written. If null, this method is like
340: * {@link #exportFrames} except that all slots can be
341: * written.
342: *
343: * @param allSlots
344: * If false, only writes current value of all slots that
345: * are either defined locally or inherited via the
346: * prototype hierarchy. If true, also includes current
347: * value of slots inherited via containment.
348: */
349: public void exportFrames(File file, Set<String> prototypes,
350: boolean allSlots) throws IOException;
351:
352: /**
353: * Loads DataFrames at the given location.
354: *
355: * @param location A file or resource path
356: */
357: public void importFrames(URL location) throws IOException;
358:
359: /**
360: * Subscribes a DataFrame to a value in the MetricsService
361: */
362: public void subscribeToMetric(DataFrame frame, Observer observer,
363: String path);
364:
365: /**
366: *
367: * Queries the metric service for a value relative to a frame
368: */
369: public Metric getMetricValue(DataFrame frame, String path);
370:
371: // Slot dependencies
372:
373: /**
374: * Creates an aggregator to compute and update the given slot. Ordinarily this happens
375: * automatically as part of loading the prototypes and wouldn't need to be called
376: * explicitly in user code.
377: *
378: * @param slot The slot whose value is computed by a {@link SlotAggregator}.
379: * @param relatedSlot If non-null, and the value of this slot changes in a related entity,
380: * the {@link SlotAggregator} will be reinvoked.
381: * @param relation The name of the RelationPrototype that's used to collect the related
382: * entites.
383: * @param className The name of the {@link SlotAggregator}. If it's qualified with
384: * a package the name is used as is. If not, the class should be in the frameset
385: * package, or in org.cougaar.core.qos.frame.aggregator.
386: */
387: public void addAggregator(String slot, String relatedSlot,
388: String relation, String role, String className);
389:
390: /**
391: * Sets up subscriptions for all aggregators that haven't done so already.
392: * Ordinarily this only needs to be called once after the prototypes are
393: * loaded. This is usually handled by {@link FrameSetLoaderPlugin}.
394: *
395: */
396: public void initializeAggregators();
397:
398: }
|