1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.layout;
21
22 import org.apache.myfaces.tobago.internal.util.StringUtils;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import java.io.Serializable;
27 import java.lang.invoke.MethodHandles;
28
29
30
31
32 public final class Measure implements Serializable {
33
34 private static final long serialVersionUID = 1L;
35
36 private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
37
38 public static final Measure ZERO = valueOf(0);
39 public static final Measure AUTO = valueOf("auto");
40 public static final Measure FRACTION1 = valueOf("1fr");
41
42 private final float value;
43 private final Unit unit;
44
45 private Measure() {
46 this.value = 0;
47 this.unit = Unit.AUTO;
48 }
49
50 public Measure(final int i, final Unit unit) {
51 this.value = i;
52 this.unit = unit;
53 }
54
55 public Measure(final double d, final Unit unit) {
56 this.value = (float) d;
57 this.unit = unit;
58 }
59
60 public Measure(final String string, final Unit unit) {
61 this.value = Float.parseFloat(string);
62 this.unit = unit;
63 }
64
65 public static Measure valueOf(final Measure measure) {
66 if (measure == null) {
67 return ZERO;
68 }
69 return measure;
70 }
71
72 public static Measure valueOf(final int value) {
73 return new Measure(value, Unit.PX);
74 }
75
76 public static Measure valueOf(final Integer i) {
77 if (i == null) {
78 return ZERO;
79 }
80 return valueOf(i.intValue());
81 }
82
83 public static Measure valueOf(final Number n) {
84 if (n == null) {
85 return ZERO;
86 }
87 return valueOf(n.doubleValue());
88 }
89
90 public static Measure valueOf(final String s) {
91 return valueOf(s, Unit.PX);
92 }
93
94 public static Measure valueOf(final String s, final Unit defaultUnit) {
95 try {
96 if (StringUtils.isEmpty(s)) {
97 return null;
98 }
99 final int length = s.length();
100 if (s.endsWith("%")) {
101 return new Measure(s.substring(0, length - 1), Unit.PERCENT);
102 }
103 if (s.endsWith("*")) {
104 if (s.length() == 1) {
105 return new Measure(1, Unit.FR);
106 } else {
107 return new Measure(s.substring(0, length - 1), Unit.FR);
108 }
109 }
110 if (s.equals("auto")) {
111 return new Measure();
112 }
113 for (int i = 4; i >= 2; i--) {
114 final int pos = length - i;
115 if (length >= i && Character.isLetter(s.charAt(pos))) {
116 return new Measure(s.substring(0, pos), Unit.valueOf(s.substring(pos).toUpperCase()));
117 }
118 }
119 return new Measure(s, defaultUnit);
120
121 } catch (final RuntimeException e) {
122 LOG.warn("Can't parse to any measure: '" + s + "'");
123 }
124 return null;
125 }
126
127 public static Measure valueOf(final Object object) {
128 if (object == null) {
129 return null;
130 }
131 if (object instanceof Measure) {
132 return valueOf((Measure) object);
133 }
134 if (object instanceof Number) {
135 return valueOf((Number) object);
136 }
137 if (object instanceof String) {
138 return valueOf((String) object);
139 }
140 return valueOf(object.toString());
141 }
142
143 public String serialize() {
144 final StringBuilder builder = new StringBuilder();
145 if (unit != Unit.AUTO) {
146 builder.append(value);
147 }
148 final int length = builder.length();
149 if (length >= 3 && builder.charAt(length - 1) == '0' && builder.charAt(length - 2) == '.') {
150 builder.deleteCharAt(length - 1);
151 builder.deleteCharAt(length - 2);
152 }
153 builder.append(unit.getValue());
154 return builder.toString();
155 }
156
157 public float getValue() {
158 return value;
159 }
160
161 public Unit getUnit() {
162 return unit;
163 }
164
165 public String toString() {
166 return serialize();
167 }
168
169 @Override
170 public boolean equals(final Object o) {
171 if (this == o) {
172 return true;
173 }
174 if (o == null || getClass() != o.getClass()) {
175 return false;
176 }
177
178 final Measure measure = (Measure) o;
179
180 if (Float.compare(measure.value, value) != 0) {
181 return false;
182 }
183 return unit == measure.unit;
184 }
185
186 @Override
187 public int hashCode() {
188 int result = value != +0.0f ? Float.floatToIntBits(value) : 0;
189 result = 31 * result + unit.hashCode();
190 return result;
191 }
192
193 public enum Unit {
194
195 EM,
196 PX,
197 EX,
198 PT,
199 CM,
200 MM,
201 IN,
202 PC,
203 CH,
204 REM,
205 VW,
206 VH,
207 VMIN,
208 VMAX,
209 PERCENT,
210 FR,
211 SEG,
212 AUTO;
213
214 private final String value;
215
216 Unit() {
217 value = name().equals("PERCENT") ? "%" : name().toLowerCase();
218 }
219
220 String getValue() {
221 return value;
222 }
223 }
224 }