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