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 | |
import org.apache.commons.ognl.enhance.OgnlExpressionCompiler; |
24 | |
import org.apache.commons.ognl.enhance.UnsupportedCompilationException; |
25 | |
|
26 | |
import java.lang.reflect.Method; |
27 | |
|
28 | |
|
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | |
|
34 | |
public class ASTStaticMethod |
35 | |
extends SimpleNode |
36 | |
implements NodeType |
37 | |
{ |
38 | |
|
39 | |
private String className; |
40 | |
|
41 | |
private String methodName; |
42 | |
|
43 | |
private Class getterClass; |
44 | |
|
45 | |
public ASTStaticMethod( int id ) |
46 | |
{ |
47 | 20 | super( id ); |
48 | 20 | } |
49 | |
|
50 | |
public ASTStaticMethod( OgnlParser p, int id ) |
51 | |
{ |
52 | 0 | super( p, id ); |
53 | 0 | } |
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
void init( String className, String methodName ) |
59 | |
{ |
60 | 20 | this.className = className; |
61 | 20 | this.methodName = methodName; |
62 | 20 | } |
63 | |
|
64 | |
protected Object getValueBody( OgnlContext context, Object source ) |
65 | |
throws OgnlException |
66 | |
{ |
67 | 27 | ObjectArrayPool objectArrayPool = OgnlRuntime.getObjectArrayPool(); |
68 | 27 | Object[] args = objectArrayPool.create( jjtGetNumChildren() ); |
69 | 27 | Object root = context.getRoot(); |
70 | |
|
71 | |
try |
72 | |
{ |
73 | 48 | for ( int i = 0, icount = args.length; i < icount; ++i ) |
74 | |
{ |
75 | 21 | args[i] = children[i].getValue( context, root ); |
76 | |
} |
77 | |
|
78 | 27 | return OgnlRuntime.callStaticMethod( context, className, methodName, args ); |
79 | |
} |
80 | |
finally |
81 | |
{ |
82 | 26 | objectArrayPool.recycle( args ); |
83 | |
} |
84 | |
} |
85 | |
|
86 | |
public Class getGetterClass() |
87 | |
{ |
88 | 4 | return getterClass; |
89 | |
} |
90 | |
|
91 | |
public Class getSetterClass() |
92 | |
{ |
93 | 0 | return getterClass; |
94 | |
} |
95 | |
|
96 | |
public String toGetSourceString( OgnlContext context, Object target ) |
97 | |
{ |
98 | 20 | String result = className + "#" + methodName + "("; |
99 | |
|
100 | |
try |
101 | |
{ |
102 | 20 | Class clazz = OgnlRuntime.classForName( context, className ); |
103 | 20 | Method m = OgnlRuntime.getMethod( context, clazz, methodName, children, true ); |
104 | |
|
105 | 20 | if ( clazz == null || m == null ) |
106 | |
{ |
107 | 2 | throw new UnsupportedCompilationException( |
108 | |
"Unable to find class/method combo " + className + " / " + methodName ); |
109 | |
} |
110 | |
|
111 | 18 | if ( !context.getMemberAccess().isAccessible( context, clazz, m, methodName ) ) |
112 | |
{ |
113 | 2 | throw new UnsupportedCompilationException( |
114 | |
"Method is not accessible, check your jvm runtime security settings. " + "For static class method " |
115 | |
+ className + " / " + methodName ); |
116 | |
} |
117 | |
|
118 | 16 | OgnlExpressionCompiler compiler = OgnlRuntime.getCompiler( context ); |
119 | 16 | if ( ( children != null ) && ( children.length > 0 ) ) |
120 | |
{ |
121 | 10 | Class[] parms = m.getParameterTypes(); |
122 | |
|
123 | 22 | for ( int i = 0; i < children.length; i++ ) |
124 | |
{ |
125 | 12 | if ( i > 0 ) |
126 | |
{ |
127 | 2 | result = result + ", "; |
128 | |
} |
129 | |
|
130 | 12 | Class prevType = context.getCurrentType(); |
131 | |
|
132 | 12 | Node child = children[i]; |
133 | 12 | Object root = context.getRoot(); |
134 | |
|
135 | 12 | String parmString = ASTMethodUtil.getParmString( context, root, child, prevType ); |
136 | |
|
137 | 12 | Class valueClass = ASTMethodUtil.getValueClass( context, root, child ); |
138 | |
|
139 | 12 | if ( valueClass != parms[i] ) |
140 | |
{ |
141 | 4 | if ( parms[i].isArray() ) |
142 | |
{ |
143 | 0 | parmString = compiler.createLocalReference( context, "(" + ExpressionCompiler.getCastString( |
144 | |
parms[i] ) + ")org.apache.commons.ognl.OgnlOps.toArray(" + parmString + ", " |
145 | |
+ parms[i].getComponentType().getName() + ".class, true)", parms[i] ); |
146 | |
|
147 | |
} |
148 | 4 | else if ( parms[i].isPrimitive() ) |
149 | |
{ |
150 | 4 | Class wrapClass = OgnlRuntime.getPrimitiveWrapperClass( parms[i] ); |
151 | |
|
152 | 4 | parmString = compiler.createLocalReference( context, "((" + wrapClass.getName() |
153 | |
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + "," |
154 | |
+ wrapClass.getName() + ".class, true))." + OgnlRuntime.getNumericValueGetter( |
155 | |
wrapClass ), parms[i] ); |
156 | |
|
157 | 4 | } |
158 | 0 | else if ( parms[i] != Object.class ) |
159 | |
{ |
160 | 0 | parmString = compiler.createLocalReference( context, "(" + parms[i].getName() |
161 | |
+ ")org.apache.commons.ognl.OgnlOps.convertValue(" + parmString + "," |
162 | |
+ parms[i].getName() + ".class)", parms[i] ); |
163 | |
} |
164 | 0 | else if ( ( NodeType.class.isInstance( child ) && ( (NodeType) child ).getGetterClass() != null |
165 | |
&& Number.class.isAssignableFrom( ( (NodeType) child ).getGetterClass() ) ) |
166 | |
|| valueClass.isPrimitive() ) |
167 | |
{ |
168 | 0 | parmString = " ($w) " + parmString; |
169 | |
} |
170 | 0 | else if ( valueClass.isPrimitive() ) |
171 | |
{ |
172 | 0 | parmString = "($w) " + parmString; |
173 | |
} |
174 | |
} |
175 | |
|
176 | 12 | result += parmString; |
177 | |
} |
178 | |
} |
179 | |
|
180 | 16 | result += ")"; |
181 | |
|
182 | |
try |
183 | |
{ |
184 | 16 | Object contextObj = getValueBody( context, target ); |
185 | 16 | context.setCurrentObject( contextObj ); |
186 | |
} |
187 | 0 | catch ( Throwable t ) |
188 | |
{ |
189 | |
|
190 | 16 | } |
191 | |
|
192 | 16 | if ( m != null ) |
193 | |
{ |
194 | 16 | getterClass = m.getReturnType(); |
195 | |
|
196 | 16 | context.setCurrentType( m.getReturnType() ); |
197 | 16 | context.setCurrentAccessor( compiler.getSuperOrInterfaceClass( m, m.getDeclaringClass() ) ); |
198 | |
} |
199 | |
|
200 | |
} |
201 | 4 | catch ( Throwable t ) |
202 | |
{ |
203 | 4 | throw OgnlOps.castToRuntime( t ); |
204 | 16 | } |
205 | |
|
206 | 16 | return result; |
207 | |
} |
208 | |
|
209 | |
public String toSetSourceString( OgnlContext context, Object target ) |
210 | |
{ |
211 | 7 | return toGetSourceString( context, target ); |
212 | |
} |
213 | |
|
214 | |
public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data ) |
215 | |
throws OgnlException |
216 | |
{ |
217 | 0 | return visitor.visit( this, data ); |
218 | |
} |
219 | |
|
220 | |
|
221 | |
|
222 | |
|
223 | |
|
224 | |
|
225 | |
|
226 | |
public String getClassName() |
227 | |
{ |
228 | 0 | return className; |
229 | |
} |
230 | |
|
231 | |
|
232 | |
|
233 | |
|
234 | |
|
235 | |
|
236 | |
|
237 | |
public String getMethodName() |
238 | |
{ |
239 | 0 | return methodName; |
240 | |
} |
241 | |
} |