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 }