View Javadoc

1   /*
2    * This file is part of Pease Plate Template Engine.
3    * 
4    * Pease Plate Template Engine is free software: you can redistribute
5    * it and/or modify it under the terms of the GNU Lesser General 
6    * Public License as published by the Free Software Foundation, 
7    * either version 3 of the License, or any later version.
8    * 
9    * Pease Plate Template Engine is distributed in the hope that it 
10   * will be useful, but WITHOUT ANY WARRANTY; without even the implied
11   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12   * See the GNU Lesser General Public License for more details.
13   * 
14   * You should have received a copy of the GNU Lesser General Public 
15   * License along with Pease Plate Template Engine. If not, see 
16   * <http://www.gnu.org/licenses/>.
17   * 
18   * Copyright (c) 2008 Manfred HANTSCHEL
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 	 * @see java.lang.Object#toString()
263 	 */
264 	@Override
265 	public String toString() {
266 		return "(" + getLeftCommand() + " " + getSign() + " " + getRightCommand() + ")";
267 	}
268 	
269 }