001    // Copyright 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.annotations;
016    
017    import java.lang.annotation.Annotation;
018    import java.lang.reflect.Method;
019    import java.util.Map;
020    
021    import org.apache.hivemind.ClassResolver;
022    import org.apache.hivemind.ErrorLog;
023    import org.apache.hivemind.Location;
024    import org.apache.hivemind.Resource;
025    import org.apache.hivemind.util.ClasspathResource;
026    import org.apache.tapestry.enhance.EnhancementOperation;
027    import org.apache.tapestry.enhance.EnhancementWorker;
028    import org.apache.tapestry.spec.IComponentSpecification;
029    import org.apache.tapestry.util.DescribedLocation;
030    
031    /**
032     * Implementation of {@link org.apache.tapestry.enhance.EnhancementWorker} that finds class and
033     * method annotations and delegates out to specific
034     * {@link org.apache.tapestry.annotations.ClassAnnotationEnhancementWorker} and
035     * {@link org.apache.tapestry.annotations.MethodAnnotationEnhancementWorker} instances.
036     * 
037     * @author Howard M. Lewis Ship
038     * @since 4.0
039     */
040    public class AnnotationEnhancementWorker implements EnhancementWorker
041    {
042        private ClassResolver _classResolver;
043    
044        private ErrorLog _errorLog;
045    
046        private Map _methodWorkers;
047    
048        private Map _classWorkers;
049    
050        public void setClassWorkers(Map classWorkers)
051        {
052            _classWorkers = classWorkers;
053        }
054    
055        public void performEnhancement(EnhancementOperation op, IComponentSpecification spec)
056        {
057            Class clazz = op.getBaseClass();
058    
059            Resource classResource = newClassResource(clazz);
060    
061            for (Annotation a : clazz.getAnnotations())
062            {
063                performClassEnhancement(op, spec, clazz, a, classResource);
064            }
065    
066            for (Method m : clazz.getMethods())
067            {
068                performMethodEnhancement(op, spec, m, classResource);
069            }
070        }
071    
072        private ClasspathResource newClassResource(Class clazz)
073        {
074            return new ClasspathResource(_classResolver, clazz.getName().replace('.', '/'));
075        }
076    
077        void performClassEnhancement(EnhancementOperation op, IComponentSpecification spec,
078                Class clazz, Annotation annotation, Resource classResource)
079        {
080            ClassAnnotationEnhancementWorker worker = (ClassAnnotationEnhancementWorker) _classWorkers
081                    .get(annotation.annotationType());
082    
083            if (worker == null)
084                return;
085    
086            try
087            {
088                Location location = new DescribedLocation(classResource, AnnotationMessages
089                        .classAnnotation(annotation, clazz));
090    
091                worker.performEnhancement(op, spec, clazz, location);
092            }
093            catch (Exception ex)
094            {
095                _errorLog.error(AnnotationMessages.failureProcessingClassAnnotation(
096                        annotation,
097                        clazz,
098                        ex), null, ex);
099            }
100    
101        }
102    
103        void performMethodEnhancement(EnhancementOperation op, IComponentSpecification spec,
104                Method method, Resource classResource)
105        {
106            for (Annotation a : method.getAnnotations())
107            {
108                performMethodEnhancement(op, spec, method, a, classResource);
109            }
110        }
111    
112        void performMethodEnhancement(EnhancementOperation op, IComponentSpecification spec,
113                Method method, Annotation annotation, Resource classResource)
114        {
115            MethodAnnotationEnhancementWorker worker = (MethodAnnotationEnhancementWorker) _methodWorkers
116                    .get(annotation.annotationType());
117    
118            if (worker == null)
119                return;
120    
121            try
122            {
123                Location location = new DescribedLocation(classResource, AnnotationMessages
124                        .methodAnnotation(annotation, method));
125                worker.performEnhancement(op, spec, method, location);
126            }
127            catch (Exception ex)
128            {
129                _errorLog.error(
130                        AnnotationMessages.failureProcessingAnnotation(annotation, method, ex),
131                        null,
132                        ex);
133            }
134    
135        }
136    
137        public void setMethodWorkers(Map methodWorkers)
138        {
139            _methodWorkers = methodWorkers;
140        }
141    
142        public void setErrorLog(ErrorLog errorLog)
143        {
144            _errorLog = errorLog;
145        }
146    
147        public void setClassResolver(ClassResolver classResolver)
148        {
149            _classResolver = classResolver;
150        }
151    }