1 package org.djunits.unit;
2
3 import java.util.Objects;
4
5 import org.djunits.quantity.def.Quantity;
6 import org.djunits.unit.scale.Scale;
7 import org.djunits.unit.si.SIPrefix;
8 import org.djunits.unit.si.SIPrefixes;
9 import org.djunits.unit.system.UnitSystem;
10 import org.djutils.exceptions.Throw;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public abstract class AbstractUnit<U extends UnitInterface<U, Q>, Q extends Quantity<Q, U>> implements UnitInterface<U, Q>
29 {
30
31 private final String textualAbbreviation;
32
33
34 private final String displayAbbreviation;
35
36
37 private final String name;
38
39
40 private final Scale scale;
41
42
43 private final UnitSystem unitSystem;
44
45
46 private SIPrefix siPrefix = null;
47
48
49
50
51
52
53
54
55 public AbstractUnit(final String textualAbbreviation, final String name, final Scale scale, final UnitSystem unitSystem)
56 {
57 this(textualAbbreviation, textualAbbreviation, name, scale, unitSystem);
58 }
59
60
61
62
63
64
65
66
67
68 public AbstractUnit(final String textualAbbreviation, final String displayAbbreviation, final String name,
69 final Scale scale, final UnitSystem unitSystem)
70 {
71
72 String cName = Units.unitClassName(getClass());
73 Throw.whenNull(textualAbbreviation, "Constructing unit %s: textualAbbreviation cannot be null", cName);
74 Throw.whenNull(displayAbbreviation, "Constructing unit %s: displayAbbreviation cannot be null", cName);
75 Throw.when(textualAbbreviation.length() == 0, UnitRuntimeException.class,
76 "Constructing unit %s: textualAbbreviation string cannot be empty", cName);
77 Throw.whenNull(name, "Constructing unit %s.%s: name cannot be null", cName, textualAbbreviation);
78 Throw.when(name.length() == 0, UnitRuntimeException.class, "Constructing unit %s.%s: name.length cannot be 0", cName,
79 textualAbbreviation);
80 Throw.whenNull(scale, "Constructing unit %s.%s: scale cannot be null", cName, textualAbbreviation);
81 Throw.whenNull(unitSystem, "Constructing unit %s.%s: unitSystem cannot be null", cName, textualAbbreviation);
82
83
84 this.displayAbbreviation = displayAbbreviation;
85 this.textualAbbreviation = textualAbbreviation;
86 this.name = name;
87 this.scale = scale;
88 this.unitSystem = unitSystem;
89
90
91 Units.register(this);
92 }
93
94
95
96
97
98
99
100 @SuppressWarnings("unchecked")
101 public U generateSiPrefixes(final boolean kilo, final boolean perUnit)
102 {
103 String cName = getClass().getSimpleName();
104 Throw.when(!getScale().isBaseScale(), UnitRuntimeException.class,
105 "SI prefixes generation for unit %s only applicable to unit with base scale", cName);
106 Throw.when(kilo && !perUnit && !getId().startsWith("k"), UnitRuntimeException.class,
107 "SI prefixes generated for kilo class for unit %s, but abbreviation %s does not start with a 'k'", cName,
108 getId());
109 Throw.when(kilo && perUnit && !getId().startsWith("/k"), UnitRuntimeException.class,
110 "SI prefixes generated for per-kilo class for unit %s, but abbreviation %s does not start with '/k'", cName,
111 getId());
112 Throw.when(kilo && !perUnit && !getStoredName().startsWith("kilo"), UnitRuntimeException.class,
113 "SI prefixes generated for kilo class for unit %s, but name %s does not start with 'kilo'", cName,
114 getStoredName());
115 Throw.when(kilo && perUnit && !getStoredName().startsWith("per kilo"), UnitRuntimeException.class,
116 "SI prefixes generated for kilo class for unit %s, but name %s does not start with 'per kilo'", cName,
117 getStoredName());
118 Throw.when(perUnit && !getId().startsWith("/"), UnitRuntimeException.class,
119 "SI prefixes generated for 'per' class for unit %s, but abbreviation %s does not start with '/'", cName,
120 getId());
121 Throw.when(perUnit && !getStoredName().startsWith("per "), UnitRuntimeException.class,
122 "SI prefixes generated for 'per' class for unit %s, but name %s does not start with 'per '", cName,
123 getStoredName());
124
125 if (!kilo)
126 {
127 if (!perUnit)
128 {
129 for (SIPrefix sip : SIPrefixes.UNIT_PREFIXES.values())
130 {
131 U unit = deriveUnit(sip.getDefaultTextualPrefix() + getStoredTextualAbbreviation(),
132 sip.getDefaultDisplayPrefix() + getStoredDisplayAbbreviation(),
133 sip.getPrefixName() + getStoredName(), sip.getFactor(), getUnitSystem());
134 unit.setSiPrefix(sip);
135 }
136 }
137 else
138 {
139 for (SIPrefix sip : SIPrefixes.PER_UNIT_PREFIXES.values())
140 {
141 U unit = deriveUnit(sip.getDefaultTextualPrefix() + getStoredTextualAbbreviation().substring(1),
142 sip.getDefaultDisplayPrefix() + getStoredDisplayAbbreviation().substring(1),
143 sip.getPrefixName() + getStoredName().substring(4), sip.getFactor(), getUnitSystem());
144 unit.setSiPrefix(sip);
145 }
146 }
147 }
148 else
149 {
150 if (!perUnit)
151 {
152 for (SIPrefix sip : SIPrefixes.KILO_PREFIXES.values())
153 {
154 U unit = deriveUnit(sip.getDefaultTextualPrefix() + getStoredTextualAbbreviation().substring(1),
155 sip.getDefaultDisplayPrefix() + getStoredDisplayAbbreviation().substring(1),
156 sip.getPrefixName() + getStoredName().substring(4), sip.getFactor(), getUnitSystem());
157 unit.setSiPrefix(sip);
158 }
159 }
160 else
161 {
162 for (SIPrefix sip : SIPrefixes.PER_KILO_PREFIXES.values())
163 {
164 U unit = deriveUnit(sip.getDefaultTextualPrefix() + getStoredTextualAbbreviation().substring(2),
165 sip.getDefaultDisplayPrefix() + getStoredDisplayAbbreviation().substring(2),
166 sip.getPrefixName() + getStoredName().substring(8), sip.getFactor(), getUnitSystem());
167 unit.setSiPrefix(sip);
168 }
169 }
170 }
171 return (U) this;
172 }
173
174
175
176
177
178
179
180
181
182
183 @SuppressWarnings("checkstyle:hiddenfield")
184 public U deriveUnit(final String textualAbbreviation, final String name, final double scaleFactor,
185 final UnitSystem unitSystem)
186 {
187 return deriveUnit(textualAbbreviation, textualAbbreviation, name, scaleFactor, unitSystem);
188 }
189
190
191
192
193
194
195
196
197
198
199 @SuppressWarnings("checkstyle:hiddenfield")
200 public abstract U deriveUnit(String textualAbbreviation, String displayAbbreviation, String name, double scaleFactor,
201 UnitSystem unitSystem);
202
203 @Override
204 public String getId()
205 {
206 return this.textualAbbreviation;
207 }
208
209 @Override
210 public String getStoredTextualAbbreviation()
211 {
212 return this.textualAbbreviation;
213 }
214
215 @Override
216 public String getTextualAbbreviation()
217 {
218 return Units.localizedUnitTextualAbbr(getClass(), getId());
219 }
220
221 @Override
222 public String getStoredDisplayAbbreviation()
223 {
224 return this.displayAbbreviation;
225 }
226
227 @Override
228 public String getDisplayAbbreviation()
229 {
230 return Units.localizedUnitDisplayAbbr(getClass(), getId());
231 }
232
233 @Override
234 public String getStoredName()
235 {
236 return this.name;
237 }
238
239 @Override
240 public String getName()
241 {
242 return Units.localizedUnitName(getClass(), getId());
243 }
244
245 @Override
246 public Scale getScale()
247 {
248 return this.scale;
249 }
250
251 @Override
252 public UnitSystem getUnitSystem()
253 {
254 return this.unitSystem;
255 }
256
257 @SuppressWarnings({"unchecked", "hiddenfield"})
258 @Override
259 public U setSiPrefix(final SIPrefix siPrefix)
260 {
261 this.siPrefix = siPrefix;
262 return (U) this;
263 }
264
265 @Override
266 public U setSiPrefix(final String prefix)
267 {
268 SIPrefix sip = SIPrefixes.getSiPrefix(prefix);
269 return setSiPrefix(sip);
270 }
271
272 @Override
273 public U setSiPrefixKilo(final String prefix)
274 {
275 SIPrefix sip = SIPrefixes.getSiPrefixKilo(prefix);
276 return setSiPrefix(sip);
277 }
278
279 @Override
280 public U setSiPrefixPer(final String prefix)
281 {
282 SIPrefix sip = SIPrefixes.getSiPrefixPer(prefix);
283 return setSiPrefix(sip);
284 }
285
286 @Override
287 public SIPrefix getSiPrefix()
288 {
289 return this.siPrefix;
290 }
291
292 @Override
293 public int hashCode()
294 {
295 return Objects.hash(this.displayAbbreviation, this.name, this.scale, this.textualAbbreviation, this.unitSystem);
296 }
297
298 @Override
299 @SuppressWarnings("checkstyle:needbraces")
300 public boolean equals(final Object obj)
301 {
302 if (this == obj)
303 return true;
304 if (obj == null)
305 return false;
306 if (getClass() != obj.getClass())
307 return false;
308 AbstractUnit<?, ?> other = (AbstractUnit<?, ?>) obj;
309 return Objects.equals(this.displayAbbreviation, other.displayAbbreviation) && Objects.equals(this.name, other.name)
310 && Objects.equals(this.scale, other.scale)
311 && Objects.equals(this.textualAbbreviation, other.textualAbbreviation)
312 && Objects.equals(this.unitSystem, other.unitSystem);
313 }
314
315 @Override
316 public String toString()
317 {
318 return this.displayAbbreviation;
319 }
320 }