001    // Copyright 2006, 2008, 2009 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.tapestry5.internal.bindings;
016    
017    import org.apache.tapestry5.PropertyConduit;
018    import org.apache.tapestry5.internal.TapestryInternalUtils;
019    import org.apache.tapestry5.internal.services.Invariant;
020    import org.apache.tapestry5.ioc.Location;
021    import org.apache.tapestry5.ioc.internal.util.TapestryException;
022    
023    import java.lang.annotation.Annotation;
024    
025    /**
026     * Base class for bindings created by the {@link org.apache.tapestry5.internal.bindings.PropBindingFactory}. A subclass
027     * of this is created at runtime.
028     */
029    public class PropBinding extends AbstractBinding implements InternalPropBinding
030    {
031        private final Object root;
032    
033        private final PropertyConduit conduit;
034    
035        private final String toString;
036    
037        private boolean invariant;
038    
039        public PropBinding(final Location location, final Object root, final PropertyConduit conduit, final String toString
040        )
041        {
042            super(location);
043    
044            this.root = root;
045            this.conduit = conduit;
046            this.toString = toString;
047    
048            invariant = conduit.getAnnotation(Invariant.class) != null;
049        }
050    
051        /**
052         * The default implementation of get() will throw a TapestryException (binding is write only). The fabricated
053         * subclass <em>may</em> override this method (as well as set()).
054         */
055        public Object get()
056        {
057            try
058            {
059                return conduit.get(root);
060            }
061            catch (Exception ex)
062            {
063                throw new TapestryException(ex.getMessage(), getLocation(), ex);
064            }
065        }
066    
067        @Override
068        public void set(Object value)
069        {
070            try
071            {
072                conduit.set(root, value);
073            }
074            catch (Exception ex)
075            {
076                throw new TapestryException(ex.getMessage(), getLocation(), ex);
077            }
078        }
079    
080        @Override
081        public String toString()
082        {
083            return toString;
084        }
085    
086        /**
087         * Almost always returns false, unless the conduit provides the {@link org.apache.tapestry5.internal.services.Invariant}
088         * annotation.
089         */
090        @Override
091        public boolean isInvariant()
092        {
093            return invariant;
094        }
095    
096        @Override
097        public Class getBindingType()
098        {
099            return conduit.getPropertyType();
100        }
101    
102        @Override
103        public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
104        {
105            return conduit.getAnnotation(annotationClass);
106        }
107    
108            public String getPropertyName() 
109            {
110                    return TapestryInternalUtils.toInternalPropertyConduit(conduit).getPropertyName();
111            }
112    }