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.planning.ldm.asset;
027:
028: import java.beans.BeanDescriptor;
029: import java.beans.BeanInfo;
030: import java.beans.EventSetDescriptor;
031: import java.beans.MethodDescriptor;
032: import java.beans.PropertyDescriptor;
033: import java.util.ArrayList;
034: import java.util.Collection;
035: import java.util.Comparator;
036: import java.util.Iterator;
037:
038: import org.cougaar.util.NewTimeSpan;
039: import org.cougaar.util.NonOverlappingTimeSpanSet;
040: import org.cougaar.util.TimeSpan;
041:
042: public class PropertyGroupSchedule extends NonOverlappingTimeSpanSet
043: implements BeanInfo, Cloneable {
044:
045: private Class myPropertyGroupClass = null;
046: private TimePhasedPropertyGroup myDefault = null;
047:
048: private NonOverlappingTimeSpanSet myTiling = null;
049:
050: // constructors
051: public PropertyGroupSchedule() {
052: super ();
053: }
054:
055: // constructors
056: public PropertyGroupSchedule(TimePhasedPropertyGroup defaultPG) {
057: super ();
058:
059: setDefault(defaultPG);
060: }
061:
062: public PropertyGroupSchedule(PropertyGroupSchedule schedule) {
063: super (schedule);
064:
065: Class pgClass = schedule.getPGClass();
066: if (pgClass != null) {
067: initializePGClass(pgClass);
068: } else {
069: RuntimeException rt = new RuntimeException(
070: "No pgClass for : " + schedule);
071: throw rt;
072: }
073:
074: TimePhasedPropertyGroup defaultPG = schedule.getDefault();
075: if (defaultPG != null) {
076: setDefault(defaultPG);
077: }
078: }
079:
080: public PropertyGroupSchedule(Collection c) {
081: super (c.size());
082:
083: // insert them carefully.
084: for (Iterator i = c.iterator(); i.hasNext();) {
085: add(i.next());
086: }
087: }
088:
089: public void initializePGClass(Class tppgClass) {
090: if (myPropertyGroupClass != null) {
091: // Can only initialize class once
092: throw new IllegalArgumentException();
093: } else if (!TimePhasedPropertyGroup.class
094: .isAssignableFrom(tppgClass)) {
095: //Must be an extension of PropertyGroup
096: throw new ClassCastException();
097: }
098:
099: myPropertyGroupClass = tppgClass;
100: }
101:
102: public void initializePGClass(PropertyGroup propertyGroup) {
103: initializePGClass(propertyGroup.getPrimaryClass());
104: }
105:
106: public Class getPGClass() {
107: return myPropertyGroupClass;
108: }
109:
110: public void setDefault(TimePhasedPropertyGroup defaultPG) {
111: if (!validClass(defaultPG.getPrimaryClass())) {
112: System.err.println("PGClass: " + getPGClass()
113: + " default arg " + defaultPG.getPrimaryClass());
114: throw new ClassCastException();
115: }
116:
117: myDefault = defaultPG;
118:
119: myTiling = null;
120: }
121:
122: public TimePhasedPropertyGroup getDefault() {
123: return myDefault;
124: }
125:
126: public void clearDefault() {
127: myDefault = null;
128:
129: myTiling = null;
130: }
131:
132: public boolean add(Object o) {
133: if (!validClass(((PropertyGroup) o).getPrimaryClass())) {
134: throw new ClassCastException();
135: }
136:
137: myTiling = null;
138:
139: TimeSpan timeSpan = (TimeSpan) o;
140: if ((timeSpan.getStartTime() == TimeSpan.MIN_VALUE)
141: && (timeSpan.getEndTime() == TimeSpan.MAX_VALUE)) {
142: setDefault((TimePhasedPropertyGroup) o);
143:
144: return true;
145: } else {
146: return super .add(o);
147: }
148: }
149:
150: public boolean remove(Object o) {
151: if (!validClass(((PropertyGroup) o).getPrimaryClass())) {
152: throw new ClassCastException();
153: }
154:
155: myTiling = null;
156:
157: if (o.equals(getDefault())) {
158: clearDefault();
159: return true;
160: } else {
161: return super .remove(o);
162: }
163:
164: }
165:
166: public NonOverlappingTimeSpanSet getTiling(long startTime,
167: long endTime) {
168: if (myDefault == null) {
169: return new NonOverlappingTimeSpanSet(intersectingSet(
170: startTime, endTime));
171: }
172:
173: if (myTiling == null) {
174: myTiling = fill((NewTimeSpan) myDefault.copy());
175: }
176:
177: return new NonOverlappingTimeSpanSet(myTiling.intersectingSet(
178: startTime, endTime));
179: }
180:
181: public NonOverlappingTimeSpanSet getTiling(TimeSpan timeSpan) {
182: return getTiling(timeSpan.getStartTime(), timeSpan.getEndTime());
183: }
184:
185: public NonOverlappingTimeSpanSet getTiling() {
186: return getTiling(TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
187: }
188:
189: public Object[] getTilingAsArray() {
190: return getTiling(TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE)
191: .toArray();
192: }
193:
194: public Object clone() {
195: /*
196: RuntimeException e = new RuntimeException();
197: e.printStackTrace();
198: */
199: // Shallow clone
200: PropertyGroupSchedule schedule = new PropertyGroupSchedule(this );
201: schedule.lockPGs();
202:
203: return schedule;
204: }
205:
206: private transient PropertyGroupSchedule _locked = null;
207:
208: public PropertyGroupSchedule lock(Object key) {
209: if (_locked == null) {
210: _locked = new _Locked(key, this );
211: }
212: return _locked;
213: }
214:
215: public PropertyGroupSchedule lock() {
216: return lock(null);
217: }
218:
219: public PropertyGroupSchedule unlock(Object key) {
220: return this ;
221: }
222:
223: public void lockPGs(Object key) {
224: if (getDefault() != null) {
225: setDefault((TimePhasedPropertyGroup) getDefault().lock(key));
226: }
227:
228: Collection set = intersectingSet(TimeSpan.MIN_VALUE,
229: TimeSpan.MAX_VALUE);
230: clear();
231: for (Iterator i = set.iterator(); i.hasNext();) {
232: add(((PropertyGroup) i.next()).lock(key));
233: }
234: }
235:
236: public void lockPGs() {
237: lockPGs(null);
238: }
239:
240: public void unlockPGs(Object key) throws IllegalAccessException {
241: if (getDefault() != null) {
242: setDefault((TimePhasedPropertyGroup) getDefault().unlock(
243: key));
244: }
245:
246: Collection set = intersectingSet(TimeSpan.MIN_VALUE,
247: TimeSpan.MAX_VALUE);
248: clear();
249: for (Iterator i = set.iterator(); i.hasNext();) {
250: add(((PropertyGroup) i.next()).unlock(key));
251: }
252: }
253:
254: protected boolean validClass(Class tppgClass) {
255: if (myPropertyGroupClass == null) {
256: try {
257: initializePGClass(tppgClass);
258: } catch (ClassCastException e) {
259: return false;
260: }
261: }
262:
263: return tppgClass.equals(myPropertyGroupClass);
264: }
265:
266: public static void main(String arg[]) {
267:
268: PropertyGroupSchedule schedule = new PropertyGroupSchedule();
269:
270: CommunityPGImpl defaultPG = new CommunityPGImpl();
271: ArrayList defaultCommunities = new ArrayList();
272: defaultCommunities.add("default");
273: defaultPG.setTimeSpan(TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
274: defaultPG.setCommunities(defaultCommunities);
275:
276: CommunityPGImpl item1 = new CommunityPGImpl();
277: ArrayList firstCommunities = new ArrayList();
278: firstCommunities.add("Item1");
279: item1.setTimeSpan(-5, 20);
280: item1.setCommunities(firstCommunities);
281:
282: CommunityPGImpl item2 = new CommunityPGImpl();
283: ArrayList secondCommunities = new ArrayList();
284: secondCommunities.add("Item2");
285: item2.setTimeSpan(30, 90);
286: item2.setCommunities(secondCommunities);
287:
288: schedule.setDefault(defaultPG);
289: schedule.add(item1);
290: schedule.add(item2);
291:
292: System.out.println("Initial");
293: Iterator iterator = schedule.iterator();
294: while (iterator.hasNext()) {
295: CommunityPG pg = (CommunityPG) iterator.next();
296: System.out.println("\t" + pg.getCommunities() + " "
297: + pg.getStartTime() + " " + pg.getEndTime());
298: }
299:
300: System.out.println("Filled");
301: iterator = schedule.getTiling(TimeSpan.MIN_VALUE,
302: TimeSpan.MAX_VALUE).iterator();
303: while (iterator.hasNext()) {
304: CommunityPG pg = (CommunityPG) iterator.next();
305: System.out.println("\t" + pg.getCommunities() + " "
306: + pg.getStartTime() + " " + pg.getEndTime());
307: }
308:
309: PropertyGroupSchedule locked = schedule.lock();
310: System.out.println("locked size: " + locked.size());
311:
312: System.out.println("schedule == locked: "
313: + locked.equals(schedule));
314:
315: System.out.println("Locked");
316: iterator = locked.iterator();
317: while (iterator.hasNext()) {
318: CommunityPG pg = (CommunityPG) iterator.next();
319: System.out.println("\t" + pg.getCommunities() + " "
320: + pg.getStartTime() + " " + pg.getEndTime());
321: }
322:
323: System.out.println("Locked Filled");
324: iterator = locked.getTiling(TimeSpan.MIN_VALUE,
325: TimeSpan.MAX_VALUE).iterator();
326: while (iterator.hasNext()) {
327: CommunityPG pg = (CommunityPG) iterator.next();
328: System.out.println("\t" + pg.getCommunities() + " "
329: + pg.getStartTime() + " " + pg.getEndTime());
330: }
331:
332: System.out.println("locked: pgClass " + locked.getPGClass()
333: + " class: " + locked.getClass());
334: System.out
335: .println("schedule: pgClass " + schedule.getPGClass());
336:
337: PropertyGroupSchedule lockedClone = (PropertyGroupSchedule) locked
338: .clone();
339: System.out.println("lockedClone: " + lockedClone + " class: "
340: + lockedClone.getClass() + " pgClass: "
341: + lockedClone.getPGClass());
342:
343: try {
344: locked.setDefault(defaultPG);
345: System.out.println("Error: able to setDefault on locked");
346: } catch (Exception e) {
347: e.printStackTrace();
348: }
349: }
350:
351: /** @return the method name on an asset to retrieve the PG **/
352: public String getAssetGetMethod() {
353: try {
354: return ((PropertyGroup) (getPGClass().newInstance()))
355: .getAssetGetMethod()
356: + "Schedule";
357: } catch (Exception e) {
358: e.printStackTrace();
359: return "";
360: }
361:
362: }
363:
364: /** @return the method name on an asset to set the PG **/
365: public String getAssetSetMethod() {
366: try {
367: return ((PropertyGroup) (getPGClass().newInstance()))
368: .getAssetSetMethod()
369: + "Schedule";
370: } catch (Exception e) {
371: e.printStackTrace();
372: return "";
373: }
374: }
375:
376: private static PropertyDescriptor properties[];
377:
378: static {
379: try {
380: properties = new PropertyDescriptor[3];
381:
382: properties[0] = new PropertyDescriptor(
383: "property_group_class",
384: PropertyGroupSchedule.class, "getPGClass", null);
385: properties[1] = new PropertyDescriptor("default",
386: PropertyGroupSchedule.class, "getDefault", null);
387: properties[2] = new PropertyDescriptor("schedule",
388: PropertyGroupSchedule.class, "toArray", null);
389: } catch (Exception e) {
390: System.err.println("Caught: " + e);
391: e.printStackTrace();
392: }
393: }
394:
395: public PropertyDescriptor[] getPropertyDescriptors() {
396: return properties;
397: }
398:
399: public Class getIntrospectionClass() {
400: return PropertyGroupSchedule.class;
401: }
402:
403: /**
404: * Deny knowledge about the class and customizer of the bean.
405: * You can override this if you wish to provide explicit info.
406: */
407: public BeanDescriptor getBeanDescriptor() {
408: return null;
409: }
410:
411: /**
412: * Deny knowledge of a default property. You can override this
413: * if you wish to define a default property for the bean.
414: */
415: public int getDefaultPropertyIndex() {
416: return -1;
417: }
418:
419: /**
420: * Deny knowledge of event sets. You can override this
421: * if you wish to provide explicit event set info.
422: */
423: public EventSetDescriptor[] getEventSetDescriptors() {
424: return null;
425: }
426:
427: /**
428: * Deny knowledge of a default event. You can override this
429: * if you wish to define a default event for the bean.
430: */
431: public int getDefaultEventIndex() {
432: return -1;
433: }
434:
435: /**
436: * Deny knowledge of methods. You can override this
437: * if you wish to provide explicit method info.
438: */
439: public MethodDescriptor[] getMethodDescriptors() {
440: return null;
441: }
442:
443: /**
444: * Claim there are no other relevant BeanInfo objects. You
445: * may override this if you want to (for example) return a
446: * BeanInfo for a base class.
447: */
448: public BeanInfo[] getAdditionalBeanInfo() {
449: return null;
450: }
451:
452: /**
453: * Claim there are no icons available. You can override
454: * this if you want to provide icons for your bean.
455: */
456: public java.awt.Image getIcon(int iconKind) {
457: return null;
458: }
459:
460: /**
461: * This is a utility method to help in loading icon images.
462: * It takes the name of a resource file associated with the
463: * current object's class file and loads an image object
464: * from that file. Typically images will be GIFs.
465: * <p>
466: * @param resourceName A pathname relative to the directory
467: * holding the class file of the current class. For example,
468: * "wombat.gif".
469: * @return an image object. May be null if the load failed.
470: */
471: public java.awt.Image loadImage(final String resourceName) {
472: try {
473: final Class c = getClass();
474: java.awt.image.ImageProducer ip = (java.awt.image.ImageProducer) java.security.AccessController
475: .doPrivileged(new java.security.PrivilegedAction() {
476: public Object run() {
477: java.net.URL url;
478: if ((url = c.getResource(resourceName)) == null) {
479: return null;
480: } else {
481: try {
482: return url.getContent();
483: } catch (java.io.IOException ioe) {
484: return null;
485: }
486: }
487: }
488: });
489:
490: if (ip == null)
491: return null;
492: java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
493: return tk.createImage(ip);
494: } catch (Exception ex) {
495: return null;
496: }
497: }
498:
499: private final class _Locked extends PropertyGroupSchedule implements
500: LockedPGSchedule, BeanInfo {
501:
502: // Kludge to work around bug in Jikes - explicitly store a ref to the outer class
503: // since Jikes refuses to recognize PropertySchedule.this.
504: private PropertyGroupSchedule myRealSchedule = null;
505:
506: private transient Object theKey = null;
507:
508: _Locked(Object key, PropertyGroupSchedule parent) {
509: if (this .theKey == null) {
510: this .theKey = key;
511: }
512: myRealSchedule = parent;
513: }
514:
515: /** public constructor for beaninfo - won't work**/
516: public _Locked() {
517: RuntimeException rt = new RuntimeException(
518: "Calling the empty constructor");
519: rt.printStackTrace();
520: }
521:
522: public PropertyGroupSchedule lock() {
523: return this ;
524: }
525:
526: public PropertyGroupSchedule lock(Object o) {
527: return this ;
528: }
529:
530: public PropertyGroupSchedule unlock(Object key) {
531: if (theKey.equals(key))
532: return myRealSchedule;
533: else
534: throw new IllegalArgumentException(
535: "unlock: mismatched internal and provided keys!");
536: }
537:
538: public PropertyGroupSchedule copy() {
539: return (PropertyGroupSchedule) clone();
540: }
541:
542: public Object clone() {
543: return new PropertyGroupSchedule(myRealSchedule);
544: }
545:
546: public boolean equals(Object o) {
547: return myRealSchedule.equals(o);
548: }
549:
550: public int hashCode() {
551: return myRealSchedule.hashCode();
552: }
553:
554: public void initializePGClass(Class tppgClass) {
555: throw new UnsupportedOperationException();
556: }
557:
558: public void initializePGClass(PropertyGroup propertyGroup) {
559: throw new UnsupportedOperationException();
560: }
561:
562: public Class getPGClass() {
563: return myRealSchedule.getPGClass();
564: }
565:
566: public void setDefault(TimePhasedPropertyGroup defaultPG) {
567: throw new UnsupportedOperationException();
568: }
569:
570: public TimePhasedPropertyGroup getDefault() {
571: return myRealSchedule.getDefault();
572: }
573:
574: public void clearDefault() {
575: throw new UnsupportedOperationException();
576: }
577:
578: public boolean add(Object o) {
579: throw new UnsupportedOperationException();
580: }
581:
582: public boolean remove(Object o) {
583: throw new UnsupportedOperationException();
584: }
585:
586: public Object remove(int index) {
587: throw new UnsupportedOperationException();
588: }
589:
590: public boolean removeAll(Collection c) {
591: throw new UnsupportedOperationException();
592: }
593:
594: public boolean retainAll(Collection c) {
595: throw new UnsupportedOperationException();
596: }
597:
598: public void clear() {
599: throw new UnsupportedOperationException();
600: }
601:
602: public Iterator iterator() {
603: return myRealSchedule.iterator();
604: }
605:
606: public NonOverlappingTimeSpanSet getTiling(long startTime,
607: long endTime) {
608: return myRealSchedule.getTiling(startTime, endTime);
609: }
610:
611: public NonOverlappingTimeSpanSet getTiling(TimeSpan timeSpan) {
612: return myRealSchedule.getTiling(timeSpan);
613: }
614:
615: public NonOverlappingTimeSpanSet getTiling() {
616: return myRealSchedule.getTiling();
617: }
618:
619: public Object[] getTilingAsArray() {
620: return myRealSchedule.getTilingAsArray();
621: }
622:
623: public TimeSpan intersects(final long time) {
624: return myRealSchedule.intersects(time);
625: }
626:
627: public NonOverlappingTimeSpanSet fill(NewTimeSpan filler) {
628: return myRealSchedule.fill(filler);
629: }
630:
631: public void add(int i, Object o) {
632: throw new UnsupportedOperationException();
633: }
634:
635: public boolean addAll(Collection c) {
636: throw new UnsupportedOperationException();
637: }
638:
639: public boolean addAll(int index, Collection c) {
640: throw new UnsupportedOperationException();
641: }
642:
643: public boolean contains(Object o) {
644: return myRealSchedule.contains(o);
645: }
646:
647: public Object set(int index, Object element) {
648: throw new UnsupportedOperationException();
649: }
650:
651: // SortedSet implementation
652: public Comparator comparator() {
653: return myRealSchedule.comparator();
654: }
655:
656: public Object last() {
657: return myRealSchedule.last();
658: }
659:
660: public int size() {
661: return myRealSchedule.size();
662: }
663:
664: public boolean isEmpty() {
665: return myRealSchedule.isEmpty();
666: }
667:
668: public int indexOf(Object elem) {
669: return myRealSchedule.indexOf(elem);
670: }
671:
672: public int lastIndexOf(Object elem) {
673: return myRealSchedule.lastIndexOf(elem);
674: }
675:
676: public Object[] toArray() {
677: return myRealSchedule.toArray();
678: }
679:
680: public Object[] toArray(Object a[]) {
681: return myRealSchedule.toArray(a);
682: }
683:
684: public Object get(int index) {
685: return myRealSchedule.get(index);
686: }
687:
688: // BeanInfo - delegate to myRealSchedule
689:
690: public PropertyDescriptor[] getPropertyDescriptors() {
691: return myRealSchedule.getPropertyDescriptors();
692: }
693:
694: public BeanDescriptor getBeanDescriptor() {
695: return myRealSchedule.getBeanDescriptor();
696: }
697:
698: public int getDefaultPropertyIndex() {
699: return myRealSchedule.getDefaultPropertyIndex();
700: }
701:
702: public EventSetDescriptor[] getEventSetDescriptors() {
703: return myRealSchedule.getEventSetDescriptors();
704: }
705:
706: public int getDefaultEventIndex() {
707: return myRealSchedule.getDefaultEventIndex();
708: }
709:
710: public MethodDescriptor[] getMethodDescriptors() {
711: return myRealSchedule.getMethodDescriptors();
712: }
713:
714: public BeanInfo[] getAdditionalBeanInfo() {
715: return myRealSchedule.getAdditionalBeanInfo();
716: }
717:
718: public java.awt.Image getIcon(int iconKind) {
719: return myRealSchedule.getIcon(iconKind);
720: }
721:
722: public Class getIntrospectionClass() {
723: return myRealSchedule.getIntrospectionClass();
724: }
725:
726: }
727: }
|