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: package org.cougaar.core.component;
027:
028: import java.io.Serializable;
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.Collections;
032: import java.util.Comparator;
033: import java.util.Iterator;
034: import java.util.List;
035:
036: /**
037: * A utility class for manipulating sets of ComponentDescription
038: * objects.
039: * <p>
040: * Contains both ComponentDescriptions and StateTuples. StateTuples
041: * are simply ComponentDescription wrappers with an addition
042: * "Object state". These two concepts may be merged in the future...
043: **/
044: public class ComponentDescriptions implements Serializable {
045: /** Storage for the ComponentDescriptions.
046: * @todo A more efficient form for traversal would be good - we're not optimizing it
047: * for now.
048: **/
049: private final List cds;
050:
051: /** Construct a ComponentDescriptions object from an array of ComponentDescription **/
052: public ComponentDescriptions(ComponentDescription[] cda) {
053: int ln = cda.length;
054: List l = new ArrayList(ln);
055: for (int i = 0; i < ln; i++) {
056: l.add(cda[i]);
057: }
058: cds = l;
059: }
060:
061: /** Construct a ComponentDescriptions object from a collection of ComponentDescription **/
062: public ComponentDescriptions(Collection cds) {
063: this .cds = new ArrayList(cds);
064: }
065:
066: /** Sort a List of ComponentDescriptions by priority.
067: * Note that the original list is destructively modified, so an exception
068: * may be generated if the argument is not mutable.
069: * @return the (now sorted) original list object.
070: **/
071: public static List sort(List cds) {
072: Collections.sort(cds, STATE_TUPLE_PRIORITY_Comparator);
073: return cds;
074: }
075:
076: /** Return a list of the components which are direct subcomponents of the specified
077: * containment point. The ContainmentPoint parameter should not end with a '.'.
078: * Always returns a newly created list. The elements are always in priority-sorted order.
079: **/
080: public List extractDirectComponents(String cp) {
081: if (cp.endsWith(".")) {
082: // assert would be better
083: throw new IllegalArgumentException(
084: "ContainmentPoint should not end with '.': \"" + cp
085: + "\"");
086: }
087: String prefix = cp + ".";
088: int prefixl = prefix.length();
089:
090: List l = new ArrayList();
091: for (Iterator it = cds.iterator(); it.hasNext();) {
092: Object o = it.next();
093: ComponentDescription cd = ((o instanceof StateTuple) ? (((StateTuple) o)
094: .getComponentDescription())
095: : ((ComponentDescription) o));
096: String ip = cd.getInsertionPoint();
097: if (ip.startsWith(prefix) && // is prefix a prefix and
098: ip.indexOf(".", prefixl + 1) == -1 // there are no more '.'s?
099: ) {
100: l.add(o);
101: }
102: }
103: sort(l);
104: return l;
105: }
106:
107: /** extract a list of ComponentDescriptions which have a specified insertion point
108: * Always returns a newly created list. The elements are always in priority-sorted order.
109: **/
110: public List extractInsertionPointComponent(String dip) {
111: List l = new ArrayList();
112: for (Iterator it = cds.iterator(); it.hasNext();) {
113: Object o = it.next();
114: ComponentDescription cd = ((o instanceof StateTuple) ? (((StateTuple) o)
115: .getComponentDescription())
116: : ((ComponentDescription) o));
117: String ip = cd.getInsertionPoint();
118: if (dip.equals(ip)) {
119: l.add(o);
120: }
121: }
122: sort(l);
123: return l;
124: }
125:
126: /** return a iterator over of the list of the ComponentDescriptions with a specified priority.
127: **/
128: public List selectComponentDescriptions(int priority) {
129: List l = new ArrayList();
130: for (Iterator it = cds.iterator(); it.hasNext();) {
131: Object o = it.next();
132: ComponentDescription cd = ((o instanceof StateTuple) ? (((StateTuple) o)
133: .getComponentDescription())
134: : ((ComponentDescription) o));
135: if (priority == cd.getPriority()) {
136: l.add(o);
137: }
138: }
139: return l;
140: }
141:
142: public String toString() {
143: List l;
144: StringBuffer buf = new StringBuffer();
145: buf.append("ComponentDescriptions[");
146: buf.append(cds.size());
147: buf.append("] {\n HIGH[");
148: l = selectComponentDescriptions(ComponentDescription.PRIORITY_HIGH);
149: buf.append(l.size()).append("] ").append(l);
150: buf.append("\n INTERNAL[");
151: l = selectComponentDescriptions(ComponentDescription.PRIORITY_INTERNAL);
152: buf.append(l.size()).append("] ").append(l);
153: buf.append("\n BINDER[");
154: l = selectComponentDescriptions(ComponentDescription.PRIORITY_BINDER);
155: buf.append(l.size()).append("] ").append(l);
156: buf.append("\n COMPONENT[");
157: l = selectComponentDescriptions(ComponentDescription.PRIORITY_COMPONENT);
158: buf.append(l.size()).append("] ").append(l);
159: buf.append("\n LOW[");
160: l = selectComponentDescriptions(ComponentDescription.PRIORITY_LOW);
161: buf.append(l.size()).append("] ").append(l);
162: buf.append("\n}");
163: return buf.toString();
164: }
165:
166: /**
167: * A comparator which may be used for sorting a mixed set of
168: * StateTuples and ComponentDescriptions by priority
169: */
170: public final static Comparator STATE_TUPLE_PRIORITY_Comparator = new Comparator() {
171: public final int compare(Object a, Object b) {
172: ComponentDescription acd = ((a instanceof StateTuple) ? (((StateTuple) a)
173: .getComponentDescription())
174: : ((ComponentDescription) a));
175: ComponentDescription bcd = ((b instanceof StateTuple) ? (((StateTuple) b)
176: .getComponentDescription())
177: : ((ComponentDescription) b));
178: return acd.getPriority() - bcd.getPriority();
179: }
180: };
181: }
|