Skip to content

Package: ELArithmetic$DoubleDelegate

ELArithmetic$DoubleDelegate

nameinstructionbranchcomplexitylinemethod
ELArithmetic.DoubleDelegate()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
add(Number, Number)
M: 31 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
coerce(Number)
M: 18 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
coerce(String)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
divide(Number, Number)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
matches(Object, Object)
M: 50 C: 0
0%
M: 28 C: 0
0%
M: 15 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
mod(Number, Number)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
multiply(Number, Number)
M: 31 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
subtract(Number, Number)
M: 31 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package com.sun.el.lang;
18:
19: import static java.math.BigDecimal.ROUND_HALF_UP;
20:
21: import java.math.BigDecimal;
22: import java.math.BigInteger;
23:
24: import com.sun.el.util.MessageFactory;
25:
26: /**
27: * A helper class of Arithmetic defined by the Jakarta Expression Specification
28: *
29: * @author Jacob Hookom [jacob@hookom.net]
30: * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: kchung $
31: */
32: public abstract class ELArithmetic {
33:
34: public final static class BigDecimalDelegate extends ELArithmetic {
35:
36: @Override
37: protected Number add(Number num0, Number num1) {
38: return ((BigDecimal) num0).add((BigDecimal) num1);
39: }
40:
41: @Override
42: protected Number coerce(Number num) {
43: if (num instanceof BigDecimal) {
44: return num;
45: }
46: if (num instanceof BigInteger) {
47: return new BigDecimal((BigInteger) num);
48: }
49:
50: return new BigDecimal(num.doubleValue());
51: }
52:
53: @Override
54: protected Number coerce(String str) {
55: return new BigDecimal(str);
56: }
57:
58: @Override
59: protected Number divide(Number num0, Number num1) {
60: return ((BigDecimal) num0).divide((BigDecimal) num1, ROUND_HALF_UP);
61: }
62:
63: @Override
64: protected Number subtract(Number num0, Number num1) {
65: return ((BigDecimal) num0).subtract((BigDecimal) num1);
66: }
67:
68: @Override
69: protected Number mod(Number num0, Number num1) {
70: return Double.valueOf(num0.doubleValue() % num1.doubleValue());
71: }
72:
73: @Override
74: protected Number multiply(Number num0, Number num1) {
75: return ((BigDecimal) num0).multiply((BigDecimal) num1);
76: }
77:
78: @Override
79: public boolean matches(Object obj0, Object obj1) {
80: return (obj0 instanceof BigDecimal || obj1 instanceof BigDecimal);
81: }
82: }
83:
84: public final static class BigIntegerDelegate extends ELArithmetic {
85:
86: @Override
87: protected Number add(Number num0, Number num1) {
88: return ((BigInteger) num0).add((BigInteger) num1);
89: }
90:
91: @Override
92: protected Number coerce(Number num) {
93: if (num instanceof BigInteger) {
94: return num;
95: }
96:
97: return new BigInteger(num.toString());
98: }
99:
100: @Override
101: protected Number coerce(String str) {
102: return new BigInteger(str);
103: }
104:
105: @Override
106: protected Number divide(Number num0, Number num1) {
107: return (new BigDecimal((BigInteger) num0)).divide(new BigDecimal((BigInteger) num1), ROUND_HALF_UP);
108: }
109:
110: @Override
111: protected Number multiply(Number num0, Number num1) {
112: return ((BigInteger) num0).multiply((BigInteger) num1);
113: }
114:
115: @Override
116: protected Number mod(Number num0, Number num1) {
117: return ((BigInteger) num0).mod((BigInteger) num1);
118: }
119:
120: @Override
121: protected Number subtract(Number num0, Number num1) {
122: return ((BigInteger) num0).subtract((BigInteger) num1);
123: }
124:
125: @Override
126: public boolean matches(Object obj0, Object obj1) {
127: return obj0 instanceof BigInteger || obj1 instanceof BigInteger;
128: }
129: }
130:
131: public final static class DoubleDelegate extends ELArithmetic {
132:
133: @Override
134: protected Number add(Number num0, Number num1) {
135: // could only be one of these
136:• if (num0 instanceof BigDecimal) {
137: return ((BigDecimal) num0).add(new BigDecimal(num1.doubleValue()));
138: }
139:• if (num1 instanceof BigDecimal) {
140: return ((new BigDecimal(num0.doubleValue()).add((BigDecimal) num1)));
141: }
142:
143: return Double.valueOf(num0.doubleValue() + num1.doubleValue());
144: }
145:
146: @Override
147: protected Number coerce(Number num) {
148:• if (num instanceof Double) {
149: return num;
150: }
151:• if (num instanceof BigInteger) {
152: return new BigDecimal((BigInteger) num);
153: }
154:
155: return Double.valueOf(num.doubleValue());
156: }
157:
158: @Override
159: protected Number coerce(String str) {
160: return Double.valueOf(str);
161: }
162:
163: @Override
164: protected Number divide(Number num0, Number num1) {
165: return Double.valueOf(num0.doubleValue() / num1.doubleValue());
166: }
167:
168: @Override
169: protected Number mod(Number num0, Number num1) {
170: return Double.valueOf(num0.doubleValue() % num1.doubleValue());
171: }
172:
173: @Override
174: protected Number subtract(Number num0, Number num1) {
175: // could only be one of these
176:• if (num0 instanceof BigDecimal) {
177: return ((BigDecimal) num0).subtract(new BigDecimal(num1.doubleValue()));
178: }
179:
180:• if (num1 instanceof BigDecimal) {
181: return ((new BigDecimal(num0.doubleValue()).subtract((BigDecimal) num1)));
182: }
183:
184: return Double.valueOf(num0.doubleValue() - num1.doubleValue());
185: }
186:
187: @Override
188: protected Number multiply(Number num0, Number num1) {
189: // could only be one of these
190:• if (num0 instanceof BigDecimal) {
191: return ((BigDecimal) num0).multiply(new BigDecimal(num1.doubleValue()));
192: }
193:• if (num1 instanceof BigDecimal) {
194: return ((new BigDecimal(num0.doubleValue()).multiply((BigDecimal) num1)));
195: }
196:
197: return Double.valueOf(num0.doubleValue() * num1.doubleValue());
198: }
199:
200: @Override
201: public boolean matches(Object obj0, Object obj1) {
202:• return (obj0 instanceof Double || obj1 instanceof Double || obj0 instanceof Float || obj1 instanceof Float
203:• || (obj0 != null && (Double.TYPE == obj0.getClass() || Float.TYPE == obj0.getClass()))
204:• || (obj1 != null && (Double.TYPE == obj1.getClass() || Float.TYPE == obj1.getClass()))
205:• || (obj0 instanceof String && ELSupport.isStringFloat((String) obj0))
206:• || (obj1 instanceof String && ELSupport.isStringFloat((String) obj1)));
207: }
208: }
209:
210: public final static class LongDelegate extends ELArithmetic {
211:
212: @Override
213: protected Number add(Number num0, Number num1) {
214: return Long.valueOf(num0.longValue() + num1.longValue());
215: }
216:
217: @Override
218: protected Number coerce(Number num) {
219: if (num instanceof Long) {
220: return num;
221: }
222:
223: return Long.valueOf(num.longValue());
224: }
225:
226: @Override
227: protected Number coerce(String str) {
228: return Long.valueOf(str);
229: }
230:
231: @Override
232: protected Number divide(Number num0, Number num1) {
233: return Long.valueOf(num0.longValue() / num1.longValue());
234: }
235:
236: @Override
237: protected Number mod(Number num0, Number num1) {
238: return Long.valueOf(num0.longValue() % num1.longValue());
239: }
240:
241: @Override
242: protected Number subtract(Number num0, Number num1) {
243: return Long.valueOf(num0.longValue() - num1.longValue());
244: }
245:
246: @Override
247: protected Number multiply(Number num0, Number num1) {
248: return Long.valueOf(num0.longValue() * num1.longValue());
249: }
250:
251: @Override
252: public boolean matches(Object obj0, Object obj1) {
253: return obj0 instanceof Long || obj1 instanceof Long;
254: }
255: }
256:
257: public static final BigDecimalDelegate BIGDECIMAL = new BigDecimalDelegate();
258: public static final BigIntegerDelegate BIGINTEGER = new BigIntegerDelegate();
259: public static final DoubleDelegate DOUBLE = new DoubleDelegate();
260: public static final LongDelegate LONG = new LongDelegate();
261: private static final Long ZERO = Long.valueOf(0);
262:
263: public final static Number add(final Object obj0, final Object obj1) {
264: if (obj0 == null && obj1 == null) {
265: return Long.valueOf(0);
266: }
267:
268: final ELArithmetic delegate;
269: if (BIGDECIMAL.matches(obj0, obj1)) {
270: delegate = BIGDECIMAL;
271: } else if (DOUBLE.matches(obj0, obj1)) {
272: delegate = DOUBLE;
273: } else if (BIGINTEGER.matches(obj0, obj1)) {
274: delegate = BIGINTEGER;
275: } else {
276: delegate = LONG;
277: }
278:
279: Number num0 = delegate.coerce(obj0);
280: Number num1 = delegate.coerce(obj1);
281:
282: return delegate.add(num0, num1);
283: }
284:
285: public final static Number mod(final Object obj0, final Object obj1) {
286: if (obj0 == null && obj1 == null) {
287: return Long.valueOf(0);
288: }
289:
290: final ELArithmetic delegate;
291: if (BIGDECIMAL.matches(obj0, obj1)) {
292: delegate = BIGDECIMAL;
293: } else if (DOUBLE.matches(obj0, obj1)) {
294: delegate = DOUBLE;
295: } else if (BIGINTEGER.matches(obj0, obj1)) {
296: delegate = BIGINTEGER;
297: } else {
298: delegate = LONG;
299: }
300:
301: Number num0 = delegate.coerce(obj0);
302: Number num1 = delegate.coerce(obj1);
303:
304: return delegate.mod(num0, num1);
305: }
306:
307: public final static Number subtract(final Object obj0, final Object obj1) {
308: if (obj0 == null && obj1 == null) {
309: return Long.valueOf(0);
310: }
311:
312: final ELArithmetic delegate;
313: if (BIGDECIMAL.matches(obj0, obj1)) {
314: delegate = BIGDECIMAL;
315: } else if (DOUBLE.matches(obj0, obj1)) {
316: delegate = DOUBLE;
317: } else if (BIGINTEGER.matches(obj0, obj1)) {
318: delegate = BIGINTEGER;
319: } else {
320: delegate = LONG;
321: }
322:
323: Number num0 = delegate.coerce(obj0);
324: Number num1 = delegate.coerce(obj1);
325:
326: return delegate.subtract(num0, num1);
327: }
328:
329: public final static Number divide(final Object obj0, final Object obj1) {
330: if (obj0 == null && obj1 == null) {
331: return ZERO;
332: }
333:
334: final ELArithmetic delegate;
335: if (BIGDECIMAL.matches(obj0, obj1)) {
336: delegate = BIGDECIMAL;
337: } else if (BIGINTEGER.matches(obj0, obj1)) {
338: delegate = BIGDECIMAL;
339: } else {
340: delegate = DOUBLE;
341: }
342:
343: Number num0 = delegate.coerce(obj0);
344: Number num1 = delegate.coerce(obj1);
345:
346: return delegate.divide(num0, num1);
347: }
348:
349: public final static Number multiply(final Object obj0, final Object obj1) {
350: if (obj0 == null && obj1 == null) {
351: return Long.valueOf(0);
352: }
353:
354: final ELArithmetic delegate;
355: if (BIGDECIMAL.matches(obj0, obj1)) {
356: delegate = BIGDECIMAL;
357: } else if (DOUBLE.matches(obj0, obj1)) {
358: delegate = DOUBLE;
359: } else if (BIGINTEGER.matches(obj0, obj1)) {
360: delegate = BIGINTEGER;
361: } else {
362: delegate = LONG;
363: }
364:
365: Number num0 = delegate.coerce(obj0);
366: Number num1 = delegate.coerce(obj1);
367:
368: return delegate.multiply(num0, num1);
369: }
370:
371: public final static boolean isNumber(final Object obj) {
372: return (obj != null && isNumberType(obj.getClass()));
373: }
374:
375: public final static boolean isNumberType(final Class type) {
376: return type == Long.TYPE || type == Double.TYPE || type == Byte.TYPE || type == Short.TYPE || type == Integer.TYPE || type == Float.TYPE
377: || Number.class.isAssignableFrom(type);
378: }
379:
380: /**
381: *
382: */
383: protected ELArithmetic() {
384: super();
385: }
386:
387: protected abstract Number add(final Number num0, final Number num1);
388:
389: protected abstract Number multiply(final Number num0, final Number num1);
390:
391: protected abstract Number subtract(final Number num0, final Number num1);
392:
393: protected abstract Number mod(final Number num0, final Number num1);
394:
395: protected abstract Number coerce(final Number num);
396:
397: protected final Number coerce(final Object obj) {
398:
399: if (isNumber(obj)) {
400: return coerce((Number) obj);
401: }
402: if (obj instanceof String) {
403: return coerce((String) obj);
404: }
405: if (obj == null || "".equals(obj)) {
406: return coerce(ZERO);
407: }
408:
409: Class objType = obj.getClass();
410: if (Character.class.equals(objType) || Character.TYPE == objType) {
411: return coerce(Short.valueOf((short) ((Character) obj).charValue()));
412: }
413:
414: throw new IllegalArgumentException(MessageFactory.get("el.convert", obj, objType));
415: }
416:
417: protected abstract Number coerce(final String str);
418:
419: protected abstract Number divide(final Number num0, final Number num1);
420:
421: protected abstract boolean matches(final Object obj0, final Object obj1);
422:
423: }