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: /** Immutable implementation of Heading.
027: **/package org.cougaar.planning.ldm.measure;
028:
029: public final class Heading extends AbstractMeasure {
030: private final double upperBound = 360.0;
031: private final double lowerBound = 0.0;
032: private final double wrapUpperBound = -1.0;
033: private final double wrapLowerBound = -360.0;
034:
035: //no real conversions for now
036: private static final Conversion DEGREES_TO_DEGREES = new Conversion() {
037: public double convert(double from) {
038: return from;
039: }
040: };
041:
042: // basic unit is Degrees
043: private double theValue;
044:
045: // private constructor
046: private Heading(double v) throws ValueRangeException {
047: if (inBounds(v)) {
048: if (v == 360.0) {
049: theValue = 0.0;
050: } else {
051: theValue = v;
052: }
053: } else if (inWrapBounds(v)) {
054: theValue = figureWrap(v);
055: } else {
056: throw new ValueRangeException(
057: "Heading expects the double to be between 0.0 and 360.0.");
058: }
059:
060: }
061:
062: public Heading(String s) {
063: int i = indexOfType(s);
064: if (i < 0)
065: throw new UnknownUnitException();
066: double n = Double.valueOf(s.substring(0, i).trim())
067: .doubleValue();
068: String u = s.substring(i).trim().toLowerCase();
069: if (u.equals("degrees"))
070: theValue = n;
071: else
072: throw new UnknownUnitException();
073: }
074:
075: public int getCommonUnit() {
076: return 0;
077: }
078:
079: public int getMaxUnit() {
080: return 0;
081: }
082:
083: public String getUnitName(int i) {
084: if (i == 0)
085: return "degrees";
086: else
087: throw new IllegalArgumentException();
088: }
089:
090: // TypeNamed factory methods
091: public static Heading newDegrees(double v) {
092: return new Heading(v);
093: }
094:
095: public static Heading newDegrees(String s) {
096: return new Heading((Double.valueOf(s).doubleValue()));
097: }
098:
099: // TypeNamed factory methods
100: public static Heading newHeading(double v) {
101: return new Heading(v);
102: }
103:
104: public static Heading newHeading(String s) {
105: return new Heading((Double.valueOf(s).doubleValue()));
106: }
107:
108: // Index Typed factory methods
109: // ***No real conversions for now
110: private static final Conversion convFactor[] = {
111: //conversions to base units
112: DEGREES_TO_DEGREES,
113: //RADIANS_TO_DEGREES,
114: // conversions from base units
115: DEGREES_TO_DEGREES
116: //DEGREES_TO_RADIANS
117: };
118: // indexes into factor array
119: public static int DEGREES = 0;
120: //public static int RADIANS = 1;
121: private static int MAXUNIT = 0;
122:
123: // Index Typed factory methods
124: public static Heading newHeading(double v, int unit) {
125: if (unit >= 0 && unit <= MAXUNIT)
126: return new Heading(convFactor[unit].convert(v));
127: else
128: throw new UnknownUnitException();
129: }
130:
131: public static Heading newHeading(String s, int unit) {
132: if (unit >= 0 && unit <= MAXUNIT)
133: return new Heading(convFactor[unit].convert(Double.valueOf(
134: s).doubleValue()));
135: else
136: throw new UnknownUnitException();
137: }
138:
139: // Support for AbstractMeasure-level constructor
140: public static AbstractMeasure newMeasure(String s, int unit) {
141: return newHeading(s, unit);
142: }
143:
144: public static AbstractMeasure newMeasure(double v, int unit) {
145: return newHeading(v, unit);
146: }
147:
148: // Unit-based Reader methods
149: public double getDegrees() {
150: return (theValue);
151: }
152:
153: //public double getRADIANS() {
154: //return (DEGREES_TO_RADIANS.convert(theValue));
155: //}
156:
157: public double getValue(int unit) {
158: if (unit >= 0 && unit <= MAXUNIT)
159: return convFactor[MAXUNIT + 1 + unit].convert(theValue);
160: else
161: throw new UnknownUnitException();
162: }
163:
164: public static Conversion getConversion(final int from, final int to) {
165: if (from >= 0 && from <= MAXUNIT && to >= 0 && to <= MAXUNIT) {
166: return new Conversion() {
167: public double convert(double value) {
168: return convFactor[MAXUNIT + 1 + to]
169: .convert(convFactor[from].convert(value));
170: }
171: };
172: } else
173: throw new UnknownUnitException();
174: }
175:
176: public boolean equals(Object o) {
177: return (o instanceof Heading && theValue == ((Heading) o)
178: .getDegrees());
179: }
180:
181: public String toString() {
182: return Double.toString(theValue) + "o";
183: }
184:
185: public int hashCode() {
186: return (new Double(theValue)).hashCode();
187: }
188:
189: private double figureWrap(double v) {
190: double wrappedValue = v + 360.0;
191: return wrappedValue;
192: }
193:
194: private boolean inWrapBounds(double v) {
195: boolean ok;
196: if ((v <= wrapUpperBound) && (v >= wrapLowerBound)) {
197: ok = true;
198: } else {
199: ok = false;
200: }
201: return ok;
202: }
203:
204: private boolean inBounds(double v) {
205: boolean ok;
206: if ((v <= upperBound) && (v >= lowerBound)) {
207: ok = true;
208: } else {
209: ok = false;
210: }
211: return ok;
212: }
213:
214: /**
215: * TODO : fill in
216: * @param other
217: * @return
218: */
219: public Measure add(Measure other) {
220: return null;
221: }
222:
223: /**
224: * TODO : fill in
225: * @param other
226: * @return
227: */
228: public Measure subtract(Measure other) {
229: return null;
230: }
231:
232: /**
233: * TODO : fill in
234: * @param other
235: * @return
236: */
237: public Measure multiply(Measure other) {
238: return null;
239: }
240:
241: /**
242: * TODO : fill in
243: * @param other
244: * @return
245: */
246: public Measure divide(Measure other) {
247: return null;
248: }
249:
250: public Measure negate() {
251: return null;
252: }
253:
254: public Measure scale(double scale) {
255: return null;
256: }
257:
258: public Measure floor(int unit) {
259: return null;
260: }
261:
262: public Measure valueOf(double value) {
263: return null;
264: }
265:
266: public Measure valueOf(double value, int unit) {
267: return null;
268: }
269:
270: public int getNativeUnit() {
271: return 0;
272: }
273:
274: public double getNativeValue() {
275: return getValue(getNativeUnit());
276: }
277:
278: public Duration divide(Rate rate) {
279: return null;
280: }
281: } // end Heading
|