001 package org.apache.commons.ognl;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.lang.reflect.Field;
023 import java.lang.reflect.Modifier;
024
025 /**
026 * $Id: ASTStaticField.java 1198661 2011-11-07 09:14:07Z mcucchiara $
027 * @author Luke Blanshard (blanshlu@netscape.net)
028 * @author Drew Davidson (drew@ognl.org)
029 */
030 public class ASTStaticField
031 extends SimpleNode
032 implements NodeType
033 {
034
035 private String className;
036
037 private String fieldName;
038
039 private Class getterClass;
040
041 public ASTStaticField( int id )
042 {
043 super( id );
044 }
045
046 public ASTStaticField( OgnlParser p, int id )
047 {
048 super( p, id );
049 }
050
051 /** Called from parser action. */
052 void init( String className, String fieldName )
053 {
054 this.className = className;
055 this.fieldName = fieldName;
056 }
057
058 protected Object getValueBody( OgnlContext context, Object source )
059 throws OgnlException
060 {
061 return OgnlRuntime.getStaticField( context, className, fieldName );
062 }
063
064 public boolean isNodeConstant( OgnlContext context )
065 throws OgnlException
066 {
067 boolean result = false;
068 Exception cause = null;
069
070 try
071 {
072 Class clazz = OgnlRuntime.classForName( context, className );
073
074 /*
075 * Check for virtual static field "class"; this cannot interfere with normal static fields because it is a
076 * reserved word. It is considered constant.
077 */
078 if ( "class".equals( fieldName ) )
079 {
080 result = true;
081 }
082 else if ( clazz.isEnum() )
083 {
084 result = true;
085 }
086 else
087 {
088 Field field = clazz.getField( fieldName );
089
090 if ( !Modifier.isStatic( field.getModifiers() ) )
091 {
092 throw new OgnlException( "Field " + fieldName + " of class " + className + " is not static" );
093 }
094 result = Modifier.isFinal( field.getModifiers() );
095 }
096 }
097 catch ( ClassNotFoundException e )
098 {
099 cause = e;
100 }
101 catch ( NoSuchFieldException e )
102 {
103 cause = e;
104 }
105 catch ( SecurityException e )
106 {
107 cause = e;
108 }
109
110 if ( cause != null )
111 {
112 throw new OgnlException( "Could not get static field " + fieldName + " from class " + className, cause );
113 }
114
115 return result;
116 }
117
118 Class getFieldClass( OgnlContext context )
119 throws OgnlException
120 {
121 Exception cause;
122
123 try
124 {
125 Class clazz = OgnlRuntime.classForName( context, className );
126
127 /*
128 * Check for virtual static field "class"; this cannot interfere with normal static fields because it is a
129 * reserved word. It is considered constant.
130 */
131 if ( "class".equals( fieldName ) )
132 {
133 return clazz;
134 }
135 else if ( clazz.isEnum() )
136 {
137 return clazz;
138 }
139 else
140 {
141 Field field = clazz.getField( fieldName );
142
143 return field.getType();
144 }
145 }
146 catch ( ClassNotFoundException e )
147 {
148 cause = e;
149 }
150 catch ( NoSuchFieldException e )
151 {
152 cause = e;
153 }
154 catch ( SecurityException e )
155 {
156 cause = e;
157 }
158 throw new OgnlException( "Could not get static field " + fieldName + " from class " + className, cause );
159 }
160
161 public Class getGetterClass()
162 {
163 return getterClass;
164 }
165
166 public Class getSetterClass()
167 {
168 return getterClass;
169 }
170
171 public String toGetSourceString( OgnlContext context, Object target )
172 {
173 try
174 {
175
176 Object obj = OgnlRuntime.getStaticField( context, className, fieldName );
177
178 context.setCurrentObject( obj );
179
180 getterClass = getFieldClass( context );
181
182 context.setCurrentType( getterClass );
183
184 }
185 catch ( Throwable t )
186 {
187 throw OgnlOps.castToRuntime( t );
188 }
189
190 return className + "." + fieldName;
191 }
192
193 public String toSetSourceString( OgnlContext context, Object target )
194 {
195 try
196 {
197
198 Object obj = OgnlRuntime.getStaticField( context, className, fieldName );
199
200 context.setCurrentObject( obj );
201
202 getterClass = getFieldClass( context );
203
204 context.setCurrentType( getterClass );
205
206 }
207 catch ( Throwable t )
208 {
209 throw OgnlOps.castToRuntime( t );
210 }
211
212 return className + "." + fieldName;
213 }
214
215 public <R, P> R accept( NodeVisitor<? extends R, ? super P> visitor, P data )
216 throws OgnlException
217 {
218 return visitor.visit( this, data );
219 }
220
221 /**
222 * Get the field name for this field.
223 *
224 * @return the field name.
225 * @since 4.0
226 */
227 String getFieldName()
228 {
229 return fieldName;
230 }
231
232 /**
233 * Get the class name for this field.
234 *
235 * @return the class name.
236 * @since 4.0
237 */
238 String getClassName()
239 {
240 return className;
241 }
242 }