1 package org.djunits.unit;
2
3 import java.io.Serializable;
4
5 import org.djunits.unit.quantity.Quantity;
6 import org.djunits.unit.scale.OffsetLinearScale;
7 import org.djunits.unit.scale.Scale;
8 import org.djunits.unit.si.SIPrefixes;
9 import org.djunits.unit.unitsystem.UnitSystem;
10 import org.djunits.unit.util.UnitRuntimeException;
11 import org.djutils.exceptions.Throw;
12
13
14
15
16
17
18
19
20
21
22
23
24 public abstract class AbsoluteLinearUnit<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>> extends Unit<AU>
25 implements Serializable
26 {
27
28 private static final long serialVersionUID = 20190826L;
29
30
31 private Quantity<RU> relativeQuantity;
32
33
34 private RU relativeUnit;
35
36
37
38
39
40 public Quantity<RU> getRelativeQuantity()
41 {
42 return this.relativeQuantity;
43 }
44
45
46
47
48
49 public RU getRelativeUnit()
50 {
51 return this.relativeUnit;
52 }
53
54
55 @SuppressWarnings("unchecked")
56 @Override
57 public AU build(final Unit.Builder<AU> builder) throws UnitRuntimeException
58 {
59 if (builder instanceof Builder)
60 {
61 this.relativeUnit = ((Builder<AU, RU>) builder).getRelativeUnit();
62 }
63 else
64 {
65 throw new UnitRuntimeException("Trying to build an absolute unit with a non-absolute builder");
66 }
67 Throw.whenNull(this.relativeUnit, "Relative unit for unit " + builder.getId() + " cannot be null");
68 this.relativeQuantity = this.relativeUnit.getQuantity();
69 AU unit = super.build(builder);
70 return unit;
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 @SuppressWarnings("checkstyle:parameternumber")
99 public AU deriveLinearOffset(final double scaleFactor, final double offset, final RU derivedRelativeUnit,
100 final String derivedId, final String derivedName, final UnitSystem derivedUnitSystem,
101 final String derivedDefaultDisplayAbbreviation, final String derivedDefaultTextualAbbreviation,
102 final String... derivedAbbreviations)
103 {
104 String cName = getClass().getSimpleName();
105 Throw.whenNull(derivedId, "deriving unit from %s.%s; derivedId cannot be null", cName, getId());
106 Throw.whenNull(derivedName, "deriving unit from %s.%s; derivedName cannot be null", cName, getId());
107 Throw.whenNull(derivedUnitSystem, "deriving unit from %s.%s; derivedUnitSystem cannot be null", cName, getId());
108 if (getScale().getOffsetToStandardUnit() != 0.0 || getScale().getConversionFactorToStandardUnit() != 1.0)
109 {
110 throw new UnitRuntimeException("Cannot derive from unit " + cName + "." + getId() + " with scale " + getScale()
111 + ". Scale should have no offset, and scale factor 1.0");
112 }
113
114 try
115 {
116 AU clone = clone();
117
118
119 Builder<AU, RU> builder = makeBuilder();
120 builder.setId(derivedId);
121 builder.setName(derivedName);
122 builder.setRelativeUnit(derivedRelativeUnit);
123 builder.setQuantity(getQuantity());
124 builder.setSiPrefixes(SIPrefixes.NONE, 1.0);
125 builder.setScale(new OffsetLinearScale(scaleFactor, offset));
126 builder.setUnitSystem(derivedUnitSystem);
127 builder.setDefaultDisplayAbbreviation(derivedDefaultDisplayAbbreviation);
128 builder.setDefaultTextualAbbreviation(derivedDefaultTextualAbbreviation);
129 if (derivedAbbreviations != null)
130 {
131 builder.setAdditionalAbbreviations(derivedAbbreviations);
132 }
133
134 return clone.build(builder);
135 }
136 catch (CloneNotSupportedException exception)
137 {
138 throw new UnitRuntimeException(exception);
139 }
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153
154 public AU deriveLinearOffset(final double scaleFactor, final double offset, final RU derivedRelativeUnit,
155 final String derivedId, final String derivedName, final UnitSystem derivedUnitSystem)
156 {
157 return deriveLinearOffset(scaleFactor, offset, derivedRelativeUnit, derivedId, derivedName, derivedUnitSystem, null,
158 null);
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172 public AU deriveLinearOffset(final double scaleFactor, final double offset, final RU derivedRelativeUnit,
173 final String derivedId, final String derivedName)
174 {
175 return deriveLinearOffset(scaleFactor, offset, derivedRelativeUnit, derivedId, derivedName, getUnitSystem());
176 }
177
178
179 @Override
180 public Builder<AU, RU> makeBuilder()
181 {
182 Builder<AU, RU> builder = new Builder<AU, RU>();
183 builder.setRelativeUnit(getRelativeUnit());
184 return builder;
185 }
186
187
188 @Override
189 public OffsetLinearScale getScale()
190 {
191 return (OffsetLinearScale) super.getScale();
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public static class Builder<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>> extends Unit.Builder<AU>
207 {
208
209 private static final long serialVersionUID = 20191018L;
210
211
212 private RU relativeUnit;
213
214
215 @Override
216 public OffsetLinearScale getScale()
217 {
218 return (OffsetLinearScale) super.getScale();
219 }
220
221
222 @Override
223 public Builder<AU, RU> setScale(final Scale scale)
224 {
225 Throw.when(!(scale instanceof OffsetLinearScale), UnitRuntimeException.class,
226 "scale for an absolute unit (id=" + getId() + ") should be an offset scale");
227 super.setScale(scale);
228 return this;
229 }
230
231
232
233
234
235 public RU getRelativeUnit()
236 {
237 return this.relativeUnit;
238 }
239
240
241
242
243
244
245 public Builder<AU, RU> setRelativeUnit(final RU newRelativeUnit)
246 {
247 Throw.whenNull(newRelativeUnit, "Relative unit for unit id " + getId() + " cannot be null");
248 this.relativeUnit = newRelativeUnit;
249 return this;
250 }
251
252
253
254
255 @Override
256 public Builder<AU, RU> setSiPrefixes(final SIPrefixes siPrefixes, final double power)
257 {
258 super.setSiPrefixes(siPrefixes, power);
259 return this;
260 }
261
262
263 @Override
264 public Builder<AU, RU> setId(final String id)
265 {
266 super.setId(id);
267 return this;
268 }
269
270
271 @Override
272 public Builder<AU, RU> setAdditionalAbbreviations(final String... abbreviations)
273 {
274 super.setAdditionalAbbreviations(abbreviations);
275 return this;
276 }
277
278
279 @Override
280 public Builder<AU, RU> setDefaultDisplayAbbreviation(final String defaultDisplayAbbreviation)
281 {
282 super.setDefaultDisplayAbbreviation(defaultDisplayAbbreviation);
283 return this;
284 }
285
286
287 @Override
288 public Builder<AU, RU> setDefaultTextualAbbreviation(final String defaultTextualAbbreviation)
289 {
290 super.setDefaultTextualAbbreviation(defaultTextualAbbreviation);
291 return this;
292 }
293
294
295 @Override
296 public Builder<AU, RU> setName(final String name)
297 {
298 super.setName(name);
299 return this;
300 }
301
302
303 @Override
304 public Builder<AU, RU> setUnitSystem(final UnitSystem unitSystem)
305 {
306 super.setUnitSystem(unitSystem);
307 return this;
308 }
309
310
311 @Override
312 public Builder<AU, RU> setGenerated(final boolean generated)
313 {
314 super.setGenerated(generated);
315 return this;
316 }
317
318
319 @Override
320 public Builder<AU, RU> setQuantity(final Quantity<AU> baseUnit)
321 {
322 super.setQuantity(baseUnit);
323 return this;
324 }
325
326
327 @Override
328 public String toString()
329 {
330 return "Builder [relativeUnit=" + this.relativeUnit + ", getId()=" + this.getId() + ", getName()=" + this.getName()
331 + ", getQuantity()=" + this.getQuantity() + "]";
332 }
333
334 }
335
336 }