1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with this 4 * work for additional information regarding copyright ownership. The ASF 5 * licenses this file to You under the Apache License, Version 2.0 (the 6 * "License"); you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law 9 * or agreed to in writing, software distributed under the License is 10 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language 12 * governing permissions and limitations under the License. 13 */ 14 package org.apache.webbeans.intercept; 15 16 import java.lang.annotation.Annotation; 17 import java.lang.reflect.Method; 18 import java.util.ArrayList; 19 import java.util.Collections; 20 import java.util.HashSet; 21 import java.util.Iterator; 22 import java.util.List; 23 import java.util.Set; 24 25 import javax.annotation.PostConstruct; 26 import javax.annotation.PreDestroy; 27 import javax.enterprise.inject.spi.Interceptor; 28 import javax.interceptor.AroundInvoke; 29 30 import org.apache.webbeans.component.AbstractBean; 31 import org.apache.webbeans.component.BaseBean; 32 import org.apache.webbeans.config.inheritance.IBeanInheritedMetaData; 33 import org.apache.webbeans.container.BeanManagerImpl; 34 import org.apache.webbeans.intercept.webbeans.WebBeansInterceptor; 35 import org.apache.webbeans.logger.WebBeansLogger; 36 import org.apache.webbeans.util.AnnotationUtil; 37 import org.apache.webbeans.util.WebBeansUtil; 38 39 /** 40 * Configures the Web Beans related interceptors. 41 * 42 * @author <a href="mailto:gurkanerdogdu@yahoo.com">Gurkan Erdogdu</a> 43 * @since 1.0 44 * @see WebBeansInterceptor 45 */ 46 public final class WebBeansInterceptorConfig 47 { 48 /** Logger instance */ 49 private static WebBeansLogger logger = WebBeansLogger.getLogger(WebBeansInterceptorConfig.class); 50 51 /* 52 * Private 53 */ 54 private WebBeansInterceptorConfig() 55 { 56 57 } 58 59 /** 60 * Configures WebBeans specific interceptor class. 61 * 62 * @param interceptorClazz interceptor class 63 */ 64 public static <T> void configureInterceptorClass(AbstractBean<T> delegate, Annotation[] interceptorBindingTypes) 65 { 66 logger.info("Configuring the Web Beans Interceptor Class : " + delegate.getReturnType().getName() + " started"); 67 68 WebBeansInterceptor<T> interceptor = new WebBeansInterceptor<T>(delegate); 69 70 for (Annotation ann : interceptorBindingTypes) 71 { 72 interceptor.addInterceptorBinding(ann.annotationType(), ann); 73 } 74 75 logger.info("Configuring the Web Beans Interceptor Class : " + delegate.getReturnType() + " ended"); 76 77 BeanManagerImpl.getManager().addInterceptor(interceptor); 78 79 } 80 81 /** 82 * Configures the given class for applicable interceptors. 83 * 84 * @param clazz configuration interceptors for this 85 */ 86 public static void configure(BaseBean<?> component, List<InterceptorData> stack) 87 { 88 Class<?> clazz = component.getReturnType(); 89 90 if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(clazz.getDeclaredAnnotations())) 91 { 92 93 Set<Annotation> bindingTypeSet = new HashSet<Annotation>(); 94 95 Annotation[] anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(clazz.getDeclaredAnnotations()); 96 97 for (Annotation ann : anns) 98 { 99 bindingTypeSet.add(ann); 100 } 101 102 Annotation[] stereoTypes = AnnotationUtil.getStereotypeMetaAnnotations(clazz.getDeclaredAnnotations()); 103 for (Annotation stero : stereoTypes) 104 { 105 if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(stero.annotationType().getDeclaredAnnotations())) 106 { 107 Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stero.annotationType().getDeclaredAnnotations()); 108 109 for (Annotation ann : steroInterceptorBindings) 110 { 111 bindingTypeSet.add(ann); 112 } 113 } 114 } 115 116 //Look for inherited binding types 117 IBeanInheritedMetaData metadata = component.getInheritedMetaData(); 118 if(metadata != null) 119 { 120 Set<Annotation> inheritedBindingTypes = metadata.getInheritedInterceptorBindings(); 121 if(!inheritedBindingTypes.isEmpty()) 122 { 123 bindingTypeSet.addAll(inheritedBindingTypes); 124 } 125 } 126 127 anns = new Annotation[bindingTypeSet.size()]; 128 anns = bindingTypeSet.toArray(anns); 129 130 Set<Interceptor<?>> set = findDeployedWebBeansInterceptor(anns); 131 132 // Adding class interceptors 133 addComponentInterceptors(set, stack); 134 } 135 136 // Method level interceptors. 137 addMethodInterceptors(clazz, stack); 138 139 } 140 141 public static void addComponentInterceptors(Set<Interceptor<?>> set, List<InterceptorData> stack) 142 { 143 Iterator<Interceptor<?>> it = set.iterator(); 144 while (it.hasNext()) 145 { 146 WebBeansInterceptor<?> interceptor = (WebBeansInterceptor<?>) it.next(); 147 148 // interceptor binding 149 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), AroundInvoke.class, true, false, stack, null, true); 150 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PostConstruct.class, true, false, stack, null, true); 151 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PreDestroy.class, true, false, stack, null, true); 152 153 } 154 155 } 156 157 private static void addMethodInterceptors(Class<?> clazz, List<InterceptorData> stack) 158 { 159 Method[] methods = clazz.getDeclaredMethods(); 160 161 for (Method method : methods) 162 { 163 if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(method.getAnnotations())) 164 { 165 Annotation[] anns = AnnotationUtil.getInterceptorBindingMetaAnnotations(method.getDeclaredAnnotations()); 166 Annotation[] annsClazz = AnnotationUtil.getInterceptorBindingMetaAnnotations(clazz.getDeclaredAnnotations()); 167 168 Set<Annotation> set = new HashSet<Annotation>(); 169 170 for (Annotation ann : anns) 171 { 172 set.add(ann); 173 } 174 175 for (Annotation ann : annsClazz) 176 { 177 set.add(ann); 178 } 179 180 Annotation[] stereoTypes = AnnotationUtil.getStereotypeMetaAnnotations(clazz.getDeclaredAnnotations()); 181 for (Annotation stero : stereoTypes) 182 { 183 if (AnnotationUtil.isInterceptorBindingMetaAnnotationExist(stero.annotationType().getDeclaredAnnotations())) 184 { 185 Annotation[] steroInterceptorBindings = AnnotationUtil.getInterceptorBindingMetaAnnotations(stero.annotationType().getDeclaredAnnotations()); 186 187 for (Annotation ann : steroInterceptorBindings) 188 { 189 set.add(ann); 190 } 191 } 192 } 193 194 Annotation[] result = new Annotation[set.size()]; 195 result = set.toArray(result); 196 197 Set<Interceptor<?>> setInterceptors = findDeployedWebBeansInterceptor(result); 198 Iterator<Interceptor<?>> it = setInterceptors.iterator(); 199 200 while (it.hasNext()) 201 { 202 WebBeansInterceptor<?> interceptor = (WebBeansInterceptor<?>) it.next(); 203 204 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), AroundInvoke.class, true, true, stack, method, true); 205 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PostConstruct.class, true, true, stack, method, true); 206 WebBeansUtil.configureInterceptorMethods(interceptor, interceptor.getClazz(), PreDestroy.class, true, true, stack, method, true); 207 } 208 209 } 210 } 211 212 } 213 214 /** 215 * Gets the configured webbeans interceptors. 216 * 217 * @return the configured webbeans interceptors 218 */ 219 private static Set<Interceptor<?>> getWebBeansInterceptors() 220 { 221 return Collections.unmodifiableSet(BeanManagerImpl.getManager().getInterceptors()); 222 } 223 224 /* 225 * Find the deployed interceptors with given interceptor binding types. 226 */ 227 public static Set<Interceptor<?>> findDeployedWebBeansInterceptor(Annotation[] anns) 228 { 229 Set<Interceptor<?>> set = new HashSet<Interceptor<?>>(); 230 231 Iterator<Interceptor<?>> it = getWebBeansInterceptors().iterator(); 232 WebBeansInterceptor<?> interceptor = null; 233 234 List<Class<? extends Annotation>> bindingTypes = new ArrayList<Class<? extends Annotation>>(); 235 List<Annotation> listAnnot = new ArrayList<Annotation>(); 236 for (Annotation ann : anns) 237 { 238 bindingTypes.add(ann.annotationType()); 239 listAnnot.add(ann); 240 } 241 242 while (it.hasNext()) 243 { 244 interceptor = (WebBeansInterceptor<?>) it.next(); 245 246 if (interceptor.isBindingExist(bindingTypes, listAnnot)) 247 { 248 set.add(interceptor); 249 set.addAll(interceptor.getMetaInceptors()); 250 } 251 } 252 253 return set; 254 } 255 }