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