View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.monitoring;
19  
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Set;
25  import java.util.concurrent.ConcurrentHashMap;
26  import java.util.concurrent.CopyOnWriteArrayList;
27  import java.util.concurrent.CopyOnWriteArraySet;
28  
29  /**
30   * Units allow monitored data to have get typed. A primary unit is the
31   * finest unit for a data type. A primary unit can have derived units,
32   * that represent the same data type, but with a scale factor.
33   * A primary Unit is created with the {@link Unit#Unit(String)} constructor.
34   * A derived Unit is created with the {@link Unit#Unit(String, Unit, long)} constructor.
35   * <p>
36   * A primary Unit maintains a Map of it's derived units. {@ Unit#getDerived()} can be
37   * used to retrieve the complete list, and {@ Unit#getDerived(String)} to retrieve a
38   * derived unit by it's name.
39   *
40   * @author <a href="mailto:nicolas@apache.org">Nicolas De Loof</a>
41   */
42  public class Unit implements Comparable<Unit>
43  {
44      private static final Map<String, Unit> UNITS = new ConcurrentHashMap<String,Unit>();
45  
46      /** Time based units */
47      public static final Unit NANOS = new Unit( "ns" );
48      public static final Unit MICROS = new Unit( "µs", NANOS, 1000 );
49      public static final Unit MILLIS = new Unit( "ms", MICROS, 1000 );
50      public static final Unit SECOND = new Unit( "s", MILLIS, 1000 );
51      public static final Unit MINUTE = new Unit( "min", SECOND, 60 );
52      public static final Unit HOUR = new Unit( "h", MINUTE, 60 );
53      public static final Unit DAY = new Unit( "day", HOUR, 24 );
54  
55      /** Binary data units */
56      public static final Unit BYTE = new Unit( "b" );
57      public static final Unit KBYTE = new Unit( "Kb", BYTE, 1024 );
58      public static final Unit MBYTE = new Unit( "Mb", KBYTE, 1024 );
59      public static final Unit GBYTE = new Unit( "Gb", MBYTE, 1024 );
60  
61  
62      /** unit for basic item counters & gauges */
63      // "BILLION" does not have same signification depending on state (10^12 or 10^9)
64      // we use International system of unit names to avoid confusion
65      // @see http://en.wikipedia.org/wiki/SI
66      public static final Unit UNARY = new Unit( "" );
67      public static final Unit DECA = new Unit( "*10", UNARY, 10 );
68      public static final Unit HECTO = new Unit( "*100", DECA, 10 );
69      public static final Unit KILO = new Unit( "*1000", HECTO, 10 );
70      public static final Unit MEGA = new Unit( "*10^6", KILO, 1000 );
71      public static final Unit GIGA = new Unit( "*10^9", MEGA, 1000 );
72      public static final Unit TERA = new Unit( "*10^12", GIGA, 1000 );
73  
74      private final String name;
75  
76      private final long scale;
77  
78      private Unit primary;
79  
80      private List<Unit> derived;
81  
82      public Set<Unit> primaryUnits = new CopyOnWriteArraySet<Unit>();
83  
84  
85      public static Unit get( String name )
86      {
87          return UNITS.get( name );
88      }
89  
90      /**
91       * Constructor for a primary unit
92       * @param name
93       */
94      public Unit( String name )
95      {
96          this.name = name;
97          this.primary = this;
98          this.scale = 1;
99          this.derived = new ArrayList<Unit>();
100         this.derived.add( this );
101         primaryUnits.add( this );
102         UNITS.put( name, this );
103     }
104 
105     /**
106      * Constructor for a derived unit
107      * @param name
108      * @param derived the unit this unit is derived from
109      * @param scale the scale factor to convert to derived unit
110      */
111     public Unit( String name, Unit derived, long scale )
112     {
113         this.name = name;
114         this.primary = derived.isPrimary() ? derived : derived.getPrimary();
115         this.scale = scale * derived.getScale();
116         primary.derived.add( this );
117         Collections.sort( primary.derived );
118         UNITS.put( name, this );
119     }
120 
121     public Unit getDerived( String name )
122     {
123         for ( Unit unit : derived )
124         {
125             if (unit.name.equals( name ))
126             {
127                 return unit;
128             }
129         }
130         return null;
131     }
132 
133     public List<Unit> getDerived()
134     {
135         return Collections.unmodifiableList( derived );
136     }
137 
138 
139     public String getName()
140     {
141         return name;
142     }
143 
144     public long getScale()
145     {
146         return scale;
147     }
148 
149     public boolean isPrimary()
150     {
151         return primary == this;
152     }
153 
154     public boolean isCompatible( Unit unit )
155     {
156         return primary == unit.getPrimary();
157     }
158 
159     public Unit getPrimary()
160     {
161         return this.primary;
162     }
163 
164     public int compareTo( Unit o )
165     {
166         return scale < o.scale ? -1 : 1;
167     }
168 
169     public String toString()
170     {
171         return name;
172     }
173 
174     /**
175      * @see java.lang.Object#hashCode()
176      */
177     @Override
178     public int hashCode()
179     {
180         final int prime = 31;
181         int result = 1;
182         result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
183         return result;
184     }
185 
186     /**
187      * @see java.lang.Object#equals(java.lang.Object)
188      */
189     @Override
190     public boolean equals( Object obj )
191     {
192         if ( this == obj )
193             return true;
194         if ( obj == null )
195             return false;
196         if ( getClass() != obj.getClass() )
197             return false;
198         final Unit other = (Unit) obj;
199         if ( name == null )
200         {
201             if ( other.name != null )
202                 return false;
203         }
204         else if ( !name.equals( other.name ) )
205             return false;
206         return true;
207     }
208 
209 }