blob: 31cee72aa40239b45dcebc795302504b9b6ec5c5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.tuscany.sca.implementation.java.introspect.impl;
import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllInterfaces;
import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllPublicAndProtectedFields;
import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getAllUniquePublicProtectedMethods;
import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.getBaseType;
import static org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper.toPropertyName;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jws.WebService;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Contract;
import org.apache.tuscany.sca.assembly.Multiplicity;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.implementation.java.IntrospectionException;
import org.apache.tuscany.sca.implementation.java.JavaConstructorImpl;
import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
import org.apache.tuscany.sca.implementation.java.JavaImplementation;
import org.apache.tuscany.sca.implementation.java.JavaParameterImpl;
import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
import org.apache.tuscany.sca.interfacedef.Interface;
import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.oasisopen.sca.ServiceReference;
import org.oasisopen.sca.annotation.Callback;
import org.oasisopen.sca.annotation.ComponentName;
import org.oasisopen.sca.annotation.Context;
import org.oasisopen.sca.annotation.Property;
import org.oasisopen.sca.annotation.Reference;
import org.oasisopen.sca.annotation.Remotable;
/**
* Heuristically evaluates an un-annotated Java implementation type to determine
* services, references, and properties according to the algorithm described in
* the SCA Java Client and Implementation Model Specification <p/> TODO
* Implement: <p/> When no service interface is annotated, need to calculate a
* single service comprising all public methods that are not reference or
* property injection sites. If that service can be exactly mapped to an
* interface implemented by the class then the service interface will be defined
* in terms of that interface.
*
* @version $Rev$ $Date$
*/
public class HeuristicPojoProcessor extends BaseJavaClassVisitor {
public HeuristicPojoProcessor(AssemblyFactory assemblyFactory, JavaInterfaceFactory javaFactory) {
super(assemblyFactory);
this.javaInterfaceFactory = javaFactory;
}
public HeuristicPojoProcessor(ExtensionPointRegistry registry) {
super(registry);
}
@Override
public <T> void visitEnd(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
List<org.apache.tuscany.sca.assembly.Service> services = type.getServices();
if (services.isEmpty()) {
// heuristically determine the service
/**
* The following is quoted from Java Specification 1.2.1.3. Introspecting services offered by a Java implementation
* In the cases described below, the services offered by a Java implementation class may be determined
* through introspection, eliding the need to specify them using @Service. The following algorithm is used
* to determine how services are introspected from an implementation class:
*
* If the interfaces of the SCA services are not specified with the @Service annotation on the
* implementation class, it is assumed that all implemented interfaces that have been annotated
* as @Remotable are the service interfaces provided by the component. If none of the implemented
* interfaces is remotable, then by default the implementation offers a single service whose type
* is the implementation class.
*/
Set<Class<?>> interfaces = getAllInterfaces(clazz);
for (Class<?> i : interfaces) {
if (i.isAnnotationPresent(Remotable.class) || i.isAnnotationPresent(WebService.class)) {
addService(type, i);
}
}
if (services.isEmpty()) {
// class is the interface
addService(type, clazz);
}
}
if (!(type.getReferenceMembers().isEmpty() && type.getPropertyMembers().isEmpty())) {
// references and properties have been explicitly defined
// if (type.getServices().isEmpty()) {
// calculateServiceInterface(clazz, type, methods);
// if (type.getServices().isEmpty()) {
// throw new ServiceTypeNotFoundException(clazz.getName());
// }
// }
evaluateConstructor(type, clazz);
return;
}
Set<Method> methods = getAllUniquePublicProtectedMethods(clazz, false);
calcPropRefs(methods, services, type, clazz);
evaluateConstructor(type, clazz);
}
// Check if the implementation is implementation.java
private boolean isImplementationJava(JavaImplementation type) {
return JavaImplementation.TYPE.equals(type.getType());
}
private void addService(JavaImplementation type, Class<?> clazz) throws IntrospectionException {
try {
org.apache.tuscany.sca.assembly.Service service = createService(clazz);
type.getServices().add(service);
} catch (InvalidInterfaceException e) {
throw new IntrospectionException(e);
}
}
private static boolean isAnnotatedWithSCA(AnnotatedElement element) {
for (Annotation a : element.getAnnotations()) {
// JCI_8023
// policy annotations can be added to reference fields that
// don't have @Reference annotations so we need to allow
// for the fields to be detected as references
if (isSCAPolicyAnnotation(a)){
continue;
} else if (isSCAAnnotation(a)) {
return true;
}
}
return false;
}
private static boolean isSCAAnnotation(Annotation a) {
return a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.");
}
private static boolean isSCAPolicyAnnotation(Annotation a) {
if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.PolicySets") ){
return true;
} else if (a.annotationType().getName().startsWith("org.oasisopen.sca.annotation.Intent") ){
return true;
} else {
return false;
}
}
private <T> void calcPropRefs(Set<Method> methods,
List<org.apache.tuscany.sca.assembly.Service> services,
JavaImplementation type,
Class<T> clazz) throws IntrospectionException {
// heuristically determine the properties references
// make a first pass through all public methods with one param
Set<String> setters = new HashSet<String>();
Set<String> others = new HashSet<String>();
for (Method method : methods) {
if (!isPublicSetter(method)) {
continue;
}
if (isAnnotatedWithSCA(method)) {
// Add the property name as others
others.add(toPropertyName(method.getName()));
continue;
}
if (!isInServiceInterface(method, services)) {
// Not part of the service interface
String name = toPropertyName(method.getName());
setters.add(name);
// avoid duplicate property or ref names
if (!type.getPropertyMembers().containsKey(name) && !type.getReferenceMembers().containsKey(name)) {
Class<?> param = method.getParameterTypes()[0];
Type genericType = method.getGenericParameterTypes()[0];
if (isReferenceType(param, genericType)) {
type.getReferences().add(createReference(name, param, genericType));
type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
} else {
type.getProperties().add(createProperty(name, param, genericType));
type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
}
}
}
}
// second pass for protected methods with one param
for (Method method : methods) {
if (!isProtectedSetter(method)) {
continue;
}
if (isAnnotatedWithSCA(method)) {
// Add the property name as others
others.add(toPropertyName(method.getName()));
continue;
}
Class<?> param = method.getParameterTypes()[0];
Type paramType = method.getGenericParameterTypes()[0];
String name = toPropertyName(method.getName());
setters.add(name);
// avoid duplicate property or ref names
if (isReferenceType(param, method.getGenericParameterTypes()[0])) {
if (!type.getReferenceMembers().containsKey(name)) {
type.getReferences().add(createReference(name, param, paramType));
type.getReferenceMembers().put(name, new JavaElementImpl(method, 0));
}
} else {
if (!type.getPropertyMembers().containsKey(name)) {
type.getProperties().add(createProperty(name, param, paramType));
type.getPropertyMembers().put(name, new JavaElementImpl(method, 0));
}
}
}
// Public or protected fields unless there is a public or protected
// setter method
// for the same name
Set<Field> fields = getAllPublicAndProtectedFields(clazz, false);
for (Field field : fields) {
if (isAnnotatedWithSCA(field)) {
continue;
}
if (setters.contains(field.getName()) || others.contains(field.getName())) {
continue;
}
String name = field.getName();
Class<?> paramType = field.getType();
Type genericType = field.getGenericType();
if (isReferenceType(paramType, field.getGenericType())) {
if (!type.getReferenceMembers().containsKey(name)) {
type.getReferences().add(createReference(name, paramType, genericType));
type.getReferenceMembers().put(name, new JavaElementImpl(field));
}
} else {
if (!type.getPropertyMembers().containsKey(name)) {
type.getProperties().add(createProperty(name, paramType, genericType));
type.getPropertyMembers().put(name, new JavaElementImpl(field));
}
}
}
}
/**
* Determines the constructor to use based on the component type's
* references and properties
*
* @param type the component type
* @param clazz the implementation class corresponding to the component type
* @throws NoConstructorException if no suitable constructor is found
* @throws AmbiguousConstructorException if the parameters of a constructor
* cannot be unambiguously mapped to references and properties
*/
@SuppressWarnings("unchecked")
private <T> void evaluateConstructor(JavaImplementation type, Class<T> clazz) throws IntrospectionException {
// determine constructor if one is not annotated
JavaConstructorImpl<?> definition = type.getConstructor();
Constructor constructor;
boolean explict = false;
if (definition != null && definition.getConstructor()
.isAnnotationPresent(org.oasisopen.sca.annotation.Constructor.class)) {
// the constructor was already defined explicitly
return;
} else if (definition != null) {
explict = true;
constructor = definition.getConstructor();
} else {
if (!isImplementationJava(type)) {
// FIXME: [rfeng] Don't process the constructors for non implementation.java types
return;
}
// no definition, heuristically determine constructor
Constructor[] constructors = clazz.getConstructors();
if (constructors.length == 0) {
throw new NoConstructorException("[JCI50001] No public constructor for class");
} else if (constructors.length == 1) {
// Only one constructor, take it
constructor = constructors[0];
} else {
Constructor<T> selected = null;
for (Constructor<T> ctor : constructors) {
if (allArgsAnnotated(ctor)) {
selected = ctor;
for (Constructor<T> ctor2 : constructors) {
if (selected != ctor2 && allArgsAnnotated(ctor2)) {
throw new InvalidConstructorException("[JCI50005] Multiple annotated constructors");
}
}
}
}
if (selected == null) {
for (Constructor<T> ctor : constructors) {
if (ctor.getParameterTypes().length == 0) {
selected = ctor;
break;
}
}
}
if (selected == null) {
throw new NoConstructorException();
}
constructor = selected;
definition = type.getConstructors().get(selected);
type.setConstructor(definition);
}
definition = type.getConstructors().get(constructor);
type.setConstructor(definition);
}
JavaParameterImpl[] parameters = definition.getParameters();
if (parameters.length == 0) {
return;
}
Map<String, JavaElementImpl> props = type.getPropertyMembers();
Map<String, JavaElementImpl> refs = type.getReferenceMembers();
Annotation[][] annotations = constructor.getParameterAnnotations();
if (!explict) {
// the constructor wasn't defined by an annotation, so check to see
// if any of the params have an annotation
// which we can impute as explicitly defining the constructor, e.g.
// @Property, @Reference, or @Autowire
explict = injectionAnnotationsPresent(annotations);
}
if (explict) {
for (int i = 0; i < parameters.length; i++) {
if (isAnnotated(parameters[i])) {
continue;
} else if (!findReferenceOrProperty(parameters[i], props, refs)) {
throw new AmbiguousConstructorException(parameters[i].toString());
}
}
} else {
if (!areUnique(parameters)) {
throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
}
if (!calcPropRefUniqueness(props.values(), refs.values())) {
throw new AmbiguousConstructorException("Cannot resolve non-unique parameter types, use @Constructor");
}
if (!(props.isEmpty() && refs.isEmpty())) {
calcParamNames(parameters, props, refs);
} else {
heuristicParamNames(type, parameters);
}
}
}
private boolean allArgsAnnotated(Constructor<?> ctor) {
if (ctor.getParameterTypes().length < 1) {
return false;
}
for (Annotation[] as : ctor.getParameterAnnotations()) {
if (as.length < 1) {
return false;
}
}
return true;
}
private void calcParamNames(JavaParameterImpl[] parameters,
Map<String, JavaElementImpl> props,
Map<String, JavaElementImpl> refs) throws AmbiguousConstructorException {
// the constructor param types must unambiguously match defined
// reference or property types
for (JavaParameterImpl param : parameters) {
if (!findReferenceOrProperty(param, props, refs)) {
throw new AmbiguousConstructorException(param.getName());
}
}
}
private void heuristicParamNames(JavaImplementation type, JavaParameterImpl[] parameters)
throws IntrospectionException {
// heuristically determine refs and props from the parameter types
for (JavaParameterImpl p : parameters) {
String name = p.getType().getSimpleName().toLowerCase();
if (isReferenceType(p.getType(), p.getGenericType())) {
type.getReferences().add(createReference(name, p.getType(), p.getGenericType()));
p.setClassifer(Reference.class);
type.getReferenceMembers().put(name, p);
} else {
type.getProperties().add(createProperty(name, p.getType(), p.getGenericType()));
p.setClassifer(Property.class);
type.getPropertyMembers().put(name, p);
}
p.setName(name);
}
}
/**
* Returns true if the union of the given collections of properties and
* references have unique Java types
*/
private boolean calcPropRefUniqueness(Collection<JavaElementImpl> props, Collection<JavaElementImpl> refs) {
Class<?>[] classes = new Class[props.size() + refs.size()];
int i = 0;
for (JavaElementImpl property : props) {
classes[i] = property.getType();
i++;
}
for (JavaElementImpl reference : refs) {
classes[i] = reference.getType();
i++;
}
return areUnique(classes);
}
/**
* Unambiguously finds the reference or property associated with the given
* type
*
* @return the name of the reference or property if found, null if not
* @throws AmbiguousConstructorException if the constructor parameter cannot
* be resolved to a property or reference
*/
private boolean findReferenceOrProperty(JavaParameterImpl parameter,
Map<String, JavaElementImpl> props,
Map<String, JavaElementImpl> refs) throws AmbiguousConstructorException {
boolean found = false;
if (!"".equals(parameter.getName())) {
// Match by name
JavaElementImpl prop = props.get(parameter.getName());
if (prop != null && prop.getType() == parameter.getType()) {
parameter.setClassifer(Property.class);
return true;
}
JavaElementImpl ref = refs.get(parameter.getName());
if (ref != null && ref.getType() == parameter.getType()) {
parameter.setClassifer(Reference.class);
return true;
}
}
for (JavaElementImpl property : props.values()) {
if (property.getType() == parameter.getType()) {
if (found) {
throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
(Member)parameter.getAnchor());
}
parameter.setClassifer(Property.class);
parameter.setName(property.getName());
found = true;
// do not break since ambiguities must be checked, i.e. more
// than one prop or ref of the same type
}
}
for (JavaElementImpl reference : refs.values()) {
if (reference.getType() == parameter.getType()) {
if (found) {
throw new AmbiguousConstructorException("Ambiguous property or reference for constructor type",
(Member)parameter.getAnchor());
}
parameter.setClassifer(Reference.class);
parameter.setName(reference.getName());
found = true;
// do not break since ambiguities must be checked, i.e. more
// than one prop or ref of the same type
}
}
return found;
}
/**
* Creates a mapped property.
*
* @param name the property name
* @param paramType the property type
*/
private org.apache.tuscany.sca.assembly.Property createProperty(String name, Class<?> javaClass, Type genericType) {
return AbstractPropertyProcessor.createProperty(assemblyFactory, name, javaClass, genericType);
}
private org.apache.tuscany.sca.assembly.Reference createReference(String name, Class<?> paramType,
Type genericType )
throws IntrospectionException {
org.apache.tuscany.sca.assembly.Reference reference = assemblyFactory.createReference();
reference.setName(name);
JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
reference.setInterfaceContract(interfaceContract);
// Compute the interface type dealing with array/Collection types and with Generic types
Class<?> baseType = getBaseType(paramType, genericType);
if (ServiceReference.class.isAssignableFrom(baseType)) {
if (Collection.class.isAssignableFrom(paramType)) {
genericType = JavaIntrospectionHelper.getParameterType(genericType);
}
baseType = JavaIntrospectionHelper.getBusinessInterface(baseType, genericType);
} // end if
try {
JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(baseType);
reference.getInterfaceContract().setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
reference.getInterfaceContract().setCallbackInterface(callbackInterface);
}
// Multiplicity of an implicit reference is 1..1 for a simple interface type
// and 1..n for an array of interface or Collection of interface type
// as defined in the OASIS SCA Java POJO specification, section 8.1 : TUSCANY-3636
if( isCollectionType( paramType ) || isArrayType( paramType )) {
reference.setMultiplicity(Multiplicity.ONE_N);
} else {
reference.setMultiplicity(Multiplicity.ONE_ONE);
} // end if
} catch (InvalidInterfaceException e1) {
throw new IntrospectionException(e1);
} // end try
// FIXME: This part seems to have already been taken care above!!
try {
processCallback(paramType, reference);
} catch (InvalidServiceTypeException e) {
throw new IntrospectionException(e);
}
return reference;
}
/**
* Reports if a parameter type is a form of java.util.Collection
* @param paramType
* @return true if paramType is a form of java.util.Collection, false otherwise
*/
private boolean isCollectionType( Class<?> paramType ) {
if( Collection.class.isAssignableFrom(paramType) ) return true;
return false;
}
/**
* Reports if a parameter type is an array
* @param paramType
* @return true if paramType is an array
*/
private boolean isArrayType( Class<?> paramType ) {
if( paramType.isArray() ) return true;
return false;
}
private org.apache.tuscany.sca.assembly.Service createService(Class<?> interfaze) throws InvalidInterfaceException {
org.apache.tuscany.sca.assembly.Service service = assemblyFactory.createService();
service.setName(interfaze.getSimpleName());
JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
service.setInterfaceContract(interfaceContract);
JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(interfaze);
service.getInterfaceContract().setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
service.getInterfaceContract().setCallbackInterface(callbackInterface);
}
Interface javaInterface = service.getInterfaceContract().getInterface();
javaInterface.setRemotable(interfaze.getAnnotation(Remotable.class) != null);
service.getInterfaceContract().setInterface(javaInterface);
return service;
}
private void processCallback(Class<?> interfaze, Contract contract) throws InvalidServiceTypeException {
Callback callback = interfaze.getAnnotation(Callback.class);
if (callback != null && !Void.class.equals(callback.value())) {
Class<?> callbackClass = callback.value();
JavaInterface javaInterface;
try {
javaInterface = javaInterfaceFactory.createJavaInterface(callbackClass);
contract.getInterfaceContract().setCallbackInterface(javaInterface);
} catch (InvalidInterfaceException e) {
throw new InvalidServiceTypeException("Invalid callback interface "+callbackClass, interfaze);
}
} else if (callback != null && Void.class.equals(callback.value())) {
throw new InvalidServiceTypeException("No callback interface specified on annotation", interfaze);
}
}
/**
* Utility methods
*/
/**
* Verify if the method is a public setter
* @param method
* @return
*/
private static boolean isPublicSetter(Method method) {
return method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers())
&& method.getName().startsWith("set")
&& method.getReturnType() == void.class;
}
/**
* Verify if the method is a protected setter
* @param method
* @return
*/
private static boolean isProtectedSetter(Method method) {
return method.getParameterTypes().length == 1 && Modifier.isProtected(method.getModifiers())
&& method.getName().startsWith("set")
&& method.getReturnType() == void.class;
}
/**
* @param collection
* @return
*/
private static boolean areUnique(Class<?>[] collection) {
Set<Class<?>> set = new HashSet<Class<?>>(Arrays.asList(collection));
return set.size() == collection.length;
}
/**
* Returns true if a given type is reference according to the SCA
* specification rules for determining reference types The following rules
* are used to determine whether an unannotated field or setter method is a
* property or reference:
* <ol>
* <li>If its type is simple, then it is a property.
* <li>If its type is complex, then if the type is an interface marked by
*
* @Remotable, then it is a reference; otherwise, it is a property.
* <li>Otherwise, if the type associated with the member is an
* array or a java.util.Collection, the basetype is the element
* type of the array or the parameterized type of the
* Collection; otherwise the basetype is the member type. If the
* basetype is an interface with an
* @Remotable or
* @Service annotation then the member is defined as a reference. Otherwise,
* it is defined as a property.
* </ol>
* <p>
* The name of the reference or of the property is derived from the
* name found on the setter method or on the field.
*/
// FIXME: [rfeng] What if it's a collection of references?
private static boolean isReferenceType(Class<?> cls, Type genericType) {
Class<?> baseType = JavaIntrospectionHelper.getBaseType(cls, genericType);
return baseType.isInterface() && baseType.isAnnotationPresent(Remotable.class);
}
/**
* Returns true if the given operation is defined in the collection of
* service interfaces
* @param operation
* @param services
* @return
*/
private static boolean isInServiceInterface(Method operation, List<org.apache.tuscany.sca.assembly.Service> services) {
for (org.apache.tuscany.sca.assembly.Service service : services) {
Interface interface1 = service.getInterfaceContract().getInterface();
if (interface1 instanceof JavaInterface) {
Class<?> clazz = ((JavaInterface)interface1).getJavaClass();
if (isMethodMatched(clazz, operation)) {
return true;
}
}
}
return false;
}
/**
* Test if the class declares a method which matches the signature of the
* given method
*
* @param clazz
* @param method
* @return
*/
private static boolean isMethodMatched(Class<?> clazz, Method method) {
if (method.getDeclaringClass() == clazz) {
return true;
}
Method[] methods = clazz.getMethods();
for (Method m : methods) {
if (JavaIntrospectionHelper.exactMethodMatch(method, m)) {
return true;
}
}
return false;
}
/**
* Verify if there is any SCA annotation on the parameter
* @param parameter
* @return
*/
private static boolean isAnnotated(JavaParameterImpl parameter) {
for (Annotation annotation : parameter.getAnnotations()) {
if (isSCAAnnotation(annotation)) {
return true;
}
}
return false;
}
/**
* Verify if the parameters are unique
* @param parameters
* @return
*/
private static boolean areUnique(JavaParameterImpl[] parameters) {
Set<Class<?>> set = new HashSet<Class<?>>(parameters.length);
for (JavaParameterImpl p : parameters) {
if (!set.add(p.getType())) {
return false;
}
}
return true;
}
/**
* Verify if the annotations are SCA annotation
* @param annots
* @return
*/
private static boolean injectionAnnotationsPresent(Annotation[][] annots) {
for (Annotation[] annotations : annots) {
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotType = annotation.annotationType();
if (annotType == Property.class || annotType == Reference.class
|| annotType == Resource.class
|| annotType == ComponentName.class
|| annotType == Context.class
|| annotType == Callback.class) {
return true;
}
}
}
return false;
}
}