View Javadoc
1   /*
2    * Copyright (C) 2018 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.units;
17  
18  import java.text.ParseException;
19  import java.util.Locale;
20  
21  /**
22   * Formats and parses frequency value and unit.
23   */
24  public class FrequencyFormatter extends MeasureFormatter<Frequency, FrequencyUnit> {
25  
26      /**
27       * Hertz symbol.
28       */
29      public static final String HERTZ = "Hz";
30  
31      /**
32       * KiloHertz symbol.
33       */
34      public static final String KILOHERTZ = "KHz";
35  
36      /**
37       * MegaHertz symbol.
38       */
39      public static final String MEGAHERTZ = "MHz";
40  
41      /**
42       * GigaHertz symbol.
43       */
44      public static final String GIGAHERTZ = "GHz";
45  
46      /**
47       * TeraHertz symbol.
48       */
49      public static final String TERAHERTZ = "THz";
50  
51      /**
52       * Constructor.
53       */
54      public FrequencyFormatter() {
55          super();
56      }
57  
58      /**
59       * Constructor with locale.
60       *
61       * @param locale locale.
62       * @throws IllegalArgumentException if locale is null.
63       */
64      public FrequencyFormatter(final Locale locale) {
65          super(locale);
66      }
67  
68      /**
69       * Copy constructor.
70       *
71       * @param formatter input instance to copy from.
72       * @throws NullPointerException if provided formatter is null.
73       */
74      public FrequencyFormatter(final FrequencyFormatter formatter) {
75          this(formatter.getLocale());
76      }
77  
78      /**
79       * Determines if two frequency formatters are equal by comparing all of their
80       * internal parameters.
81       *
82       * @param obj another object to compare.
83       * @return true if provided object is assumed to be equal to this instance.
84       */
85      @Override
86      public boolean equals(final Object obj) {
87          final var equals = super.equals(obj);
88          return (obj instanceof FrequencyFormatter) && equals;
89      }
90  
91      /**
92       * Hash code generated for this instance.
93       * Hash codes can be internally used by some collections to coarsely compare objects.
94       * This implementation only calls parent implementation to avoid static analyzer warning.
95       *
96       * @return hash code.
97       */
98      @Override
99      public int hashCode() {
100         return super.hashCode();
101     }
102 
103     /**
104      * Gets unit system for detected unit into provided string representation
105      * of a measurement.
106      *
107      * @param source a measurement string representation to be checked.
108      * @return a unit system (either metric or imperial) or null if unit
109      * cannot be determined.
110      */
111     @Override
112     public UnitSystem getUnitSystem(final String source) {
113         return UnitSystem.METRIC;
114     }
115 
116     /**
117      * Parses provided string and tries to determine a frequency value and unit.
118      *
119      * @param source a string to be parsed.
120      * @return a frequency containing a value and unit.
121      * @throws ParseException       if provided string cannot be parsed.
122      * @throws UnknownUnitException if unit cannot be determined.
123      */
124     @Override
125     public Frequency parse(final String source) throws ParseException, UnknownUnitException {
126         return internalParse(source, new Frequency());
127     }
128 
129     /**
130      * Attempts to determine a frequency unit within a frequency string
131      * representation.
132      *
133      * @param source a frequency measurement string representation.
134      * @return a frequency unit, or null if none can be determined.
135      */
136     @Override
137     public FrequencyUnit findUnit(final String source) {
138         if (source.contains(KILOHERTZ + " ") || source.endsWith(KILOHERTZ)) {
139             return FrequencyUnit.KILOHERTZ;
140         }
141         if (source.contains(MEGAHERTZ + " ") || source.endsWith(MEGAHERTZ)) {
142             return FrequencyUnit.MEGAHERTZ;
143         }
144         if (source.contains(GIGAHERTZ + " ") || source.endsWith(GIGAHERTZ)) {
145             return FrequencyUnit.GIGAHERTZ;
146         }
147         if (source.contains(TERAHERTZ + " ") || source.endsWith(TERAHERTZ)) {
148             return FrequencyUnit.TERAHERTZ;
149         }
150         if (source.contains(HERTZ + " ") || source.endsWith(HERTZ)) {
151             return FrequencyUnit.HERTZ;
152         }
153         return null;
154     }
155 
156     /**
157      * Formats and converts provided frequency value and unit using provided unit
158      * system.
159      * If provided value is too large for provided unit, this method will convert
160      * it to a more appropriate unit. This implementation ignores unit system.
161      *
162      * @param value  a measurement value.
163      * @param unit   a measurement unit.
164      * @param system system unit to convert measurement to (it is ignored).
165      * @return a string representation of frequency value and unit.
166      */
167     @Override
168     public String formatAndConvert(final Number value, final FrequencyUnit unit, final UnitSystem system) {
169         return formatAndConvertMetric(value, unit);
170     }
171 
172     /**
173      * Formats and converts provided frequency value and unit using metric unit
174      * system.
175      * If provided frequency value is too large for provided frequency unit, this
176      * method will convert it to a more appropriate unit.
177      *
178      * @param value a frequency value.
179      * @param unit  a frequency unit.
180      * @return a string representation of frequency value and unit using metric
181      * unit system.
182      */
183     public String formatAndConvertMetric(final Number value, final FrequencyUnit unit) {
184         final var v = value.doubleValue();
185 
186         final var hertz = FrequencyConverter.convert(v, unit, FrequencyUnit.HERTZ);
187         if (Math.abs(hertz) < FrequencyConverter.HERTZS_PER_KILOHERTZ) {
188             return format(hertz, FrequencyUnit.HERTZ);
189         }
190 
191         final var kiloHertz = FrequencyConverter.convert(v, unit, FrequencyUnit.KILOHERTZ);
192         if (Math.abs(kiloHertz) < (FrequencyConverter.HERTZ_PER_MEGAHERTZ / FrequencyConverter.HERTZS_PER_KILOHERTZ)) {
193             return format(kiloHertz, FrequencyUnit.KILOHERTZ);
194         }
195 
196         final var megaHertz = FrequencyConverter.convert(v, unit, FrequencyUnit.MEGAHERTZ);
197         if (Math.abs(megaHertz) < (FrequencyConverter.HERTZ_PER_GIGAHERTZ / FrequencyConverter.HERTZ_PER_MEGAHERTZ)) {
198             return format(megaHertz, FrequencyUnit.MEGAHERTZ);
199         }
200 
201         final var gigaHertz = FrequencyConverter.convert(v, unit, FrequencyUnit.GIGAHERTZ);
202         if (Math.abs(gigaHertz) < (FrequencyConverter.HERTZ_PER_TERAHERTZ / FrequencyConverter.HERTZ_PER_GIGAHERTZ)) {
203             return format(gigaHertz, FrequencyUnit.GIGAHERTZ);
204         }
205 
206         final var teraHertz = FrequencyConverter.convert(v, unit, FrequencyUnit.TERAHERTZ);
207         return format(teraHertz, FrequencyUnit.TERAHERTZ);
208     }
209 
210     /**
211      * Returns unit string representation.
212      *
213      * @param unit a frequency unit.
214      * @return its string representation
215      */
216     @SuppressWarnings("DuplicatedCode")
217     @Override
218     public String getUnitSymbol(final FrequencyUnit unit) {
219         return switch (unit) {
220             case KILOHERTZ -> KILOHERTZ;
221             case MEGAHERTZ -> MEGAHERTZ;
222             case GIGAHERTZ -> GIGAHERTZ;
223             case TERAHERTZ -> TERAHERTZ;
224             default -> HERTZ;
225         };
226     }
227 
228     /**
229      * Returns unit system this instance will use based on its assigned locale.
230      * Notice that if no locale was assigned, then the default system locale
231      * will be used.
232      *
233      * @return unit system this instance will use.
234      */
235     @Override
236     public UnitSystem getUnitSystem() {
237         return UnitSystem.METRIC;
238     }
239 }