1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.peaseplate.internal.lang.command;
21
22 import java.math.BigDecimal;
23 import java.math.BigInteger;
24
25 import org.peaseplate.TemplateRuntimeException;
26 import org.peaseplate.internal.BuildContext;
27 import org.peaseplate.internal.conversion.ConversionException;
28 import org.peaseplate.locator.TemplateLocator;
29 import org.peaseplate.service.ConversionService;
30
31 public abstract class AbstractNumericCommand extends AbstractDoubleParameterCommand {
32
33 public AbstractNumericCommand(TemplateLocator locator, int line, int column, ICommand leftCommand, ICommand rightCommand) {
34 super(locator, line, column, leftCommand, rightCommand);
35 }
36
37 public abstract String getSign();
38
39 public Object call(BuildContext context) throws TemplateRuntimeException {
40 Object result = null;
41 ConversionService conversionService = context.getEngine().getConversionService();
42 Object left = callLeftCommand(context);
43 Object right = callRightCommand(context);
44 Class<?> leftType = (left != null) ? left.getClass() : Void.class;
45 Class<?> rightType = (right != null) ? right.getClass() : Void.class;
46
47 try {
48 if ((leftType == StringBuilder.class) || (rightType == StringBuilder.class))
49 result = calculate(
50 conversionService.convey(left, StringBuilder.class),
51 conversionService.convey(right, StringBuilder.class)
52 );
53
54 else if ((leftType == StringBuffer.class) || (rightType == StringBuffer.class))
55 result = calculate(
56 conversionService.convey(left, StringBuffer.class),
57 conversionService.convey(right, StringBuffer.class)
58 );
59
60 else if ((leftType == String.class) || (rightType == String.class))
61 result = calculate(
62 conversionService.convey(left, String.class),
63 conversionService.convey(right, String.class)
64 );
65
66 else if ((leftType == BigDecimal.class) || (rightType == BigDecimal.class))
67 result = calculate(
68 conversionService.convey(left, BigDecimal.class),
69 conversionService.convey(right, BigDecimal.class)
70 );
71
72 else if ((leftType == BigInteger.class) || (rightType == BigInteger.class))
73 result = calculate(
74 conversionService.convey(left, BigInteger.class),
75 conversionService.convey(right, BigInteger.class)
76 );
77
78 else if (
79 (leftType == double.class) || (leftType == Double.class) ||
80 (rightType == double.class) || (rightType == Double.class)
81 )
82 result = calculate(
83 conversionService.convey(left, Double.class),
84 conversionService.convey(right, Double.class)
85 );
86
87 else if (
88 (leftType == float.class) || (leftType == Float.class) ||
89 (rightType == float.class) || (rightType == Float.class)
90 )
91 result = calculate(
92 conversionService.convey(left, Float.class),
93 conversionService.convey(right, Float.class)
94 );
95
96 else if (
97 (leftType == long.class) || (leftType == Long.class) ||
98 (rightType == long.class) || (rightType == Long.class)
99 )
100 result = calculate(
101 conversionService.convey(left, Long.class),
102 conversionService.convey(right, Long.class)
103 );
104
105 else if (
106 (leftType == int.class) || (leftType == Integer.class) ||
107 (rightType == int.class) || (rightType == Integer.class)
108 )
109 result = calculate(
110 conversionService.convey(left, Integer.class),
111 conversionService.convey(right, Integer.class)
112 );
113
114 else if (
115 (leftType == char.class) || (leftType == Character.class) ||
116 (rightType == char.class) || (rightType == Character.class)
117 )
118 result = calculate(
119 conversionService.convey(left, Character.class),
120 conversionService.convey(right, Character.class)
121 );
122
123 else if (
124 (leftType == short.class) || (leftType == Short.class) ||
125 (rightType == short.class) || (rightType == Short.class)
126 )
127 result = calculate(
128 conversionService.convey(left, Short.class),
129 conversionService.convey(right, Short.class)
130 );
131
132 else if (
133 (leftType == byte.class) || (leftType == Byte.class) ||
134 (rightType == byte.class) || (rightType == Byte.class)
135 )
136 result = calculate(
137 conversionService.convey(left, Byte.class),
138 conversionService.convey(right, Byte.class)
139 );
140
141 else
142 result = calculate(left, right);
143 }
144 catch (ConversionException e) {
145 if (e.getValue() == left)
146 throw new TemplateRuntimeException(
147 getLeftCommand().getLocator(), getLeftCommand().getLine(), getLeftCommand().getColumn(),
148 "Could not convert left operator to " + e.getType(), e
149 );
150
151 else if (e.getValue() == right)
152 throw new TemplateRuntimeException(
153 getRightCommand().getLocator(), getRightCommand().getLine(), getRightCommand().getColumn(),
154 "Could not convert right operator to " + e.getType(), e
155 );
156
157 else
158 throw new TemplateRuntimeException(
159 getLocator(), getLine(), getColumn(),
160 "Could not convert operator to " + e.getType(), e
161 );
162 }
163
164 return result;
165 }
166
167 public Byte calculate(Byte left, Byte right) throws TemplateRuntimeException {
168 throw new TemplateRuntimeException(
169 getLocator(), getLine(), getColumn(),
170 "Operation " + getSign() + " not supported on operands of type " + Byte.class
171 );
172 }
173
174 public Short calculate(Short left, Short right) throws TemplateRuntimeException {
175 throw new TemplateRuntimeException(
176 getLocator(), getLine(), getColumn(),
177 "Operation " + getSign() + " not supported on operands of type " + Short.class
178 );
179 }
180
181 public Character calculate(Character left, Character right) throws TemplateRuntimeException {
182 throw new TemplateRuntimeException(
183 getLocator(), getLine(), getColumn(),
184 "Operation " + getSign() + " not supported on operands of type " + Character.class
185 );
186 }
187
188 public Integer calculate(Integer left, Integer right) throws TemplateRuntimeException {
189 throw new TemplateRuntimeException(
190 getLocator(), getLine(), getColumn(),
191 "Operation " + getSign() + " not supported on operands of type " + Integer.class
192 );
193 }
194
195 public Long calculate(Long left, Long right) throws TemplateRuntimeException {
196 throw new TemplateRuntimeException(
197 getLocator(), getLine(), getColumn(),
198 "Operation " + getSign() + " not supported on operands of type " + Long.class
199 );
200 }
201
202 public Float calculate(Float left, Float right) throws TemplateRuntimeException {
203 throw new TemplateRuntimeException(
204 getLocator(), getLine(), getColumn(),
205 "Operation " + getSign() + " not supported on operands of type " + Float.class
206 );
207 }
208
209 public Double calculate(Double left, Double right) throws TemplateRuntimeException {
210 throw new TemplateRuntimeException(
211 getLocator(), getLine(), getColumn(),
212 "Operation " + getSign() + " not supported on operands of type " + Double.class
213 );
214 }
215
216 public BigInteger calculate(BigInteger left, BigInteger right) throws TemplateRuntimeException {
217 throw new TemplateRuntimeException(
218 getLocator(), getLine(), getColumn(),
219 "Operation " + getSign() + " not supported on operands of type " + BigInteger.class
220 );
221 }
222
223 public BigDecimal calculate(BigDecimal left, BigDecimal right) throws TemplateRuntimeException {
224 throw new TemplateRuntimeException(
225 getLocator(), getLine(), getColumn(),
226 "Operation " + getSign() + " not supported on operands of type " + BigDecimal.class
227 );
228 }
229
230 public String calculate(String left, String right) throws TemplateRuntimeException {
231 throw new TemplateRuntimeException(
232 getLocator(), getLine(), getColumn(),
233 "Operation " + getSign() + " not supported on operands of type " + String.class
234 );
235 }
236
237 public StringBuffer calculate(StringBuffer left, StringBuffer right) throws TemplateRuntimeException {
238 throw new TemplateRuntimeException(
239 getLocator(), getLine(), getColumn(),
240 "Operation " + getSign() + " not supported on operands of type " + StringBuffer.class
241 );
242 }
243
244 public StringBuilder calculate(StringBuilder left, StringBuilder right) throws TemplateRuntimeException {
245 throw new TemplateRuntimeException(
246 getLocator(), getLine(), getColumn(),
247 "Operation " + getSign() + " not supported on operands of type " + StringBuilder.class
248 );
249 }
250
251 public Object calculate(Object left, Object right) throws TemplateRuntimeException {
252 Class<?> leftType = (left != null) ? left.getClass() : Void.class;
253 Class<?> rightType = (right != null) ? right.getClass() : Void.class;
254
255 throw new TemplateRuntimeException(
256 getLocator(), getLine(), getColumn(),
257 "Operation " + getSign() + " not supported on operands of type " + leftType + " and " + rightType
258 );
259 }
260
261
262
263
264 @Override
265 public String toString() {
266 return "(" + getLeftCommand() + " " + getSign() + " " + getRightCommand() + ")";
267 }
268
269 }