View Javadoc
1   /*
2    * Copyright (C) 2020 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 magnetic flux density value and unit.
23   */
24  public class MagneticFluxDensityFormatter extends MeasureFormatter<MagneticFluxDensity, MagneticFluxDensityUnit> {
25  
26      /**
27       * Nanotesla symbol.
28       */
29      public static final String NANOTESLA = "nT";
30  
31      /**
32       * Microtesla symbol.
33       */
34      public static final String MICROTESLA = "µT";
35  
36      /**
37       * Millitesla symbol.
38       */
39      public static final String MILLITESLA = "mT";
40  
41      /**
42       * Tesla symbol.
43       */
44      public static final String TESLA = "T";
45  
46      /**
47       * Kilotesla symbol.
48       */
49      public static final String KILOTESLA = "KT";
50  
51      /**
52       * Megatesla symbol.
53       */
54      public static final String MEGATESLA = "MT";
55  
56      /**
57       * Gigatesla symbol.
58       */
59      public static final String GIGATESLA = "GT";
60  
61      /**
62       * Constructor.
63       */
64      public MagneticFluxDensityFormatter() {
65          super();
66      }
67  
68      /**
69       * Constructor with locale.
70       *
71       * @param locale locale.
72       * @throws IllegalArgumentException if locale is null.
73       */
74      public MagneticFluxDensityFormatter(final Locale locale) {
75          super(locale);
76      }
77  
78      /**
79       * Copy constructor.
80       *
81       * @param formatter input instance to copy from.
82       * @throws NullPointerException if provided formatter is null.
83       */
84      public MagneticFluxDensityFormatter(final MagneticFluxDensityFormatter formatter) {
85          this(formatter.getLocale());
86      }
87  
88      /**
89       * Determines if two magnetic flux density formatters are equal by comparing all of their
90       * internal parameters.
91       *
92       * @param obj another object to compare.
93       * @return true if provided object is assumed to be equal to this instance.
94       */
95      @Override
96      public boolean equals(final Object obj) {
97          final var equals = super.equals(obj);
98          return (obj instanceof MagneticFluxDensityFormatter) && equals;
99      }
100 
101     /**
102      * Hash code generated for this instance.
103      * Hash codes can be internally used by some collections to coarsely compare objects.
104      * This implementation only calls parent implementation to avoid static analyzer warning.
105      *
106      * @return hash code.
107      */
108     @Override
109     public int hashCode() {
110         return super.hashCode();
111     }
112     
113     /**
114      * Gets unit system for detected unit into provided string representation
115      * of a measurement.
116      *
117      * @param source a measurement string representation to be checked.
118      * @return a unit system (either metric or imperial) or null if unit
119      * cannot be determined.
120      */
121     @Override
122     public UnitSystem getUnitSystem(final String source) {
123         return UnitSystem.METRIC;
124     }
125 
126     /**
127      * Parses provided string and tries to determine a magnetic flux density
128      * value and unit.
129      *
130      * @param source a string to be parsed.
131      * @return a magnetic flux density containing a value and unit.
132      * @throws ParseException       if provided string cannot be parsed.
133      * @throws UnknownUnitException if unit cannot be determined.
134      */
135     @Override
136     public MagneticFluxDensity parse(final String source) throws ParseException, UnknownUnitException {
137         return internalParse(source, new MagneticFluxDensity());
138     }
139 
140     /**
141      * Attempts to determine a magnetic flux density unit within a string
142      * representation.
143      *
144      * @param source a magnetic flux density string representation.
145      * @return a magnetic flux density unit, or null if nonce can be
146      * determined.
147      */
148     @Override
149     public MagneticFluxDensityUnit findUnit(final String source) {
150         if (source.contains(NANOTESLA + " ") || source.endsWith(NANOTESLA)) {
151             return MagneticFluxDensityUnit.NANOTESLA;
152         }
153         if (source.contains(MICROTESLA + " ") || source.endsWith(MICROTESLA)) {
154             return MagneticFluxDensityUnit.MICROTESLA;
155         }
156         if (source.contains(MILLITESLA + " ") || source.endsWith(MILLITESLA)) {
157             return MagneticFluxDensityUnit.MILLITESLA;
158         }
159         if (source.contains(KILOTESLA + " ") || source.endsWith(KILOTESLA)) {
160             return MagneticFluxDensityUnit.KILOTESLA;
161         }
162         if (source.contains(MEGATESLA + " ") || source.endsWith(MEGATESLA)) {
163             return MagneticFluxDensityUnit.MEGATESLA;
164         }
165         if (source.contains(GIGATESLA + " ") || source.endsWith(GIGATESLA)) {
166             return MagneticFluxDensityUnit.GIGATESLA;
167         }
168         if (source.contains(TESLA + " ") || source.endsWith(TESLA)) {
169             return MagneticFluxDensityUnit.TESLA;
170         }
171         return null;
172     }
173 
174     /**
175      * Formats and converts provided magnetic flux density value and unit
176      * using provided unit system.
177      * If provided value is too large for provided unit, this method will convert
178      * it to a more appropriate unit. This implementation ignores unit system.
179      *
180      * @param value  a measurement value.
181      * @param unit   a measurement unit.
182      * @param system system unit to convert measurement to (it is ignored).
183      * @return a string representation of magnetic flux density value
184      * and unit.
185      */
186     @Override
187     public String formatAndConvert(final Number value, final MagneticFluxDensityUnit unit, final UnitSystem system) {
188         return formatAndConvertMetric(value, unit);
189     }
190 
191     /**
192      * Formats and converts provided magnetic flux density value and unit
193      * using metric unit system.
194      * If provided magnetic flux density value is too large for provided
195      * magnetic flux density unit, this method will convert it to a more
196      * appropriate unit.
197      *
198      * @param value a magnetic flux density value.
199      * @param unit  a magnetic flux density unit.
200      * @return a string representation of magnetic flux density value and
201      * unit using metric unit system.
202      */
203     public String formatAndConvertMetric(final Number value, final MagneticFluxDensityUnit unit) {
204         final var v = value.doubleValue();
205 
206         final var nanoTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.NANOTESLA);
207         if (Math.abs(nanoTesla) < MagneticFluxDensityConverter.TESLAS_PER_MICROTESLA
208                 / MagneticFluxDensityConverter.TESLAS_PER_NANOTESLA) {
209             return format(nanoTesla, MagneticFluxDensityUnit.NANOTESLA);
210         }
211 
212         final var microTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.MICROTESLA);
213         if (Math.abs(microTesla) < (MagneticFluxDensityConverter.TESLAS_PER_MILLITESLA
214                 / MagneticFluxDensityConverter.TESLAS_PER_MICROTESLA)) {
215             return format(microTesla, MagneticFluxDensityUnit.MICROTESLA);
216         }
217 
218         final var milliTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.MILLITESLA);
219         if (Math.abs(milliTesla) < (1.0 / MagneticFluxDensityConverter.TESLAS_PER_MILLITESLA)) {
220             return format(milliTesla, MagneticFluxDensityUnit.MILLITESLA);
221         }
222 
223         final var tesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.TESLA);
224         if (Math.abs(tesla) < MagneticFluxDensityConverter.TESLAS_PER_KILOTESLA) {
225             return format(tesla, MagneticFluxDensityUnit.TESLA);
226         }
227 
228         final var kiloTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.KILOTESLA);
229         if (Math.abs(kiloTesla) < (MagneticFluxDensityConverter.TESLAS_PER_MEGATESLA
230                 / MagneticFluxDensityConverter.TESLAS_PER_KILOTESLA)) {
231             return format(kiloTesla, MagneticFluxDensityUnit.KILOTESLA);
232         }
233 
234         final var megaTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.MEGATESLA);
235         if (Math.abs(megaTesla) < (MagneticFluxDensityConverter.TESLAS_PER_GIGATESLA
236                 / MagneticFluxDensityConverter.TESLAS_PER_MEGATESLA)) {
237             return format(megaTesla, MagneticFluxDensityUnit.MEGATESLA);
238         }
239 
240         final var gigaTesla = MagneticFluxDensityConverter.convert(v, unit, MagneticFluxDensityUnit.GIGATESLA);
241         return format(gigaTesla, MagneticFluxDensityUnit.GIGATESLA);
242     }
243 
244     /**
245      * Returns unit string representation.
246      *
247      * @param unit a frequency unit.
248      * @return its string representation
249      */
250     @Override
251     public String getUnitSymbol(MagneticFluxDensityUnit unit) {
252         return switch (unit) {
253             case NANOTESLA -> NANOTESLA;
254             case MICROTESLA -> MICROTESLA;
255             case MILLITESLA -> MILLITESLA;
256             case KILOTESLA -> KILOTESLA;
257             case MEGATESLA -> MEGATESLA;
258             case GIGATESLA -> GIGATESLA;
259             default -> TESLA;
260         };
261     }
262 
263     /**
264      * Returns unit system this instance will use based on its assigned locale.
265      * Notice that if no locale was assigned, then the default system locale
266      * will be used.
267      *
268      * @return unit system this instance will use.
269      */
270     @Override
271     public UnitSystem getUnitSystem() {
272         return UnitSystem.METRIC;
273     }
274 }