View Javadoc
1   //
2   //Unit.java
3   //MirkE_0.3_withoutAnt
4   //
5   //Created by Scott Menor on 5.11.04.
6   //Copyright 2004 . All rights reserved.
7   //
8   /*  ***************************************
9    *
10   * Modified 07/01/05 by jafaleon
11   *
12   * The general idea of this class is that every unit is refernced to
13   * another unit that is used for the same magnitude.
14   * So, for each magnitude will be e first unit which will be
15   * the master unit for that magnitude, every new unit entered by
16   * the user must be referenced to an existing unit or be the
17   * master unit applying to that fiel.
18   *
19   * The idea is to make the conversion
20   * value, unitConversionValue, referncing the master unit of the
21   * magnitude and then hiding the master unit from the user.
22   * In the class that makes the new units must check the field before
23   * if the field is a new one then the constructor for the master 
24   * unit shall be used e.g.
25   *  if(!findField(fieldName){
26   *       createMasterUnit(fieldName);
27   *  }
28   * //create new unit here.
29   * 
30   * 
31   * Modified 07.01.05 by smenor
32   * 
33   * Made a slight modification to the conversion method. Now including a conversion offset
34   *  and multipliter. To convert a value, v_i, from the i'th unit to j'th, we take 
35   * 
36   *  v_j = m_i,j * v_i + a_i,j
37   * 
38   * where m_i,j is the multiplier from i'th to j'th units and a_i,j is the corresponding offset.
39   * 
40   *
41   * Modified 10.01.05 by jafaleon
42   *  added the classic id field for database key.
43   *  added unitAbbreviation field for the abbreviation of the unit's name.   
44   *  a new constructor to admit the abbeviation as a parameter.
45   * 
46   */
47  
48  package edu.asu.cri.MirkE.dataStructures;
49  
50  import java.util.HashMap;
51  
52  /***
53   * @author jafaleon
54   *
55   */
56  public class Unit {
57      /*** 
58       * id field for Hibernate. 
59       */ 
60      private long id;
61      
62      /***
63      
64       @return id
65       */
66      public long getId() {
67          return id;
68      }
69      
70      /***
71          @param id
72       */
73      public void setId(long id) {
74          this.id = id;
75      }
76      
77      /*** 
78       * Unit abbreviation not need to write Kilometers if km. is enough  
79       */ 
80      private String unitAbbreviation; 
81      
82      /*** 
83       * @return Returns the unitAbbreviation. 
84       */ 
85      public String getUnitAbbreviation() { 
86          return unitAbbreviation; 
87      }
88      
89      /*** 
90       * @param unitAbbreviation The unitAbbreviation to set. 
91       */ 
92      protected void setUnitAbbreviation(String unitAbbreviation) { 
93          this.unitAbbreviation = unitAbbreviation; 
94      } 
95      
96      /*** 
97       *String field identifying the magnitude meassured by the unit. 
98       */ 
99      private String unitField; 
100     
101     /***
102      *The name of the unit.
103      */
104     private String unitName;
105     
106     /***
107      *The converssion value of the unit.
108      */
109     private double unitConversionMultiplier;
110     private double unitConversionOffset;
111     
112     /*** 
113      * Parameter-free JavaBean constructor (for Hibernate)
114      */
115     protected Unit() {
116         
117     }
118     
119     /***
120      *Constructor for the class which is intended only for the 
121      * master unit of every field..
122      *@param unitField the magnitude measured by this unit.
123      */
124     private Unit(String unitField){
125         this.unitName = unitField;
126         this.unitField = unitField;
127         this.unitConversionMultiplier = 1;
128         this.unitConversionOffset = 0;
129     }
130     
131     /***
132      *Constructor for the class which can be converted to the master unit.
133      *@param unitName The name given to the unit.
134      *@param unitConversionMultiplier the value to multiply the unit to the <code>referenceUnit</code>.
135      *@param unitConversionOffset the value to add to <code>unitConversionMultiplier</code>*<code>referenceUnit</code>
136      *@param referenceUnit the reference unit for this one.
137      */
138     private Unit(
139             String unitName, 
140             double unitConversionMultiplier, 
141             double unitConversionOffset, 
142             Unit referenceUnit) {
143         this.unitName = unitName;
144         this.unitConversionMultiplier = unitConversionMultiplier * referenceUnit.getUnitConversionMultiplier();
145         this.unitConversionOffset = unitConversionMultiplier*referenceUnit.getUnitConversionOffset() + unitConversionOffset;
146         
147         this.unitField = referenceUnit.getUnitField();
148     }
149     
150     /***
151      *Constructor for the class which can be converted to the master unit.
152      *@param unitName The name given to the unit.
153      *@param unitAbbreviation
154      *@param unitConversionMultiplier the value to multiply the unit to the <code>referenceUnit</code>.
155      *@param unitConversionOffset the value to add to <code>unitConversionMultiplier</code>*<code>referenceUnit</code>
156      *@param referenceUnit the reference unit for this one.
157      */
158     private Unit(
159             String unitName, 
160             String unitAbbreviation,
161             double unitConversionMultiplier, 
162             double unitConversionOffset, 
163             Unit referenceUnit) {
164         this.unitName = unitName;
165         this.unitAbbreviation = unitAbbreviation;
166         this.unitConversionMultiplier = unitConversionMultiplier * referenceUnit.getUnitConversionMultiplier();
167         this.unitConversionOffset = unitConversionMultiplier*referenceUnit.getUnitConversionOffset() + unitConversionOffset;
168         
169         this.unitField = referenceUnit.getUnitField();
170     }
171     
172     /***
173      * @return Returns the unitConversionMultiplier.
174      */
175     public double getUnitConversionMultiplier() {
176         return unitConversionMultiplier;
177     } 
178     
179     /***
180      * @param unitConversionMultiplier The unitConversionMultiplier to set.
181      */
182     private void setUnitConversionMultiplier(double unitConversionMultiplier) {
183         this.unitConversionMultiplier = unitConversionMultiplier;
184     }
185     
186     /***
187      * @return Returns the unitConversionOffset.
188      */
189     public double getUnitConversionOffset() {
190         return this.unitConversionOffset;
191     }
192     
193     /***
194      * @param unitConversionOffset The unitConversionOffset to set.
195      */
196     private void setUnitConversionOffset(double unitConversionOffset) {
197         this.unitConversionOffset = unitConversionOffset;
198     }
199     
200     /***
201      * @return Returns the unitField.
202      */
203     public String getUnitField() {
204         return unitField;
205     }
206     
207     /***
208      * @param unitField The unitField to set.
209      */
210     private void setUnitField(String unitField) {
211         this.unitField = unitField;
212     }
213     
214     /***
215      * @return Returns the unitName.
216      */
217     public String getUnitName() {
218         return unitName;
219     }
220     
221     /***
222      * @param unitName The unitName to set.
223      */
224     private void setUnitName(String unitName) {
225         this.unitName = unitName;
226     }
227     
228     /***
229      * Method converTo converts the given amount of this unit
230      *  to its corresponding value measured with the other unit
231      * 
232      * @param quantity the amount in this unit
233      * @param resultUnit the units in wich the result will be given.
234      * @return the conversion rate from this unit to the resultUnit.
235      */
236     public double convertTo(
237             double quantity, 
238             Unit resultUnit) {
239         if(isCompatible(resultUnit)){
240             
241             double quantityInBaseUnits = (quantity-this.unitConversionOffset)/this.unitConversionMultiplier;
242             double quantityInResultUnits = resultUnit.getUnitConversionMultiplier()*quantityInBaseUnits + resultUnit.getUnitConversionOffset();
243             
244             return quantityInResultUnits;
245             
246         } else{
247             // TODO - A Exception should be thrown instead.
248             return Double.NaN;
249         }
250     }
251     
252     /***
253      *  Method to know if two units are compatible.
254      * @param unit the other unit
255      * @return true if they are compatible.
256      */
257     public boolean isCompatible(Unit unit){
258         if(unitField.equals(unit.getUnitField())){
259             return true;
260         }else{
261             return false;
262         }
263     }
264     
265     /***
266      * @return stringValue
267      */
268     public String toString() {
269         String stringValue = null;
270         if (this.unitAbbreviation == null) {
271             stringValue = this.unitName;
272         } else {
273             stringValue = this.unitAbbreviation;
274         }
275         
276         return stringValue;
277     }
278     
279     /***
280      * @see java.lang.Object#equals(java.lang.Object)
281      */
282     public boolean equals(Object object) {
283         if (object instanceof Unit) {
284             Unit comparisonUnit = (Unit)object;
285             
286             if (comparisonUnit.isCompatible(this)) {
287                 if (
288                         (convertTo(0, comparisonUnit) == 0) &&
289                         (convertTo(1, comparisonUnit) == 1)) {
290                     
291                     return true; 
292                 }
293             }
294         }
295         
296         return false;
297     }
298     
299     private static HashMap unitNameToUnitMap = new HashMap();
300 
301     /***
302      * @param unitName 
303      * @return an instance of Unit with name unitName 
304      */
305     public static Unit createUnit(String unitName) {
306         if (unitNameToUnitMap.containsKey(unitName)) {
307             return (Unit)unitNameToUnitMap.get(unitName);
308         } else {
309             Unit unit = new Unit(unitName);
310             unitNameToUnitMap.put(unitName, unit);
311             return unit;
312         }
313     }
314 
315     /***
316      * @param unitName
317      * @param unitConversionMultiplier
318      * @param unitConversionOffset
319      * @param referenceUnit
320      * @return an instance of Unit with name <code>unitName</code> = <code>unitConversionMultiplier</code>*<code>referenceUnit</code> + <code>unitConversionOffset</code> 
321      */
322     public static Unit createUnit(
323             String unitName,
324             double unitConversionMultiplier, 
325             double unitConversionOffset, 
326             Unit referenceUnit) {
327         if (unitNameToUnitMap.containsKey(unitName)) {
328             Unit unit = (Unit)unitNameToUnitMap.get(unitName);
329             if (1==1) { // TODO - ensure that unit is the same Unit as the one the user is seeking and throw an exception if not
330                 return unit;
331                 
332             } else {
333                 return null;
334                 
335             }
336             
337         } else {
338             Unit unit = new Unit(
339                     unitName, 
340                     unitConversionMultiplier, 
341                     unitConversionOffset, 
342                     referenceUnit);
343             unitNameToUnitMap.put(unitName, unit);
344             return unit;
345         }
346     }
347     
348     /***
349      * @param unitName
350      * @param unitAbbreviation
351      * @param unitConversionMultiplier
352      * @param unitConversionOffset
353      * @param referenceUnit
354      * @return an instance of Unit with name <code>unitName</code> = <code>unitConversionMultiplier</code>*<code>referenceUnit</code> + <code>unitConversionOffset</code> 
355      */
356     public static Unit createUnit(
357             String unitName, 
358             String unitAbbreviation,
359             double unitConversionMultiplier, 
360             double unitConversionOffset, 
361             Unit referenceUnit) {
362         if (unitNameToUnitMap.containsKey(unitName)) {
363             Unit unit = (Unit)unitNameToUnitMap.get(unitName);
364             if (1==1) { // TODO - ensure that unit is the same Unit as the one the user is seeking and throw an exception if not
365                 return unit;
366                 
367             } else {
368                 return null;
369             }
370             
371         } else {
372             Unit unit = new Unit(
373                     unitName, 
374                     unitAbbreviation,
375                     unitConversionMultiplier, 
376                     unitConversionOffset,
377                     referenceUnit);
378             unitNameToUnitMap.put(unitName, unit);
379             return unit;
380         }
381     }
382 }