View Javadoc

1   package org.apache.commons.ognl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Field;
23  import java.lang.reflect.Modifier;
24  
25  /**
26   * $Id: ASTStaticField.java 1198661 2011-11-07 09:14:07Z mcucchiara $
27   * @author Luke Blanshard (blanshlu@netscape.net)
28   * @author Drew Davidson (drew@ognl.org)
29   */
30  public class ASTStaticField
31      extends SimpleNode
32      implements NodeType
33  {
34  
35      private String className;
36  
37      private String fieldName;
38  
39      private Class getterClass;
40  
41      public ASTStaticField( int id )
42      {
43          super( id );
44      }
45  
46      public ASTStaticField( OgnlParser p, int id )
47      {
48          super( p, id );
49      }
50  
51      /** Called from parser action. */
52      void init( String className, String fieldName )
53      {
54          this.className = className;
55          this.fieldName = fieldName;
56      }
57  
58      protected Object getValueBody( OgnlContext context, Object source )
59          throws OgnlException
60      {
61          return OgnlRuntime.getStaticField( context, className, fieldName );
62      }
63  
64      public boolean isNodeConstant( OgnlContext context )
65          throws OgnlException
66      {
67          boolean result = false;
68          Exception cause = null;
69  
70          try
71          {
72              Class clazz = OgnlRuntime.classForName( context, className );
73  
74              /*
75               * Check for virtual static field "class"; this cannot interfere with normal static fields because it is a
76               * reserved word. It is considered constant.
77               */
78              if ( "class".equals( fieldName ) )
79              {
80                  result = true;
81              }
82              else if ( clazz.isEnum() )
83              {
84                  result = true;
85              }
86              else
87              {
88                  Field field = clazz.getField( fieldName );
89  
90                  if ( !Modifier.isStatic( field.getModifiers() ) )
91                  {
92                      throw new OgnlException( "Field " + fieldName + " of class " + className + " is not static" );
93                  }
94                  result = Modifier.isFinal( field.getModifiers() );
95              }
96          }
97          catch ( ClassNotFoundException e )
98          {
99              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 }