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 }