001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.bean;
016    
017    import java.lang.reflect.Field;
018    
019    import org.apache.hivemind.ApplicationRuntimeException;
020    import org.apache.hivemind.ClassResolver;
021    import org.apache.tapestry.IBeanProvider;
022    import org.apache.tapestry.Tapestry;
023    
024    /**
025     *  Initializes a bean with the value of a public static field.
026     *
027     *  @author Howard Lewis Ship
028     *  @since 1.0.8
029     *
030     **/
031    
032    public class FieldBeanInitializer extends AbstractBeanInitializer
033    {
034        protected String _fieldName;
035        protected Object _fieldValue;
036        private boolean _fieldResolved = false;
037    
038        public synchronized void setBeanProperty(IBeanProvider provider, Object bean)
039        {
040            ClassResolver resolver = provider.getClassResolver();
041    
042            if (!_fieldResolved)
043                resolveField(resolver);
044    
045            setBeanProperty(bean, _fieldValue);
046        }
047    
048        private void resolveField(ClassResolver resolver)
049        {
050            if (_fieldResolved)
051                return;
052    
053            // This is all copied out of of FieldBinding!!
054    
055            int dotx = _fieldName.lastIndexOf('.');
056    
057            if (dotx < 0)
058                throw new ApplicationRuntimeException(
059                    Tapestry.format("invalid-field-name", _fieldName));
060    
061            String className = _fieldName.substring(0, dotx);
062            String simpleFieldName = _fieldName.substring(dotx + 1);
063    
064            // Simple class names are assumed to be in the java.lang package.
065    
066            if (className.indexOf('.') < 0)
067                className = "java.lang." + className;
068    
069            Class targetClass = null;
070    
071            try
072            {
073                targetClass = resolver.findClass(className);
074            }
075            catch (Throwable t)
076            {
077                throw new ApplicationRuntimeException(
078                    Tapestry.format("unable-to-resolve-class", className),
079                    t);
080            }
081    
082            Field field = null;
083    
084            try
085            {
086                field = targetClass.getField(simpleFieldName);
087            }
088            catch (NoSuchFieldException ex)
089            {
090                throw new ApplicationRuntimeException(
091                    Tapestry.format("field-not-defined", _fieldName),
092                    ex);
093            }
094    
095            // Get the value of the field.  null means look for it as a static
096            // variable.
097    
098            try
099            {
100                _fieldValue = field.get(null);
101            }
102            catch (IllegalAccessException ex)
103            {
104                throw new ApplicationRuntimeException(
105                    Tapestry.format("illegal-field-access", _fieldName),
106                    ex);
107            }
108            catch (NullPointerException ex)
109            {
110                throw new ApplicationRuntimeException(
111                    Tapestry.format("field-is-instance", _fieldName),
112                    ex);
113            }
114    
115            _fieldResolved = true;
116        }
117    
118    }