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.tools.csmart.ui.servlet;
028:
029: import org.cougaar.core.mts.Message;
030: import org.cougaar.core.mts.MessageAddress;
031: import org.cougaar.core.util.UID;
032: import org.cougaar.core.util.UniqueObject;
033: import org.cougaar.planning.ldm.asset.Asset;
034: import org.cougaar.planning.ldm.asset.AssetGroup;
035: import org.cougaar.planning.ldm.asset.TypeIdentificationPG;
036: import org.cougaar.planning.ldm.asset.ClusterPG;
037: import org.cougaar.planning.ldm.measure.AbstractMeasure;
038: import org.cougaar.planning.ldm.plan.*;
039: import org.cougaar.tools.csmart.ui.monitor.PropertyNames;
040: import org.cougaar.util.PropertyTree;
041:
042: import java.beans.PropertyDescriptor;
043: import java.beans.SimpleBeanInfo;
044: import java.lang.reflect.Method;
045: import java.text.SimpleDateFormat;
046: import java.util.ArrayList;
047: import java.util.Date;
048: import java.util.Enumeration;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.Vector;
052:
053: /**
054: * Translate <code>UniqueObject</code>s to <code>PropertyTree</code>s.
055: */
056: public final class TranslateUtils {
057:
058: private TranslateUtils() {
059: // just static utilities!
060: }
061:
062: /**
063: * Translate all the <code>Object</code>s in the given <code>List</code>
064: * into <code>PropertyTree</code>s.
065: * <p>
066: * Simply uses <tt>toPropertyTree(Object)</tt>.
067: *
068: * @param objects a List of Objects
069: * @param agent the name of the Agent (MessageAddress) for these Objects; i.e. the name of the agent in which this code is executing
070: *
071: * @return a List of non-null PropertyTrees; list may be empty, but is not null
072: */
073: public static List toPropertyTrees(List objects, String agent) {
074: int n = ((objects != null) ? objects.size() : 0);
075: if (n <= 0) {
076: return new ArrayList(0);
077: }
078: List results = new ArrayList(n);
079: for (int i = 0; i < n; i++) {
080: PropertyTree pt = toPropertyTree(objects.get(i), agent);
081: if (pt != null) {
082: results.add(pt);
083: }
084: }
085: return results;
086: }
087:
088: /**
089: * Translate the given <code>Object</code>s into an equivalent
090: * <code>PropertyTree</code>. The Object must be an instance of
091: * org.cougaar.core.util.UniqueObject or this will return null.
092: *
093: * @param o an Object to convert into a PropertyTree
094: * @param agent the name of the Agent (MessageAddress) for this Object
095: *
096: * @return a PropertyTree, or null if an error occurred
097: */
098: public static PropertyTree toPropertyTree(Object o, String agent) {
099: return (o instanceof UniqueObject) ? toPropertyTree(
100: (UniqueObject) o, agent) : null;
101: }
102:
103: /**
104: * Return property trees for Tasks, PlanElements, Assets and Workflows.
105: * If object is not one of these, then returns null.
106: */
107: public static PropertyTree toPropertyTree(UniqueObject uo,
108: String agent) {
109: return (uo instanceof Task) ? toPropertyTree((Task) uo, agent)
110: : (uo instanceof PlanElement) ? toPropertyTree(
111: (PlanElement) uo, agent)
112: : (uo instanceof Asset) ? toPropertyTree(
113: (Asset) uo, agent)
114: : (uo instanceof Workflow) ? toPropertyTree(
115: (Workflow) uo, agent)
116: : null;
117: }
118:
119: /**
120: * Return a PropertyTree for a task.
121: * @param task the task for which to return a property tree
122: * @param agent the name of the agent
123: * @return a non-null PropertyTree
124: */
125: public static PropertyTree toPropertyTree(Task task, String agent) {
126: PropertyTree pt = toBasicPropertyTree(
127: PropertyNames.TASK_OBJECT,
128: getUIDAsString(task.getUID()), agent);
129: pt.put(PropertyNames.TASK_VERB, task.getVerb().toString());
130: Asset a = task.getDirectObject();
131: if (a != null) {
132: pt.put(PropertyNames.TASK_DIRECT_OBJECT_UID,
133: getUIDAsString(a.getUID()));
134: }
135: // prepositional phrases
136: Enumeration phrases = task.getPrepositionalPhrases();
137: while (phrases.hasMoreElements()) {
138: PrepositionalPhrase phrase = (PrepositionalPhrase) phrases
139: .nextElement();
140: pt.put(PropertyNames.TASK_PREP_PHRASE + "_"
141: + phrase.getPreposition(),
142: getPrepositionalObjectDescription(phrase
143: .getIndirectObject()));
144: }
145: // indicate if it's a multi-parent task, and return the parents
146: if (task instanceof MPTask) {
147: pt.put(PropertyNames.TASK_TYPE, PropertyNames.MPTASK);
148: Enumeration parents = ((MPTask) task).getParentTasks();
149: ArrayList parentUIDs = new ArrayList();
150: while (parents.hasMoreElements()) {
151: Task parent = (Task) parents.nextElement();
152: parentUIDs.add(getUIDAsString(parent.getUID()));
153: }
154: pt.put(PropertyNames.TASK_PARENT_UID, parentUIDs);
155: } else {
156: pt.put(PropertyNames.TASK_TYPE, PropertyNames.SINGLE_TASK);
157: pt.put(PropertyNames.TASK_PARENT_UID, getUIDAsString(task
158: .getParentTaskUID()));
159: pt.put(PropertyNames.TASK_SOURCE, trimAngles(task
160: .getSource().toString()));
161: }
162: double endTime = task.getPreferredValue(AspectType.END_TIME);
163: if (!(endTime == -1))
164: pt.put(PropertyNames.TASK_END_TIME, new Double(endTime));
165: if (task.getPlanElement() != null) {
166: pt.put(PropertyNames.TASK_PLAN_ELEMENT_UID,
167: getUIDAsString(task.getPlanElement().getUID()));
168: }
169: return pt;
170: }
171:
172: public static PropertyTree toPropertyTree(Workflow wf, String agent) {
173: PropertyTree pt = toBasicPropertyTree(
174: PropertyNames.WORKFLOW_OBJECT, getUIDAsString(wf
175: .getUID()), agent);
176: pt.put(PropertyNames.WORKFLOW_PARENT_TASK_UID,
177: getUIDAsString(wf.getParentTask().getUID()));
178: Enumeration tasks = wf.getTasks();
179: StringBuffer sb = new StringBuffer(100);
180: while (tasks.hasMoreElements()) {
181: Task task = (Task) tasks.nextElement();
182: sb.append(getUIDAsString(task.getUID()));
183: sb.append(",");
184: }
185: int n = sb.length();
186: if (n > 0) {
187: pt.put(PropertyNames.WORKFLOW_TASK_UIDS, sb.substring(0,
188: n - 1));
189: }
190: return pt;
191: }
192:
193: public static PropertyTree toPropertyTree(PlanElement pe,
194: String agent) {
195: return (pe instanceof Expansion) ? toPropertyTree(
196: (Expansion) pe, agent)
197: : (pe instanceof Allocation) ? toPropertyTree(
198: (Allocation) pe, agent)
199: : (pe instanceof Aggregation) ? toPropertyTree(
200: (Aggregation) pe, agent)
201: : (pe instanceof Disposition) ? toPropertyTree(
202: (Disposition) pe, agent)
203: : (pe instanceof AssetTransfer) ? toPropertyTree(
204: (AssetTransfer) pe,
205: agent)
206: : toPlanElementPropertyTree(
207: pe,
208: agent,
209: PropertyNames.PLAN_ELEMENT_UNKNOWN);
210: }
211:
212: public static PropertyTree toPropertyTree(Expansion exp,
213: String agent) {
214: PropertyTree pt = toPlanElementPropertyTree(exp, agent,
215: PropertyNames.PLAN_ELEMENT_EXPANSION);
216: pt.put(PropertyNames.EXPANSION_WORKFLOW_UID, getUIDAsString(exp
217: .getWorkflow().getUID()));
218: return pt;
219: }
220:
221: public static PropertyTree toPropertyTree(Allocation alloc,
222: String agent) {
223: PropertyTree pt = toPlanElementPropertyTree(alloc, agent,
224: PropertyNames.PLAN_ELEMENT_ALLOCATION);
225: // ALLOCATION TO REMOTE or LOCAL ORGANIZATION ASSET
226: Asset asset = alloc.getAsset();
227: if (asset.hasClusterPG()) {
228: if (alloc instanceof AllocationforCollections) {
229: AllocationforCollections ac = (AllocationforCollections) alloc;
230: UID uid = ac.getAllocationTaskUID();
231: if (uid != null) {
232: ClusterPG cpg = asset.getClusterPG();
233: MessageAddress destination = cpg
234: .getMessageAddress();
235: pt.put(PropertyNames.ALLOCATION_TO_AGENT,
236: trimAngles(destination.toString()));
237: pt.put(PropertyNames.ALLOCATION_TASK_UID, uid
238: .toString());
239: }
240: // Need to add pointer to Asset representing remote
241: pt.put(PropertyNames.ALLOCATION_ASSET_UID,
242: getUIDAsString(asset.getUID()));
243: } else {
244: Task task = alloc.getTask();
245: pt.put(PropertyNames.ALLOCATION_REMOTE_AGENT_UID,
246: trimAngles(task.getDestination().toString()));
247: pt.put(PropertyNames.ALLOCATION_LOCAL_ORG_UID,
248: getUIDAsString(asset.getUID()));
249: }
250: } else {
251: pt.put(PropertyNames.ALLOCATION_ASSET_UID,
252: getUIDAsString(asset.getUID()));
253: }
254: return pt;
255: }
256:
257: // Some things, like AgentID.toString(), have these ugly angle brackets
258: public static String trimAngles(String input) {
259: if (input == null)
260: return input;
261: if (input.startsWith("<"))
262: input = input.substring(1);
263: if (input.endsWith(">"))
264: input = input.substring(0, input.length() - 1);
265: return input;
266: }
267:
268: public static PropertyTree toPropertyTree(Aggregation agg,
269: String agent) {
270: PropertyTree pt = toPlanElementPropertyTree(agg, agent,
271: PropertyNames.PLAN_ELEMENT_AGGREGATION);
272: Composition comp = agg.getComposition();
273: MPTask mp = comp.getCombinedTask();
274: if (mp.getUID() != null)
275: pt.put(PropertyNames.AGGREGATION_MPTASK_UID,
276: getUIDAsString(mp.getUID()));
277:
278: List parents = comp.getParentTasks();
279: StringBuffer sb = new StringBuffer(100);
280: for (Iterator i = parents.iterator(); i.hasNext();) {
281: Object o = i.next();
282: if (o instanceof Task) {
283: sb.append(getUIDAsString(((Task) o).getUID()));
284: sb.append(",");
285: }
286: }
287: int n = sb.length();
288: if (n > 0) {
289: pt.put(PropertyNames.AGGREGATION_PARENT_UIDS, sb.substring(
290: 0, n - 1));
291: }
292:
293: return pt;
294: }
295:
296: public static PropertyTree toPropertyTree(Disposition disp,
297: String agent) {
298: PropertyTree pt = toPlanElementPropertyTree(disp, agent,
299: PropertyNames.PLAN_ELEMENT_DISPOSITION);
300: pt.put(PropertyNames.DISPOSITION_SUCCESS,
301: (disp.isSuccess() ? "true" : "false"));
302: return pt;
303: }
304:
305: public static PropertyTree toPropertyTree(AssetTransfer atr,
306: String agent) {
307: PropertyTree pt = toPlanElementPropertyTree(atr, agent,
308: PropertyNames.PLAN_ELEMENT_ASSET_TRANSFER);
309: // get asset UID
310: pt.put(PropertyNames.ASSET_TRANSFER_ASSET_UID,
311: getUIDAsString(atr.getAsset().getUID()));
312:
313: // get assignee, which is an asset
314: pt.put(PropertyNames.ASSET_TRANSFER_ASSIGNEE_UID,
315: getUIDAsString(atr.getAssignee().getUID()));
316:
317: // get assignor, which is a agent id
318: pt.put(PropertyNames.ASSET_TRANSFER_ASSIGNOR, trimAngles(atr
319: .getAssignor().toString()));
320:
321: return pt;
322: }
323:
324: private static PropertyTree toPlanElementPropertyTree(
325: PlanElement pe, String agent, String peType) {
326: PropertyTree pt = toBasicPropertyTree(
327: PropertyNames.PLAN_ELEMENT_OBJECT, getUIDAsString(pe
328: .getUID()), agent);
329: pt.put(PropertyNames.PLAN_ELEMENT_TYPE, peType);
330: pt.put(PropertyNames.PLAN_ELEMENT_TASK_UID, getUIDAsString(pe
331: .getTask().getUID()));
332: AllocationResult estimated = pe.getEstimatedResult();
333: if (estimated != null) {
334: pt.put(PropertyNames.PLAN_ELEMENT_ESTIMATED_RESULT,
335: estimated.toString());
336: addAllocationEndTime(pt,
337: PropertyNames.ESTIMATED_ALLOCATION_RESULT_END_TIME,
338: estimated);
339: addAllocationReason(
340: pt,
341: PropertyNames.ESTIMATED_ALLOCATION_RESULT_FAILURE_REASON,
342: estimated);
343: }
344: AllocationResult reported = pe.getReportedResult();
345: if (reported != null) {
346: pt.put(PropertyNames.PLAN_ELEMENT_REPORTED_RESULT, reported
347: .toString());
348: addAllocationEndTime(pt,
349: PropertyNames.REPORTED_ALLOCATION_RESULT_END_TIME,
350: reported);
351: addAllocationReason(
352: pt,
353: PropertyNames.REPORTED_ALLOCATION_RESULT_FAILURE_REASON,
354: reported);
355: }
356: AllocationResult observed = pe.getObservedResult();
357: if (observed != null) {
358: pt.put(PropertyNames.PLAN_ELEMENT_OBSERVED_RESULT, observed
359: .toString());
360: addAllocationEndTime(pt,
361: PropertyNames.OBSERVED_ALLOCATION_RESULT_END_TIME,
362: observed);
363: addAllocationReason(
364: pt,
365: PropertyNames.OBSERVED_ALLOCATION_RESULT_FAILURE_REASON,
366: observed);
367:
368: }
369: return pt;
370: }
371:
372: /**
373: * Create property tree with properties that all objects have.
374: */
375: private static PropertyTree toBasicPropertyTree(String objectType,
376: String UID, String agent) {
377: PropertyTree pt = new PropertyTree();
378: pt.put(PropertyNames.OBJECT_TYPE, objectType);
379: pt.put(PropertyNames.UID_ATTR, UID);
380: pt.put(PropertyNames.AGENT_ATTR, agent);
381: return pt;
382: }
383:
384: private static void addAllocationEndTime(PropertyTree properties,
385: String propertyName, AllocationResult result) {
386: if (result.isDefined(AspectType.END_TIME)) {
387: properties.put(propertyName, Double.toString(result
388: .getValue(AspectType.END_TIME)));
389: }
390: }
391:
392: private static void addAllocationReason(PropertyTree properties,
393: String propertyName, AllocationResult result) {
394: if (!result.isSuccess()) {
395: try {
396: String s = result
397: .auxiliaryQuery(AuxiliaryQueryType.FAILURE_REASON);
398: properties.put(propertyName, s);
399: } catch (IllegalArgumentException e) {
400: System.out
401: .println("TranslateUtils: can't get AllocationQueryType FAILURE_REASON: "
402: + e);
403: }
404: }
405: }
406:
407: /**
408: * This always returns the property tree for an asset.
409: * In most cases, non-local agent assets should be ignored;
410: * this is the responsibility of the caller.
411: * The agent in the property tree returned is always the agent in which
412: * this code is executing.
413: * Assets with clusterPG also return an ASSET_AGENT
414: * which is the agent ID in asset.getClusterPG().getMessageAddress
415: */
416:
417: public static PropertyTree toPropertyTree(Asset asset, String agent) {
418: PropertyTree pt = toBasicPropertyTree(
419: PropertyNames.ASSET_OBJECT, getUIDAsString(asset
420: .getUID()), agent);
421: pt.put(PropertyNames.ASSET_KEY, trimAngles(asset.getKey()
422: .toString()));
423: if (asset.hasClusterPG())
424: pt.put(PropertyNames.ASSET_AGENT, trimAngles(asset
425: .getClusterPG().getMessageAddress().toString()));
426:
427: String className = asset.getClass().getName();
428: int index = className.lastIndexOf('.');
429: if (index >= 0) {
430: className = className.substring(index + 1);
431: }
432: if (asset instanceof AssetGroup) {
433: pt.put(PropertyNames.ASSET_GROUP_NAME, className);
434: Vector assets = ((AssetGroup) asset).getAssets();
435: ArrayList groupUIDs = new ArrayList(assets.size());
436: for (int i = 0; i < assets.size(); i++) {
437: Asset a = (Asset) assets.elementAt(i);
438: groupUIDs.add(getUIDAsString(a.getUID()));
439: }
440: pt.put(PropertyNames.ASSET_GROUP_ASSETS, groupUIDs);
441: } else {
442: pt.put(PropertyNames.ASSET_NAME, className);
443: pt.put(PropertyNames.ASSET_DESC, asset.toString());
444: }
445: // get property groups and values
446: PropertyDescriptor[] pd = asset.getPropertyDescriptors();
447: int n = 0;
448: for (int i = 0; i < pd.length; i++) {
449: Method readMethod = pd[i].getReadMethod();
450: Object assetPropertyObj;
451: // get a propertygroupimpl object which extends SimpleBeanInfo
452: try {
453: assetPropertyObj = readMethod.invoke(asset, null);
454: } catch (Exception ex1) {
455: System.err
456: .println("TranslateUtils: Unable to get asset property group["
457: + i + "]: " + ex1);
458: continue;
459: }
460: if (!(assetPropertyObj instanceof SimpleBeanInfo)) {
461: continue;
462: }
463: SimpleBeanInfo assetProperty = (SimpleBeanInfo) assetPropertyObj;
464: // get the descriptors for the attributes in the property group
465: PropertyDescriptor[] attributePDs = assetProperty
466: .getPropertyDescriptors();
467: for (int j = 0; j < attributePDs.length; j++) {
468: readMethod = attributePDs[j].getReadMethod();
469: Object result = null;
470: try {
471: result = readMethod.invoke(assetProperty, null);
472: } catch (Exception ex2) {
473: System.err
474: .println("TranslateUtils: Unable to get asset property["
475: + i + "][" + j + "]: " + ex2);
476: continue;
477: }
478: if (result != null) {
479: // adds name of the form ASSET_PROPERTY_n_name_name
480: pt.put(PropertyNames.ASSET_PROPERTY + "_" + (n++)
481: + "_" + pd[i].getName() + "_"
482: + attributePDs[j].getName(), result
483: .toString());
484: }
485: }
486: }
487: return pt;
488: }
489:
490: private static final String getUIDAsString(final UID uid) {
491: return ((uid != null) ? uid.toString() : "null");
492: }
493:
494: /**
495: * Get description of object that is an indirect object
496: * of a prepositional phrase.
497: * The indirect object of a prepositional
498: * phrase is defined as an object, so there's no way to know
499: * what object types are legal. The documentation claims one of:
500: * Asset, Location, Schedule, Requisition, Vector, or OPLAN
501: */
502: private static String getPrepositionalObjectDescription(
503: Object indirectObject) {
504: if (indirectObject == null) {
505: return "null";
506: }
507: // STRING
508: if (indirectObject instanceof String) {
509: return (String) indirectObject;
510: }
511: // LOCATION
512: if (indirectObject instanceof Location) {
513: return indirectObject.toString();
514: }
515: // ASSET
516: if (indirectObject instanceof Asset) {
517: Asset asset = (Asset) indirectObject;
518: TypeIdentificationPG typeIdPG = asset
519: .getTypeIdentificationPG();
520: StringBuffer sb = new StringBuffer(100);
521: if (typeIdPG != null) {
522: String nomenclature = typeIdPG.getNomenclature();
523: if (nomenclature != null)
524: sb.append(nomenclature);
525: }
526: sb.append(" (asset type=" + asset.getClass().getName()
527: + ", asset uid=" + getUIDAsString(asset.getUID())
528: + ")");
529: return sb.toString();
530: }
531: // SCHEDULE
532: if (indirectObject instanceof Schedule) {
533: return getScheduleDescription((Schedule) indirectObject);
534: }
535: // MESSAGEADDRESS (aka AgentIdentifier)
536: if (indirectObject instanceof MessageAddress) {
537: return trimAngles(indirectObject.toString());
538: }
539: // ASSETTRANSFER
540: if (indirectObject instanceof AssetTransfer) {
541: return ((AssetTransfer) indirectObject).getAsset()
542: .getName();
543: }
544: // ASSETASSIGNMENT
545: if (indirectObject instanceof AssetAssignment) {
546: return ((AssetAssignment) indirectObject).getAsset()
547: .getName();
548: }
549: // ASSETGROUP
550: if (indirectObject instanceof AssetGroup) {
551: List assets = ((AssetGroup) indirectObject).getAssets();
552: for (int i = 0; i < assets.size(); i++) {
553: Asset asset = (Asset) assets.get(i);
554: // recursive
555: getPrepositionalObjectDescription(asset);
556: }
557: }
558: // ABSTRACTMEASURE
559: if (indirectObject instanceof AbstractMeasure) {
560: AbstractMeasure measure = (AbstractMeasure) indirectObject;
561: String s = measure.getClass().getName();
562: int index = s.lastIndexOf('.');
563: return s.substring(0, index - 1) + ": "
564: + indirectObject.toString();
565: }
566: // DEFAULT
567: return indirectObject.getClass().getName() + ": "
568: + indirectObject.toString();
569: }
570:
571: /**
572: * TODO: Probably necessary to break this down into individual properties.
573: */
574: private static String getScheduleDescription(Schedule schedule) {
575: StringBuffer sb = new StringBuffer(100);
576: sb.append("Schedule: Type: " + schedule.getScheduleType());
577: sb.append(" Start Time = ");
578: sb.append(getTimeString(schedule.getStartTime()));
579: sb.append(" End Time = ");
580: sb.append(getTimeString(schedule.getEndTime()));
581: if (schedule.isEmpty()) {
582: return sb.toString();
583: }
584:
585: // schedule elements
586: sb.append(" Elements:");
587: Enumeration elements = schedule.getAllScheduleElements();
588: while (elements.hasMoreElements()) {
589: ScheduleElement scheduleElement = (ScheduleElement) elements
590: .nextElement();
591: sb.append(" Start Time = ");
592: sb.append(getTimeString(scheduleElement.getStartTime()));
593: sb.append(" End Time = ");
594: sb.append(getTimeString(scheduleElement.getEndTime()));
595: if (scheduleElement instanceof LocationRangeScheduleElement) {
596: LocationRangeScheduleElement locSE = (LocationRangeScheduleElement) scheduleElement;
597: sb.append(" Start Location = ");
598: sb.append(locSE.getStartLocation());
599: sb.append(" End Location = ");
600: sb.append(locSE.getEndLocation());
601: if (locSE instanceof ItineraryElement) {
602: sb.append(" Verb = ");
603: sb.append(((ItineraryElement) locSE).getRole());
604: }
605: } else if (scheduleElement instanceof LocationScheduleElement) {
606: sb.append(" Location = ");
607: sb.append(((LocationScheduleElement) scheduleElement)
608: .getLocation());
609: }
610: }
611: return sb.toString();
612: }
613:
614: private static SimpleDateFormat myDateFormat = new SimpleDateFormat(
615: "MM_dd_yyyy_h:mma");
616:
617: /**
618: * Format long time as String.
619: */
620: private static String getTimeString(long time) {
621: synchronized (myDateFormat) {
622: return myDateFormat.format(new Date(time));
623: }
624: }
625:
626: }
|