1 package org.apache.commons.ognl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.ognl.enhance.ExpressionCompiler;
23
24 import java.math.BigDecimal;
25 import java.math.BigInteger;
26
27
28
29
30
31
32 class ASTAdd
33 extends NumericExpression
34 {
35 public ASTAdd( int id )
36 {
37 super( id );
38 }
39
40 public ASTAdd( OgnlParser p, int id )
41 {
42 super( p, id );
43 }
44
45 public void jjtClose()
46 {
47 flattenTree();
48 }
49
50 protected Object getValueBody( OgnlContext context, Object source )
51 throws OgnlException
52 {
53 Object result = children[0].getValue( context, source );
54
55 for ( int i = 1; i < children.length; ++i )
56 {
57 result = OgnlOps.add( result, children[i].getValue( context, source ) );
58 }
59
60 return result;
61 }
62
63 public String getExpressionOperator( int index )
64 {
65 return "+";
66 }
67
68 boolean isWider( NodeType type, NodeType lastType )
69 {
70 if ( lastType == null )
71 {
72 return true;
73 }
74
75
76
77 if ( String.class.isAssignableFrom( lastType.getGetterClass() ) )
78 {
79 return false;
80 }
81
82 if ( String.class.isAssignableFrom( type.getGetterClass() ) )
83 {
84 return true;
85 }
86
87 if ( parent != null && String.class.isAssignableFrom( type.getGetterClass() ) )
88 {
89 return true;
90 }
91
92 if ( String.class.isAssignableFrom( lastType.getGetterClass() ) && Object.class == type.getGetterClass() )
93 {
94 return false;
95 }
96
97 if ( parent != null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
98 {
99 return false;
100 }
101 else if ( parent == null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
102 {
103 return true;
104 }
105 else if ( parent == null && String.class.isAssignableFrom( type.getGetterClass() ) )
106 {
107 return false;
108 }
109
110 if ( BigDecimal.class.isAssignableFrom( type.getGetterClass() )
111 || BigInteger.class.isAssignableFrom( type.getGetterClass() ) )
112 {
113 return true;
114 }
115
116 if ( BigDecimal.class.isAssignableFrom( lastType.getGetterClass() )
117 || BigInteger.class.isAssignableFrom( lastType.getGetterClass() ) )
118 {
119 return false;
120 }
121
122 if ( Double.class.isAssignableFrom( type.getGetterClass() ) )
123 {
124 return true;
125 }
126
127 if ( Integer.class.isAssignableFrom( type.getGetterClass() )
128 && Double.class.isAssignableFrom( lastType.getGetterClass() ) )
129 {
130 return false;
131 }
132
133 if ( Float.class.isAssignableFrom( type.getGetterClass() )
134 && Integer.class.isAssignableFrom( lastType.getGetterClass() ) )
135 {
136 return true;
137 }
138
139 return true;
140 }
141
142 public String toGetSourceString( OgnlContext context, Object target )
143 {
144 try
145 {
146 String result = "";
147 NodeType lastType = null;
148
149
150
151 if ( ( children != null ) && ( children.length > 0 ) )
152 {
153 Class currType = context.getCurrentType();
154 Class currAccessor = context.getCurrentAccessor();
155
156 Object cast = context.get( ExpressionCompiler.PRE_CAST );
157
158 for ( int i = 0; i < children.length; ++i )
159 {
160 children[i].toGetSourceString( context, target );
161
162 if ( NodeType.class.isInstance( children[i] )
163 && ( (NodeType) children[i] ).getGetterClass() != null
164 && isWider( (NodeType) children[i], lastType ) )
165 {
166 lastType = (NodeType) children[i];
167 }
168 }
169
170 context.put( ExpressionCompiler.PRE_CAST, cast );
171
172 context.setCurrentType( currType );
173 context.setCurrentAccessor( currAccessor );
174 }
175
176
177
178 context.setCurrentObject( target );
179
180 if ( ( children != null ) && ( children.length > 0 ) )
181 {
182
183 for ( int i = 0; i < children.length; ++i )
184 {
185 if ( i > 0 )
186 {
187 result += " " + getExpressionOperator( i ) + " ";
188 }
189
190 String expr = children[i].toGetSourceString( context, target );
191
192 if ( ( expr != null && "null".equals( expr ) )
193 || ( !ASTConst.class.isInstance( children[i] )
194 && ( expr == null || expr.trim().length() <= 0 ) ) )
195 {
196 expr = "null";
197 }
198
199
200
201
202 if ( ASTProperty.class.isInstance( children[i] ) )
203 {
204 expr = ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context ) + expr;
205 context.setCurrentAccessor( context.getRoot().getClass() );
206 }
207 else if ( ASTMethod.class.isInstance( children[i] ) )
208 {
209 String chain = (String) context.get( "_currentChain" );
210 String rootExpr =
211 ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context );
212
213
214
215
216
217 if ( rootExpr.endsWith( "." ) && chain != null && chain.startsWith( ")." ) )
218 {
219 chain = chain.substring( 1, chain.length() );
220 }
221
222 expr = rootExpr + ( chain != null ? chain + "." : "" ) + expr;
223 context.setCurrentAccessor( context.getRoot().getClass() );
224
225 }
226 else if ( ExpressionNode.class.isInstance( children[i] ) )
227 {
228 expr = "(" + expr + ")";
229 }
230 else if ( ( parent == null || !ASTChain.class.isInstance( parent ) )
231 && ASTChain.class.isInstance( children[i] ) )
232 {
233 String rootExpr =
234 ExpressionCompiler.getRootExpression( children[i], context.getRoot(), context );
235
236 if ( !ASTProperty.class.isInstance( children[i].jjtGetChild( 0 ) ) && rootExpr.endsWith( ")" )
237 && expr.startsWith( ")" ) )
238 {
239 expr = expr.substring( 1, expr.length() );
240 }
241
242 expr = rootExpr + expr;
243 context.setCurrentAccessor( context.getRoot().getClass() );
244
245 String cast = (String) context.remove( ExpressionCompiler.PRE_CAST );
246 if ( cast == null )
247 {
248 cast = "";
249 }
250
251 expr = cast + expr;
252 }
253
254
255
256 if ( context.getCurrentType() != null && context.getCurrentType() == Character.class
257 && ASTConst.class.isInstance( children[i] ) )
258 {
259 expr = expr.replaceAll( "'", "\"" );
260 context.setCurrentType( String.class );
261 }
262 else
263 {
264
265 if ( !ASTVarRef.class.isAssignableFrom( children[i].getClass() )
266 && !ASTProperty.class.isInstance( children[i] )
267 && !ASTMethod.class.isInstance( children[i] )
268 && !ASTSequence.class.isInstance( children[i] )
269 && !ASTChain.class.isInstance( children[i] )
270 && !NumericExpression.class.isAssignableFrom( children[i].getClass() )
271 && !ASTStaticField.class.isInstance( children[i] )
272 && !ASTStaticMethod.class.isInstance( children[i] )
273 && !ASTTest.class.isInstance( children[i] ) )
274 {
275 if ( lastType != null && String.class.isAssignableFrom( lastType.getGetterClass() ) )
276 {
277
278 expr = expr.replaceAll( """, "\"" );
279 expr = expr.replaceAll( "\"", "'" );
280 expr = "\"" + expr + "\"";
281
282 }
283 }
284 }
285
286 result += expr;
287
288
289
290 if ( ( lastType == null || !String.class.isAssignableFrom( lastType.getGetterClass() ) )
291 && !ASTConst.class.isAssignableFrom( children[i].getClass() )
292 && !NumericExpression.class.isAssignableFrom( children[i].getClass() ) )
293 {
294 if ( context.getCurrentType() != null
295 && Number.class.isAssignableFrom( context.getCurrentType() )
296 && !ASTMethod.class.isInstance( children[i] ) )
297 {
298 if ( ASTVarRef.class.isInstance( children[i] )
299 || ASTProperty.class.isInstance( children[i] )
300 || ASTChain.class.isInstance( children[i] ) )
301 {
302 result += ".";
303 }
304
305 result += OgnlRuntime.getNumericValueGetter( context.getCurrentType() );
306 context.setCurrentType( OgnlRuntime.getPrimitiveWrapperClass( context.getCurrentType() ) );
307 }
308 }
309
310 if ( lastType != null )
311 {
312 context.setCurrentAccessor( lastType.getGetterClass() );
313 }
314 }
315 }
316
317 if ( parent == null || ASTSequence.class.isAssignableFrom( parent.getClass() ) )
318 {
319 if ( getterClass != null && String.class.isAssignableFrom( getterClass ) )
320 {
321 getterClass = Object.class;
322 }
323 }
324 else
325 {
326 context.setCurrentType( getterClass );
327 }
328
329 try
330 {
331 Object contextObj = getValueBody( context, target );
332 context.setCurrentObject( contextObj );
333 }
334 catch ( Throwable t )
335 {
336 throw OgnlOps.castToRuntime( t );
337 }
338
339 return result;
340
341 }
342 catch ( Throwable t )
343 {
344 throw OgnlOps.castToRuntime( t );
345 }
346 }
347
348 public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
349 throws OgnlException
350 {
351 return visitor.visit( this, data );
352 }
353 }