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.mlm.debug.ui;
028:
029: import java.util.Calendar;
030: import java.util.Date;
031: import java.util.GregorianCalendar;
032: import java.util.TimeZone;
033:
034: public class UITimeLine {
035: private static long MSECS_PER_HOUR = 3600000;
036: private static long MSECS_PER_DAY = MSECS_PER_HOUR * 24;
037: private static int MIN_INTERVALS = 2;
038: private int numberOfIntervals;
039: private int intervalUnits;
040: private Date startDate;
041: private GregorianCalendar startCalendar;
042:
043: /** Create a timeline with the minimum and maximum times.
044: Optionally determine timeline divisions: years, days or hours.
045: @param startDate the date corresponding to the first division on the timeline
046: @param stopDate the date corresponding to the last division on the timeline
047: */
048: public UITimeLine(Date startDate, Date stopDate) {
049: initTimeLine(startDate, stopDate, false, 0);
050: }
051:
052: /** Create a timeline with the minimum and maximum times.
053: Optionally determine timeline divisions: years, days or hours.
054: @param startDate the date corresponding to the first division on the timeline
055: @param stopDate the date corresponding to the last division on the timeline
056: @param intervalUnits years, days, or hours, or unspecified
057: */
058: public UITimeLine(Date startDate, Date stopDate, int intervalUnits) {
059: initTimeLine(startDate, stopDate, true, intervalUnits);
060: }
061:
062: private void initTimeLine(Date startDate, Date stopDate,
063: boolean haveTimeIntervals, int intervalUnits) {
064: this .startDate = startDate;
065: startCalendar = new GregorianCalendar(TimeZone
066: .getTimeZone("GMT"));
067: startCalendar.setTime(startDate);
068: GregorianCalendar stopCalendar = new GregorianCalendar(TimeZone
069: .getTimeZone("GMT"));
070: stopCalendar.setTime(stopDate);
071: // determines number of intervals and interval units
072: if (haveTimeIntervals) {
073: this .intervalUnits = intervalUnits;
074: if (intervalUnits == Calendar.YEAR) {
075: int startYear = startCalendar.get(Calendar.YEAR);
076: int stopYear = stopCalendar.get(Calendar.YEAR);
077: numberOfIntervals = stopYear - startYear + 1;
078: } else {
079: long stopTime = stopCalendar.getTime().getTime();
080: long startTime = startCalendar.getTime().getTime();
081: if (intervalUnits == Calendar.DAY_OF_YEAR) {
082: numberOfIntervals = (int) ((stopTime - startTime) / MSECS_PER_DAY) + 1;
083: } else if (intervalUnits == Calendar.HOUR_OF_DAY) { // use hours
084: numberOfIntervals = (int) ((stopTime - startTime) / MSECS_PER_HOUR) + 1;
085: } else {
086: System.out
087: .println("Ignoring invalid time line interval.");
088: setIntervalUnits(startCalendar, stopCalendar);
089: }
090: }
091: } else
092: setIntervalUnits(startCalendar, stopCalendar);
093: }
094:
095: private void setIntervalUnits(GregorianCalendar startCalendar,
096: GregorianCalendar stopCalendar) {
097: int startYear = startCalendar.get(Calendar.YEAR);
098: int stopYear = stopCalendar.get(Calendar.YEAR);
099:
100: // if schedule is greater than 1 year long, use years as time intervals
101: if ((stopYear - startYear) > 1) {
102: numberOfIntervals = stopYear - startYear + 1;
103: intervalUnits = Calendar.YEAR;
104: return;
105: }
106:
107: // if schedule is greater than minInterval days long, use days
108: long stopTime = stopCalendar.getTime().getTime();
109: long startTime = startCalendar.getTime().getTime();
110: numberOfIntervals = (int) ((stopTime - startTime) / MSECS_PER_DAY) + 1;
111: if (numberOfIntervals > MIN_INTERVALS) {
112: intervalUnits = Calendar.DAY_OF_YEAR;
113: return;
114: }
115:
116: // use hour intervals
117: intervalUnits = Calendar.HOUR_OF_DAY;
118: numberOfIntervals = (int) ((stopTime - startTime) / MSECS_PER_HOUR) + 1;
119: }
120:
121: /** Return array of strings for timeline labels.
122: @return the numeric labels for the timeline
123: */
124:
125: public String[] getLabels() {
126: String labels[] = new String[numberOfIntervals];
127: GregorianCalendar nextCalendar = (GregorianCalendar) startCalendar
128: .clone();
129: int labelUnits = intervalUnits;
130: if (labelUnits == Calendar.DAY_OF_YEAR)
131: labelUnits = Calendar.DAY_OF_MONTH; // more useful
132: for (int i = 0; i < numberOfIntervals; i++) {
133: labels[i] = String.valueOf(nextCalendar.get(labelUnits));
134: nextCalendar.add(intervalUnits, 1);
135: }
136: return labels;
137: }
138:
139: /** Get number of intervals in the timeline.
140: @return number of intervals in the timeline
141: */
142:
143: public int getNumberOfIntervals() {
144: return numberOfIntervals;
145: }
146:
147: /** Get timeline units.
148: @return Calendar.HOUR_OF_DAY, Calendar.DAY_OF_YEAR, or Calendar.HOUR_OF_DAY
149: */
150:
151: public int getIntervalUnits() {
152: return intervalUnits;
153: }
154:
155: /** Get timeline units name.
156: @return "Hours" "Days" or "Year"
157: */
158:
159: public String getIntervalUnitsName() {
160: switch (intervalUnits) {
161: case Calendar.HOUR_OF_DAY:
162: return "Hours";
163: case Calendar.DAY_OF_YEAR:
164: return "Days";
165: case Calendar.YEAR:
166: return "Year";
167: default:
168: return "";
169: }
170: }
171:
172: /** For testing, create a time line.
173: */
174:
175: public static void main(String args[]) {
176: GregorianCalendar start = new GregorianCalendar(1999, 12, 31,
177: 9, 0, 0);
178: GregorianCalendar stop = new GregorianCalendar(2000, 1, 1, 20,
179: 0, 0);
180: Date startDate = start.getTime();
181: Date stopDate = stop.getTime();
182: long x = stopDate.getTime() - startDate.getTime();
183: System.out.println("Difference is: " + x);
184: UITimeLine timeLine = new UITimeLine(startDate, stopDate);
185: System.out.println("Number of intervals: "
186: + timeLine.getNumberOfIntervals());
187: }
188: }
|