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.lib.util;
028:
029: import java.util.Collection;
030: import java.util.Date;
031: import java.util.Iterator;
032: import java.util.Vector;
033:
034: import org.cougaar.planning.ldm.LDMServesPlugin;
035: import org.cougaar.planning.ldm.PlanningFactory;
036: import org.cougaar.planning.ldm.asset.AggregateAsset;
037: import org.cougaar.planning.ldm.asset.Asset;
038: import org.cougaar.planning.ldm.asset.AssetGroup;
039: import org.cougaar.planning.ldm.asset.ItemIdentificationPG;
040: import org.cougaar.planning.ldm.asset.NewItemIdentificationPG;
041: import org.cougaar.planning.ldm.asset.NewTypeIdentificationPG;
042: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
043: import org.cougaar.planning.ldm.plan.Allocation;
044: import org.cougaar.planning.ldm.plan.PlanElement;
045: import org.cougaar.planning.ldm.plan.RoleSchedule;
046: import org.cougaar.planning.ldm.plan.Task;
047: import org.cougaar.util.log.Logger;
048:
049: /**
050: * This class contains utility functions for getting
051: * Assets.
052: */
053:
054: public class UTILAsset {
055: private static String myName = "UTILAsset";
056:
057: public UTILAsset(Logger log) {
058: logger = log;
059: prefHelper = new UTILPreference(log);
060: }
061:
062: /**
063: * Creates an instance of an LDM object from a prototype.
064: * An LDM Prototype is like the "idea" of an object.
065: *
066: * @param ldm - ldm prototype manager
067: * @param prototypeName - name of the prototype, e.g. "DC-10"
068: * @param bumperno - the unique identifier assigned to the returned instance.
069: * @return an LDM asset, null if no prototype prototypeName is known
070: */
071: public Asset createInstance(LDMServesPlugin ldm,
072: String prototypeName, String bumperno) {
073: Asset instance = ldm.getFactory().createInstance(prototypeName,
074: bumperno);
075: return instance;
076: }
077:
078: /**
079: * Create empty asset group
080: */
081: public final AssetGroup makeAssetGroup(PlanningFactory root,
082: String id) {
083: AssetGroup ag = makeAssetGroup(root, new Vector());
084: ((NewItemIdentificationPG) ag.getItemIdentificationPG())
085: .setItemIdentification(id);
086: return ag;
087: }
088:
089: /**
090: * Given a vector of objects, it creates an asset group
091: * containing those objects.
092: *
093: * @param root can be gotten from the getLDM() method inherited from PluginAdapter.
094: * @param v a Vector of assets to be grouped
095: * @return AssetGroup
096: */
097: public final AssetGroup makeAssetGroup(PlanningFactory root,
098: Vector v) {
099: AssetGroup ag = null;
100: try {
101: NewTypeIdentificationPG p1 = null;
102:
103: ag = (AssetGroup) root
104: .createAsset(Class
105: .forName("org.cougaar.planning.ldm.asset.AssetGroup"));
106:
107: p1 = (NewTypeIdentificationPG) ag.getTypeIdentificationPG();
108: p1.setTypeIdentification("ASSET_GROUP");
109: p1.setNomenclature("AssetGroup");
110: } catch (Exception e) {
111: throw new UTILRuntimeException(e.getMessage());
112: }
113: ag.setAssets(v);
114: return (ag);
115: }
116:
117: /**
118: * utility methods for accessing TypeIdentification of an asset
119: * @param item an asset
120: * @return String representing the TypeIdentification of the asset
121: */
122:
123: public String getTypeName(Asset item) {
124: TypeIdentificationPG tip = item.getTypeIdentificationPG();
125:
126: String typeName;
127: if (tip != null)
128: try {
129: typeName = tip.getNomenclature();
130: } catch (Exception e) {
131: typeName = item.getClass().getName();
132: }
133: else
134: typeName = item.getClass().getName();
135:
136: return typeName;
137: }
138:
139: /**
140: * utility methods for accessing ItemIdentification of an asset
141: * @param item an asset
142: * @return String representing the ItemIdentification of the asset
143: */
144:
145: public String getItemName(Asset item) {
146: ItemIdentificationPG iip = item.getItemIdentificationPG();
147:
148: String itemID;
149: if (iip != null)
150: try {
151: // itemID = iip.getNomenclature ();
152: itemID = iip.getItemIdentification();
153: } catch (Exception e) {
154: itemID = "<unknown>";
155: }
156: else
157: itemID = "<unknown>";
158:
159: return itemID;
160: }
161:
162: /*
163: protected static int latestUID = 0;
164: protected static int getLatestUID () {
165: if (latestUID == Integer.MAX_VALUE)
166: latestUID = 0;
167: return ++latestUID;
168: }
169: */
170:
171: /**
172: * Utility function to determine if an asset is or contains
173: * an AssetGroup at any level of its hierarchy.
174: * @param asset the asset.
175: * @return true iff the asset is or contains an AssetGroup
176: **/
177: public boolean containsAssetGroup(Asset asset) {
178: if (asset instanceof AssetGroup)
179: return true;
180: else if (asset instanceof AggregateAsset) {
181: AggregateAsset aggregate = (AggregateAsset) asset;
182: Asset subobject = (Asset) aggregate.getAsset();
183: return containsAssetGroup(subobject);
184: }
185: return false;
186: }
187:
188: /**
189: * Break up an asset group into individual assets. This
190: * is a utility wrapper around a private function
191: * to make the input/output nicer to deal with.
192: *
193: * NOTE : Convoys are AssetGroups, so the contents of a convoy
194: * will also appear on the result list.
195: *
196: * @param group AssetGroup to divide
197: * @return Vector of sub-objects
198: */
199: public Vector expandAssetGroup(AssetGroup group) {
200: Vector buffer = new Vector();
201: expandAssetGroup(group, buffer);
202: return buffer;
203: }
204:
205: /**
206: * Private utility function to break up an asset group
207: * recursively. Does not expand Aggregate assets.
208: *
209: * NOTE : Convoys are AssetGroups, so the contents of a convoy
210: * will also appear on the result list.
211: *
212: * @param group - the asset group
213: * @param buffer - the vector to put the assets into
214: * @return void
215: */
216: private void expandAssetGroup(AssetGroup group, Vector buffer) {
217: Vector subobjects = group.getAssets();
218: if (subobjects.isEmpty())
219: logger.warn("WARNING -- asset group is empty!");
220: for (int i = 0; i < subobjects.size(); i++) {
221: Object subobject = subobjects.elementAt(i);
222:
223: if (subobject instanceof AssetGroup)
224: expandAssetGroup((AssetGroup) subobject, buffer);
225: else
226: buffer.addElement(subobject);
227: }
228: }
229:
230: /**
231: * Looks for Allocation (is this correct?) plan element that contains
232: * a task immediately previous (check_backwards is true) or after (false)
233: * the time given in the RoleSchedule.
234: * Do we need to check the role in this allocation as well?
235: * @return null if no task found
236: */
237: public Task findClosestRoleScheduleTask(RoleSchedule rs, Date time,
238: boolean check_backwards) {
239: // !!FIXIT!! What we really want is the entire role schedule as an
240: // OrderedSet by PE start time.
241: // Since we're doing forward planning, 'now' should be earlier than
242: // all plan elements (i.e. start_of_time_window could just new Date())
243: // but let's be safe
244: // Date start_of_time_window = new Date(0); // The beginning of time
245: long start_of_time_window = 0; // The beginning of time
246: // And pick an arbitrary time far in the future
247: // Date end_of_time_window = new Date((long)((new Date()).getTime() * 2));
248: long end_of_time_window = ((new Date()).getTime() * 2);
249: Collection pes = rs.getEncapsulatedRoleSchedule(
250: start_of_time_window, end_of_time_window);
251:
252: PlanElement pe_to_return = null;
253:
254: Iterator pe_i = pes.iterator();
255: // Are there any JGL tricks that would make this more efficient?
256: while (pe_i.hasNext()) {
257: PlanElement next_pe = (PlanElement) pe_i.next();
258: // Is all we care about allocations?
259: if (next_pe instanceof Allocation) {
260: // Process it! Check if it's the PE that we want- we want to make
261: // sure that there's a clear space in the schedule either from
262: // (if check_backwards is true) or to (false) the given time
263: if (prefHelper.getReadyAt(next_pe.getTask()).before(
264: time))
265: pe_to_return = next_pe;
266: // If we're going backwards from the time, get the one immediately previous
267: else if (check_backwards)
268: break;
269: // If we're going forwards, get the one immediately subsequent
270: else if (!check_backwards) {
271: pe_to_return = next_pe;
272: break;
273: }
274: }
275: }
276:
277: if (pe_to_return == null)
278: return null;
279:
280: return pe_to_return.getTask();
281: }
282:
283: protected Logger logger;
284: protected UTILPreference prefHelper;
285: }
|