package org.easysoa.discovery.code.handler.consumption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.easysoa.discovery.code.ParsingUtils;
import org.easysoa.discovery.code.model.JavaServiceConsumptionInformation;
import org.easysoa.discovery.code.model.JavaServiceInterfaceInformation;
import org.easysoa.registry.types.ServiceConsumption;
import org.easysoa.registry.types.java.MavenDeliverable;
import com.thoughtworks.qdox.model.AbstractJavaEntity;
import com.thoughtworks.qdox.model.BeanProperty;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.thoughtworks.qdox.model.JavaSource;
import com.thoughtworks.qdox.model.Type;
public class AnnotatedServicesConsumptionFinder implements ServiceConsumptionFinder {
// configuration :
private boolean allInjected = true;
/** whether not to find test consumptions (default false) */
private boolean filterSources = false;
private List<String> annotationsToDetect;
public AnnotatedServicesConsumptionFinder(List<String> annotationsToDetect) {
this.annotationsToDetect = annotationsToDetect;
if (this.annotationsToDetect == null) {
this.annotationsToDetect = new ArrayList<String>();
}
}
public void addAnnotationToDetect(String annotationToDetect) {
annotationsToDetect.add(annotationToDetect);
}
/**
* Default value: true
* @param allInjected
*/
public void setAllInjected(boolean allInjected) {
this.allInjected = allInjected;
}
/**
* Default value: true
* @param filterSources
*/
public void setFilterSources(boolean filterSources) {
this.filterSources = filterSources;
}
@Override
public List<JavaServiceConsumptionInformation> find(JavaSource javaSource,
MavenDeliverable mavenDeliverable, Map<String, JavaServiceInterfaceInformation> serviceInterfaces) throws Exception {
List<JavaServiceConsumptionInformation> discoveredConsumptions = new LinkedList<JavaServiceConsumptionInformation>();
// NB. JAXWS WebServiceClient (generated client stub) not reported as such but through injection below
// (though they could be, as "connector" TODO)
// member injected by WebService annotated interfaces, WebServiceClients (generated client stub) or WebServiceRefs :
for (JavaClass c : javaSource.getClasses()) {
if (!filterSources || !ParsingUtils.isTestClass(c)) {
// Java 6 (and other methods) injection of fields by service-annotated interfaces
// in injected fields :
HashSet<String> injectedBeanProperties = new HashSet<String>();
for (JavaField javaField : c.getFields()) { // TODO also superfields...
addConsumerFoundInInjectedMember(discoveredConsumptions, c, javaField, javaField.getType(),
javaField.getName(), injectedBeanProperties, serviceInterfaces, mavenDeliverable);
}
// in injected setters :
for (BeanProperty beanProperty : c.getBeanProperties()) {
JavaMethod method = beanProperty.getMutator();
if (method != null) {
JavaParameter[] parameters = method.getParameters();
if (parameters.length == 1) {
addConsumerFoundInInjectedMember(discoveredConsumptions, c, method, parameters[0].getType(),
beanProperty.getName(), injectedBeanProperties, serviceInterfaces, mavenDeliverable);
}
}
}
}
}
return discoveredConsumptions;
}
private void addConsumerFoundInInjectedMember(List<JavaServiceConsumptionInformation> discoveredConsumptions,
JavaClass fromClass, AbstractJavaEntity injectedMember, Type injectedType,
String beanPropertyName, HashSet<String> injectedBeanProperties,
Map<String, JavaServiceInterfaceInformation> serviceInterfaces,
MavenDeliverable mavenDeliverable) throws Exception {
if (injectedBeanProperties.contains(beanPropertyName)) {
return;
}
String injectionAnnotation = getInjectionAnnotation(injectedMember);
if (allInjected || injectionAnnotation != null) {
String itfClassName = injectedType.getFullyQualifiedName();
if (serviceInterfaces.containsKey(itfClassName)) {
JavaServiceConsumptionInformation scInfo = new JavaServiceConsumptionInformation(
fromClass.getFullyQualifiedName(), serviceInterfaces.get(itfClassName));
if (injectedMember.getComment() != null) {
scInfo.setProperty(ServiceConsumption.XPATH_DOCUMENTATION,
injectedMember.getName() + ((injectedMember.getComment() == null) ?
"" : ": " + injectedMember.getComment()));
}
scInfo.setProperty(ServiceConsumption.XPATH_ISTEST, ParsingUtils.isTestClass(fromClass));
discoveredConsumptions.add(scInfo);
injectedBeanProperties.add(beanPropertyName);
}
}
}
private String getInjectionAnnotation(AbstractJavaEntity javaInjectionMember) {
for (String injectionAnnotation : this.annotationsToDetect) {
if (ParsingUtils.hasAnnotation(javaInjectionMember, injectionAnnotation)) {
return injectionAnnotation;
}
}
return null;
}
}