001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/csct/units/Unit.java $
002    /*
003     * Units specification.
004     */
005    package org.deegree.model.csct.units;
006    
007    // Miscellaneous
008    import java.util.Map;
009    import java.util.HashMap;
010    import java.io.Serializable;
011    
012    /**
013     * Placeholder for future <code>Unit</code> class. This skeleton will be removed when the real
014     * classes (from <A HREF="http://www.jcp.org/jsr/detail/108.jsp">JSR-108: Units specification</A>)
015     * will be publicly available. <br>
016     * <br>
017     * <strong>IMPORTANT: future version will NOT be compatible will this one. Remind, this is a
018     * temporary class!</strong>
019     */
020    public final class Unit implements Serializable {
021        /**
022         * Pool of units.
023         */
024        private static final Map<Unit, Unit> pool = new HashMap<Unit, Unit>();
025    
026        /**
027         * Unit of angle.
028         */
029        public static final Unit DEGREE = new Unit( "�" );
030    
031        /**
032         * Base unit of length.
033         */
034        public static final Unit METRE = new Unit( "m" );
035    
036        /**
037         * British yard; unit of length.
038         */
039        public static final Unit BRITISHYARD = new Unit( "y", 0.9144, METRE );
040    
041        /**
042         * Base unit of time.
043         */
044        public static final Unit SECOND = new Unit( "s" );
045    
046        /**
047         * Unit of time.
048         */
049        public static final Unit MILLISECOND = new Unit( "ms", 0.001, SECOND );
050    
051        /**
052         * Unit of time.
053         */
054        public static final Unit DAY = new Unit( "day", 24 * 60 * 60, SECOND );
055    
056        /**
057         * The unit's symbol.
058         */
059        private final String symbol;
060    
061        /**
062         * The scale factor.
063         */
064        private final double scale;
065    
066        /**
067         * Base unit, or <code>this</code> if none.
068         */
069        private final Unit unit;
070    
071        /**
072         * Returns an unit instance.
073         */
074        public static Unit get( final String symbol ) {
075            synchronized ( pool ) {
076                final Unit unit = new Unit( symbol );
077                final Unit current = pool.get( unit );
078                if ( current != null )
079                    return current;
080                pool.put( unit, unit );
081                return unit;
082            }
083        }
084    
085        /**
086         * Unit constructor. Don't allow user creation, since this is not the official Unit class.
087         */
088        private Unit( final String symbol ) {
089            this.symbol = symbol;
090            this.scale = 1;
091            this.unit = this;
092        }
093    
094        /**
095         * Unit constructor. Don't allow user creation, since this is not the official Unit class.
096         */
097        private Unit( final String symbol, final double scale, final Unit unit ) {
098            this.symbol = symbol;
099            this.scale = scale;
100            this.unit = unit;
101        }
102    
103        /**
104         * Check if amount of the specified unit can be converted into amount of this unit.
105         */
106        public boolean canConvert( final Unit other ) {
107            return ( unit == other.unit ) || ( unit != null && unit.equals( other.unit ) );
108        }
109    
110        /**
111         * Convert a value from one unit to an other. This method is not implemented (the JSR-108 will
112         * provide the reference implementation).
113         */
114        public double convert( final double value, final Unit unit ) {
115            if ( canConvert( unit ) )
116                return value * unit.scale / scale;
117            throw new IllegalArgumentException( "Can't convert from \"" + this + "\" to \"" + unit + "\"." );
118        }
119    
120        /**
121         * Returns a string representation of this unit's symbol.
122         */
123        public String toString() {
124            return symbol;
125        }
126    
127        /**
128         * Returns a hash code value.
129         */
130        public int hashCode() {
131            return symbol.hashCode();
132        }
133    
134        /**
135         * Compare this unit symbol with the specified object for equality. Only symbols are compared;
136         * other parameters are ignored.
137         */
138        public boolean equals( final Object object ) {
139            if ( object instanceof Unit ) {
140                final Unit that = (Unit) object;
141                return symbol.equals( that.symbol );
142            }
143            return false;
144        }
145    }