// Copyright 2013 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package org.apache.tapestry5.cdi.internal.utils; import static org.apache.tapestry5.cdi.BeanHelper.getQualifiers; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.apache.tapestry5.Block; import org.apache.tapestry5.ComponentResources; import org.apache.tapestry5.annotations.Path; import org.apache.tapestry5.ioc.AnnotationProvider; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.ObjectLocator; import org.apache.tapestry5.ioc.annotations.Symbol; import org.apache.tapestry5.services.pageload.ComponentResourceSelector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A collection of utility methods including a method that checks if a bean is managed by tapestry-ioc or not * */ public final class InternalUtils { private static Logger logger = LoggerFactory.getLogger(InternalUtils.class); @SuppressWarnings("rawtypes") private static final Map<Class, Annotation[]> annotationsCache = new HashMap<Class, Annotation[]>(); private static final List<String> tapestry_injectable_resources = Arrays.asList( new String[]{ ComponentResources.class.getName(), ComponentResourceSelector.class.getName(), Messages.class.getName(), Locale.class.getName(), Logger.class.getName(), Block.class.getName() }); /** * Check if the injected field is managed by tapestry (resource or service) * @param type the class type * @param annotationProvider used to check the annotation of the class/field * @param locator the objectLocator * @return true if the injected field is managed by Tapestry, false otherwise */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static boolean isManagedByTapestry(final Class type, final AnnotationProvider annotationProvider, final ObjectLocator locator){ if(type == null) return false; /** * We guess that in a tapestry webapp, injected resources are mostly from Tapestry * Is a tapestry resource/service ? * First, we check if the injected resource is a tapestry one, * then we check if it has a <i>Symbol</i> or <i>Path</i> annotation and * finally if it's a tapestry service by asking the locator. */ try { if( tapestry_injectable_resources.contains(type.getName()) || isAnnotation(annotationProvider, Symbol.class) || isAnnotation(annotationProvider, Path.class) || locator.getService(type)!=null ){ logger.debug(type+" is a Tapestry resources or service"); return true; } } catch (RuntimeException e) { // do nothing, the service is not managed by tapestry logger.debug(type +" is not a known service of the tapestry registry"); } return false; } private static <T extends Annotation> boolean isAnnotation(AnnotationProvider annotationProvider, final Class<T> annotation) { return annotationProvider.getAnnotation( new Annotation(){ public Class<? extends Annotation> annotationType() { return annotation; } }.annotationType())!=null; } /** * Returns the field's annotations corresponding to qualifiers for the current PlasticClass * @param type the class type * @param annotationProvider used to check the annotation of the class/field * @return an annotation array */ @SuppressWarnings("rawtypes") public static Annotation[] getFieldQualifiers(final Class type,final AnnotationProvider annotationProvider) { logger.debug("Field type : "+type); final Annotation[] annotations; if (!annotationsCache.containsKey(type)) { synchronized (annotationsCache) { if (!annotationsCache.containsKey(type)) { logger.debug("Put qualifiers in cache for type : "+type); annotationsCache.put(type, getQualifiers(type)); } } } annotations = annotationsCache.get(type); List<Annotation> qualifiers = new ArrayList<Annotation>(); for (Annotation annotation : annotations) { boolean isAnnotationPresent = annotationProvider.getAnnotation(annotation.annotationType())!=null; logger.debug("Is "+type+" has qualifier : "+annotation.annotationType()+" ? "+isAnnotationPresent); if(isAnnotationPresent){ logger.debug("Qualifier "+annotation+" found for "+type); qualifiers.add(annotation); } } return qualifiers.toArray(new Annotation[qualifiers.size()]); } }