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
17 package com.irurueta.units;
18
19 import java.text.ParseException;
20 import java.util.Locale;
21
22 /**
23 * Formats and parses acceleration value and unit.
24 */
25 public class AccelerationFormatter extends MeasureFormatter<Acceleration, AccelerationUnit> {
26
27 /**
28 * Meters per squared second symbol.
29 */
30 public static final String METERS_PER_SQUARED_SECOND = "m/s²";
31
32 /**
33 * Standard gravity symbol.
34 */
35 public static final String G = "g₀";
36
37 /**
38 * Feet per squared second symbol.
39 */
40 public static final String FEET_PER_SQUARED_SECOND = "ft/s²";
41
42 /**
43 * Constructor.
44 */
45 public AccelerationFormatter() {
46 super();
47 }
48
49 /**
50 * Constructor with locale.
51 *
52 * @param locale locale.
53 * @throws IllegalArgumentException if locale is null.
54 */
55 public AccelerationFormatter(final Locale locale) {
56 super(locale);
57 }
58
59 /**
60 * Copy constructor.
61 *
62 * @param formatter input instance to copy from.
63 * @throws NullPointerException if provided formatter is null.
64 */
65 public AccelerationFormatter(final AccelerationFormatter formatter) {
66 this(formatter.getLocale());
67 }
68
69 /**
70 * Determines if two acceleration formatters are equal by comparing all of their internal parameters.
71 *
72 * @param obj another object to compare.
73 * @return true if provided object is assumed to be equal to this instance.
74 */
75 @Override
76 public boolean equals(final Object obj) {
77 final var equals = super.equals(obj);
78 return (obj instanceof AccelerationFormatter) && equals;
79 }
80
81 /**
82 * Hash code generated for this instance. Hash codes can be internally used by some collections to coarsely
83 * compare objects. This implementation only calls parent implementation to avoid static analyzer warning.
84 *
85 * @return hash code.
86 */
87 @Override
88 public int hashCode() {
89 return super.hashCode();
90 }
91
92 /**
93 * Gets unit system for detected unit into provided string representation of a measurement.
94 *
95 * @param source a measurement string representation to be checked.
96 * @return a unit system (either metric or imperial) or null if unit cannot be determined.
97 */
98 public UnitSystem getUnitSystem(final String source) {
99 final var unit = findUnit(source);
100 return unit != null ? AccelerationUnit.getUnitSystem(unit) : null;
101 }
102
103 /**
104 * Parses provided string and tries to determine acceleration value and unit.
105 *
106 * @param source a string to be parsed.
107 * @return an acceleration containing a value and unit.
108 * @throws ParseException if provided string cannot be parsed.
109 * @throws UnknownUnitException if unit cannot be determined.
110 */
111 @Override
112 public Acceleration parse(final String source) throws ParseException, UnknownUnitException {
113 return internalParse(source, new Acceleration());
114 }
115
116 /**
117 * Attempts to determine an acceleration unit within a measurement string representation.
118 *
119 * @param source a measurement string representation.
120 * @return an acceleration unit, or null if none can be determined.
121 */
122 @Override
123 public AccelerationUnit findUnit(final String source) {
124 if (source.contains(METERS_PER_SQUARED_SECOND + " ") || source.endsWith(METERS_PER_SQUARED_SECOND)) {
125 return AccelerationUnit.METERS_PER_SQUARED_SECOND;
126 }
127 if (source.contains(G + " ") || source.endsWith(G)) {
128 return AccelerationUnit.G;
129 }
130 if (source.contains(FEET_PER_SQUARED_SECOND + " ") || source.endsWith(FEET_PER_SQUARED_SECOND)) {
131 return AccelerationUnit.FEET_PER_SQUARED_SECOND;
132 }
133 return null;
134 }
135
136 /**
137 * Formats and converts provided acceleration value and unit using provided unit system. If provided value is
138 * too large for provided unit, this method will convert it to a more appropriate unit using provided unit
139 * system (either metric or imperial).
140 *
141 * @param value an acceleration value.
142 * @param unit an acceleration unit.
143 * @param system system unit to convert measurement to.
144 * @return a string representation of acceleration value and unit.
145 */
146 public String formatAndConvert(
147 final Number value, final AccelerationUnit unit, final UnitSystem system) {
148 if (system == UnitSystem.IMPERIAL) {
149 return formatAndConvertImperial(value, unit);
150 } else {
151 return formatAndConvertMetric(value, unit);
152 }
153 }
154
155 /**
156 * Formats and converts provided acceleration value and unit using metric unit system.
157 *
158 * @param value an acceleration value.
159 * @param unit an acceleration unit.
160 * @return a string representation of acceleration value and unit using metric unit system.
161 */
162 public String formatAndConvertMetric(final Number value, final AccelerationUnit unit) {
163 //always format as meters per squared second
164 return format(AccelerationConverter.convert(value, unit, AccelerationUnit.METERS_PER_SQUARED_SECOND),
165 AccelerationUnit.METERS_PER_SQUARED_SECOND);
166 }
167
168 /**
169 * Formats and converts provided acceleration value and unit using imperial unit system.
170 *
171 * @param value an acceleration value.
172 * @param unit an acceleration unit.
173 * @return a string representation of acceleration value and unit using imperial unit system.
174 */
175 public String formatAndConvertImperial(final Number value, final AccelerationUnit unit) {
176 //always format as feet per squared second
177 return format(AccelerationConverter.convert(value, unit, AccelerationUnit.FEET_PER_SQUARED_SECOND),
178 AccelerationUnit.FEET_PER_SQUARED_SECOND);
179 }
180
181 /**
182 * Returns unit string representation.
183 *
184 * @param unit an acceleration unit.
185 * @return its string representation.
186 */
187 @Override
188 public String getUnitSymbol(final AccelerationUnit unit) {
189 return switch (unit) {
190 case FEET_PER_SQUARED_SECOND -> FEET_PER_SQUARED_SECOND;
191 case G -> G;
192 default -> METERS_PER_SQUARED_SECOND;
193 };
194 }
195 }