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 AbstractCompareCommand extends AbstractDoubleParameterCommand {
32  
33  	public AbstractCompareCommand(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  	/**
40  	 * @see org.peaseplate.internal.lang.command.ICommand#call(BuildContext)
41  	 */
42      public Object call(BuildContext context) throws TemplateRuntimeException {
43  		Object result = null;
44  		ConversionService conversionService = context.getEngine().getConversionService();
45  		Object left = callLeftCommand(context);
46  		Object right = callRightCommand(context);
47  		Class<?> leftType = (left != null) ? left.getClass() : Void.class;
48  		Class<?> rightType = (right != null) ? right.getClass() : Void.class;
49  		
50  		try {
51  			if (
52  				(leftType == StringBuilder.class) || (rightType == StringBuilder.class) ||
53  				(leftType == StringBuffer.class) || (rightType == StringBuffer.class) ||
54  				(leftType == String.class) || (rightType == String.class)
55  			)
56  				result = evaluateComparable(
57  					conversionService.convert(left, String.class),
58  					conversionService.convert(right, String.class)
59  				);
60  
61  			else if ((leftType == BigDecimal.class) || (rightType == BigDecimal.class))
62  				result = evaluateComparable(
63  					conversionService.convert(left, BigDecimal.class),
64  					conversionService.convert(right, BigDecimal.class)
65  				);
66  			
67  			else if ((leftType == BigInteger.class) || (rightType == BigInteger.class))
68  				result = evaluateComparable(
69  					conversionService.convert(left, BigInteger.class),
70  					conversionService.convert(right, BigInteger.class)
71  				);
72  			
73  			else if (
74  				(leftType == double.class) || (leftType == Double.class) ||
75  				(rightType == double.class) || (rightType == Double.class)
76  			)
77  				result = evaluateComparable(
78  					conversionService.convert(left, Double.class),
79  					conversionService.convert(right, Double.class)
80  				);
81  			
82  			else if (
83  				(leftType == float.class) || (leftType == Float.class) ||
84  				(rightType == float.class) || (rightType == Float.class)
85  			)
86  				result = evaluateComparable(
87  					conversionService.convert(left, Float.class),
88  					conversionService.convert(right, Float.class)
89  				);
90  			
91  			else if (
92  				(leftType == long.class) || (leftType == Long.class) ||
93  				(rightType == long.class) || (rightType == Long.class)
94  			)
95  				result = evaluateComparable(
96  					conversionService.convert(left, Long.class),
97  					conversionService.convert(right, Long.class)
98  				);
99  			
100 			else if (
101 				(leftType == int.class) || (leftType == Integer.class) ||
102 				(rightType == int.class) || (rightType == Integer.class)
103 			)
104 				result = evaluateComparable(
105 					conversionService.convert(left, Integer.class),
106 					conversionService.convert(right, Integer.class)
107 				);
108 			
109 			else if (
110 				(leftType == char.class) || (leftType == Character.class) ||
111 				(rightType == char.class) || (rightType == Character.class)
112 			)
113 				result = evaluateComparable(
114 					conversionService.convert(left, Character.class),
115 					conversionService.convert(right, Character.class)
116 				);
117 			
118 			else if (
119 				(leftType == short.class) || (leftType == Short.class) ||
120 				(rightType == short.class) || (rightType == Short.class)
121 			)
122 				result = evaluateComparable(
123 					conversionService.convert(left, Short.class),
124 					conversionService.convert(right, Short.class)
125 				);
126 			
127 			else if (
128 				(leftType == byte.class) || (leftType == Byte.class) ||
129 				(rightType == byte.class) || (rightType == Byte.class)
130 			)
131 				result = evaluateComparable(
132 					conversionService.convert(left, Byte.class),
133 					conversionService.convert(right, Byte.class)
134 				);
135 			
136 			else if (
137 				(leftType == boolean.class) || (leftType == Boolean.class) ||
138 				(rightType == boolean.class) || (rightType == Boolean.class)
139 			)
140 				result = evaluateComparable(
141 					conversionService.convert(left, Boolean.class),
142 					conversionService.convert(right, Boolean.class)
143 				);
144 
145 			else if ((leftType == Void.class) && (rightType == Void.class))
146 				result = evaluateNull();
147 
148 			else
149 				result = evaluateNonComparable(left, right);
150 		}
151 		catch (ConversionException e) {
152 			if (e.getValue() == left)
153 				throw new TemplateRuntimeException(
154 					getLeftCommand().getLocator(), getLeftCommand().getLine(), getLeftCommand().getColumn(),
155 					"Could not convert left operator to " + e.getType(), e
156 				);
157 	
158 			else if (e.getValue() == right)
159 				throw new TemplateRuntimeException(
160 					getRightCommand().getLocator(), getRightCommand().getLine(), getRightCommand().getColumn(),
161 					"Could not convert right operator to " + e.getType(), e
162 				);
163 	
164 			else 
165 				throw new TemplateRuntimeException(
166 					getLocator(), getLine(), getColumn(),
167 					"Could not convert operator to " + e.getType(), e
168 				);
169 		}
170 
171 	    return result;
172     }
173 
174 	public Boolean evaluateNull() throws TemplateRuntimeException {
175 		throw new TemplateRuntimeException(
176 			getLocator(), getLine(), getColumn(),
177 			"Operation " + getSign() + " not supported on operands both null"
178 		);
179 	}
180 	
181 	public <TYPE> Boolean evaluateComparable(Comparable<TYPE> left, Comparable<TYPE> right) throws TemplateRuntimeException {
182 		Class<?> leftType = (left != null) ? left.getClass() : Void.class;
183 		Class<?> rightType = (right != null) ? right.getClass() : Void.class;
184 
185 		throw new TemplateRuntimeException(
186 			getLocator(), getLine(), getColumn(),
187 			"Operation " + getSign() + " not supported on operands of type " + leftType + " and " + rightType
188 		);
189 	}
190 	
191 	public Boolean evaluateNonComparable(Object left, Object right) throws TemplateRuntimeException {
192 		Class<?> leftType = (left != null) ? left.getClass() : Void.class;
193 		Class<?> rightType = (right != null) ? right.getClass() : Void.class;
194 
195 		throw new TemplateRuntimeException(
196 			getLocator(), getLine(), getColumn(),
197 			"Operation " + getSign() + " not supported on operands of type " + leftType + " and " + rightType
198 		);
199 	}
200 	
201 	/**
202 	 * @see java.lang.Object#toString()
203 	 */
204 	@Override
205 	public String toString() {
206 		return "(" + getLeftCommand() + " " + getSign() + " " + getRightCommand() + ")";
207 	}
208 	
209 }