001    // Copyright 2006 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.Binding;
018    import org.apache.tapestry5.ioc.BaseLocatable;
019    import org.apache.tapestry5.ioc.Location;
020    import org.apache.tapestry5.ioc.internal.util.TapestryException;
021    
022    import java.lang.annotation.Annotation;
023    
024    /**
025     * Abstract base class for bindings. Assumes that the binding is read only and invariant. Subclasses must provide an
026     * implementation of {@link Binding#get()}.
027     */
028    public abstract class AbstractBinding extends BaseLocatable implements Binding
029    {
030        public AbstractBinding()
031        {
032            this(null);
033        }
034    
035        protected AbstractBinding(Location location)
036        {
037            super(location);
038        }
039    
040        /**
041         * @throws TapestryException always
042         */
043        public void set(Object value)
044        {
045            throw new TapestryException(BindingsMessages.bindingIsReadOnly(this), this, null);
046        }
047    
048        /**
049         * Returns true. Subclasses that do not supply a fixed, read-only value should override this method to return
050         * false.
051         */
052        public boolean isInvariant()
053        {
054            return true;
055        }
056    
057        /**
058         * Returns the actual class, by invoking {@link Binding#get()}. Subclasses may override this method to work more
059         * efficiently (say, when the binding type is known statically).
060         */
061        public Class getBindingType()
062        {
063            return get().getClass();
064        }
065    
066        /**
067         * Always returns null. Bindings that provide access to a method or field will override this method to return the
068         * appropriate annotation.
069         */
070        public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
071        {
072            return null;
073        }
074    
075    }