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