1 package org.djunits.formatter;
2
3 import java.util.Locale;
4
5 import org.djunits.quantity.def.AbsQuantity;
6 import org.djunits.quantity.def.Quantity;
7 import org.djunits.unit.Unit;
8 import org.djunits.unit.Units;
9 import org.djunits.unit.si.PrefixType;
10 import org.djunits.unit.si.SIPrefix;
11 import org.djunits.unit.si.SIPrefixes;
12
13
14
15
16
17
18
19
20
21
22
23
24 public class QuantityFormatter extends Formatter<QuantityFormatContext>
25 {
26
27
28
29
30 QuantityFormatter(final Quantity<?> quantity, final QuantityFormatContext ctx)
31 {
32 super(quantity, ctx);
33 }
34
35
36
37
38
39
40
41
42 public static String format(final Quantity<?> quantity, final QuantityFormat quantityFormat)
43 {
44 QuantityFormatContext ctx = quantityFormat.ctx;
45 Locale savedLocale = Locale.getDefault();
46 try
47 {
48 savedLocale = saveLocale(ctx.locale);
49 return new QuantityFormatter(quantity, ctx).format();
50 }
51 finally
52 {
53 restoreLocale(savedLocale);
54 }
55 }
56
57
58
59
60
61
62
63
64 public static String format(final AbsQuantity<?, ?, ?> absQuantity, final QuantityFormat quantityFormat)
65 {
66 QuantityFormatContext ctx = quantityFormat.ctx;
67 Locale savedLocale = Locale.getDefault();
68 try
69 {
70 savedLocale = saveLocale(ctx.locale);
71 return new QuantityFormatter(absQuantity.getQuantity(), ctx).format()
72 + formatReference(ctx, absQuantity.getReference());
73 }
74 finally
75 {
76 restoreLocale(savedLocale);
77 }
78 }
79
80
81
82
83
84 Quantity<?> quantity()
85 {
86 return (Quantity<?>) this.value;
87 }
88
89
90
91
92
93 @Override
94 String format()
95 {
96 formatUnit();
97 double value = this.useSi ? quantity().si : this.unit.getScale().fromIdentityScale(quantity().si());
98 return formatValue(value) + this.ctx.unitPrefix + this.unitStr + this.ctx.unitPostfix;
99 }
100
101
102
103
104 @SuppressWarnings("checkstyle:needbraces")
105 @Override
106 void formatUnit()
107 {
108 boolean formatted = checkSiUnits();
109 if (!formatted)
110 formatted = checkUnitString();
111 if (!formatted)
112 formatted = checkDisplayUnit();
113 checkScaleSiPrefixes();
114 if (this.unitStr == null)
115 this.unitStr = this.ctx.textual ? this.unit.getTextualAbbreviation() : this.unit.getDisplayAbbreviation();
116 }
117
118
119
120
121
122
123 @SuppressWarnings("unchecked")
124 private <Q extends Quantity<Q>> boolean checkScaleSiPrefixes()
125 {
126 Q q = (Q) quantity();
127 if (this.ctx.scaleSiPrefixes && this.unit.getSiPrefix() != null)
128 {
129 PrefixType type = this.unit.getSiPrefix().getType();
130 double si = q.si();
131 double log10si = Math.log10(si);
132 int power = log10si > 0 ? 3 * (int) (Math.log10(si) / 3.0) : 3 * (int) (Math.log10(si) / 3.0 - 1);
133 if (power >= this.ctx.minimumPrefixPower && power <= this.ctx.maximumPrefixPower)
134 {
135 switch (type)
136 {
137 case UNIT:
138 {
139 SIPrefix prefix = SIPrefixes.FACTORS.getOrDefault(power, SIPrefixes.getSiPrefix(""));
140 String key = prefix.getDefaultTextualPrefix() + q.getDisplayUnit().getBaseUnit().getId();
141 this.unit = (Unit<?, Q>) Units.resolve(q.getDisplayUnit().getClass(), key);
142 return true;
143 }
144 case KILO:
145 {
146 power += 3;
147 SIPrefix prefix = SIPrefixes.FACTORS.getOrDefault(power, SIPrefixes.getSiPrefix(""));
148 String key = prefix.getDefaultTextualPrefix() + q.getDisplayUnit().getBaseUnit().getId().substring(1);
149 this.unit = (Unit<?, Q>) Units.resolve(q.getDisplayUnit().getClass(), key);
150 return true;
151 }
152 case PER_UNIT:
153 {
154 SIPrefix prefix = SIPrefixes.FACTORS.getOrDefault(-power, SIPrefixes.getSiPrefix(""));
155 String key =
156 "/" + prefix.getDefaultTextualPrefix() + q.getDisplayUnit().getBaseUnit().getId().substring(1);
157 this.unit = (Unit<?, Q>) Units.resolve(q.getDisplayUnit().getClass(), key);
158 return true;
159 }
160 case PER_KILO:
161 {
162 power -= 3;
163 SIPrefix prefix = SIPrefixes.FACTORS.getOrDefault(-power, SIPrefixes.getSiPrefix(""));
164 String key =
165 "/" + prefix.getDefaultTextualPrefix() + q.getDisplayUnit().getBaseUnit().getId().substring(2);
166 this.unit = (Unit<?, Q>) Units.resolve(q.getDisplayUnit().getClass(), key);
167 return true;
168 }
169 default:
170
171 }
172 }
173 }
174 return false;
175 }
176
177 }