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
25
26
27 public abstract class NumericExpression
28 extends ExpressionNode
29 implements NodeType
30 {
31
32 private static final long serialVersionUID = -174952564587478850L;
33
34 protected Class<?> getterClass;
35
36 public NumericExpression( int id )
37 {
38 super( id );
39 }
40
41 public NumericExpression( OgnlParser p, int id )
42 {
43 super( p, id );
44 }
45
46
47
48
49 public Class<?> getGetterClass()
50 {
51 if ( getterClass != null )
52 {
53 return getterClass;
54 }
55
56 return Double.TYPE;
57 }
58
59
60
61
62 public Class<?> getSetterClass()
63 {
64 return null;
65 }
66
67
68
69
70 @Override
71 public String toGetSourceString( OgnlContext context, Object target )
72 {
73 Object value;
74 StringBuilder result = new StringBuilder( "" );
75
76 try
77 {
78
79 value = getValueBody( context, target );
80
81 if ( value != null )
82 {
83 getterClass = value.getClass();
84 }
85
86 for ( int i = 0; i < children.length; i++ )
87 {
88 if ( i > 0 )
89 {
90 result.append( " " ).append( getExpressionOperator( i ) ).append( " " );
91 }
92 String str = OgnlRuntime.getChildSource( context, target, children[i] );
93
94 result.append( coerceToNumeric( str, context, children[i] ) );
95 }
96
97 }
98 catch ( Throwable t )
99 {
100 throw OgnlOps.castToRuntime( t );
101 }
102
103 return result.toString();
104 }
105
106 public String coerceToNumeric( String source, OgnlContext context, Node child )
107 {
108 StringBuilder ret = new StringBuilder( source );
109 Object value = context.getCurrentObject();
110
111 if ( ASTConst.class.isInstance( child ) && value != null )
112 {
113 return value.toString();
114 }
115
116 if ( context.getCurrentType() != null && !context.getCurrentType().isPrimitive()
117 && context.getCurrentObject() != null && Number.class.isInstance( context.getCurrentObject() ) )
118 {
119 ret = new StringBuilder( "((" ).append(
120 ExpressionCompiler.getCastString( context.getCurrentObject().getClass() ) ).append( ")" ).append(
121 ret ).append( ")." ).append(
122 OgnlRuntime.getNumericValueGetter( context.getCurrentObject().getClass() ) );
123 }
124 else if ( context.getCurrentType() != null && context.getCurrentType().isPrimitive()
125 && ( ASTConst.class.isInstance( child ) || NumericExpression.class.isInstance( child ) ) )
126 {
127 @SuppressWarnings( "unchecked" )
128 Class<? extends Number> numberClass = (Class<? extends Number>) context.getCurrentType();
129 ret.append( OgnlRuntime.getNumericLiteral( numberClass ) );
130 }
131 else if ( context.getCurrentType() != null && String.class.isAssignableFrom( context.getCurrentType() ) )
132 {
133 ret = new StringBuilder( "Double.parseDouble(" )
134 .append( ret )
135 .append( ")" );
136 context.setCurrentType( Double.TYPE );
137 }
138
139 if ( NumericExpression.class.isInstance( child ) )
140 {
141 ret = new StringBuilder( "(" ).append( ret ).append( ")" );
142 }
143
144 return ret.toString();
145 }
146 }