
com.oneandone.iocunit.analyzer.Configuration Maven / Gradle / Ivy
package com.oneandone.iocunit.analyzer;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Stereotype;
import javax.enterprise.inject.spi.Extension;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.oneandone.iocunit.analyzer.annotations.AnalyzerFlags;
/**
* @author aschoerk
*/
public class Configuration {
enum Phase {
UNKNOWN,
ANALYZING,
MATCHING,
FIXING,
WARNING,
INITIALIZING;
}
public boolean allowGuessing = true;
public boolean produceInstanceInjectsByAvailables = false;
public boolean addAllStartableBeans = false;
public boolean addAvailableInterceptorsAndDecorators = false;
public List> excludedExtensions;
public List> initialAvailables = new ArrayList<>();
Set> injectAnnotations = new HashSet<>();
public Configuration(final TesterExtensionsConfigsFinder a) {
this.testerExtensionsConfigsFinder = a;
injectAnnotations.add(Inject.class);
injectAnnotations.addAll(a.injectAnnotations);
initialAvailables.addAll(a.initialAvailableClasses);
}
private Class> theTestClass;
public Class> getTheTestClass() {
return theTestClass;
}
private void handleAnalyzerFlags(Class> aClass) {
if (aClass.equals(Object.class))
return;
AnalyzerFlags analyzerFlags = aClass.getAnnotation(AnalyzerFlags.class);
handleAnalyzerFlags(aClass.getSuperclass());
if (analyzerFlags != null) {
this.allowGuessing = analyzerFlags.allowGuessing();
this.produceInstanceInjectsByAvailables = analyzerFlags.produceInstanceInjectsByAvailables();
this.addAllStartableBeans = analyzerFlags.addAllStartableBeans();
this.addAvailableInterceptorsAndDecorators = analyzerFlags.addAvailableInterceptorsAndDecorators();
this.excludedExtensions = Arrays.asList(analyzerFlags.excludedExtensions());
}
}
public void setTheTestClass(final Class> testClass) {
this.theTestClass = testClass;
handleAnalyzerFlags(testClass);
}
private Phase phase = Phase.UNKNOWN;
public void setPhase(final Phase phase) {
this.phase = phase;
}
public TesterExtensionsConfigsFinder testerExtensionsConfigsFinder = null;
Logger logger = LoggerFactory.getLogger(Configuration.class);
// used to separate classes which might have configuring annotations and might have priority over
// each other in case of injections.
private Set> testClasses = new HashSet<>();
private Set> enabledAlternatives = new HashSet<>();
// candidates to be started.
// The testclass, all classes found in @TestClasses
// classes usable to fill injects in beansToBeStarted.
private List> beansToBeStarted = new ArrayList<>(); // these beans must be given to CDI to be started
// the testclass itself and beans defined by @TestClasses or @SutClasses, or by services
private List> obligatory = new ArrayList<>();
// classes defined to be excluded from configuration. Done by servcices or @ExcludedClasses
private Set> excluded = new HashSet<>();
private Set testClassPaths = new HashSet<>();
public Set getTestClassPaths() {
return testClassPaths;
}
public void addCandidate(Class> c) {
if(!candidates.contains(c)) {
candidates.add(c);
}
else {
if(phase != Phase.ANALYZING && phase != Phase.INITIALIZING) {
logger.debug("candidates already contains {}", c);
}
}
}
public boolean isCandidate(Class> c) {
return candidates.contains(c);
}
public void moveCandidates(Collection> dest) {
dest.addAll(candidates);
candidates.clear();
}
public boolean emptyCandidates() {
return candidates.isEmpty();
}
// previously available classes to be added to the startconfiguration
private List> candidates = new ArrayList<>();
// classes available to be added to configuration
private Set> available = new HashSet<>();
private boolean availablesChanged = false;
// producers available from obligatory and candidates
private ProducerMap producerMap = new ProducerMap(this, "Obligatory");
// producers found in availables
private ProducerMap availableProducerMap = new ProducerMap(this, "Available");
// producers created by enabled Alternatives
private ProducerMap alternativesProducerMap = new ProducerMap(this, "Alternatives");
// injects found in obligatory and candidates
private Set injects = new HashSet();
// Instance-injects found in obligatory and candidates
private Set instanceInjects = new HashSet();
// injects found in obligatory and candidates which are handled
private Set handledInjects = new HashSet();
private HashMultiMap, QualifiedType> classes2Injects = new HashMultiMap<>();
private ElseClasses elseClasses = new ElseClasses();
/**
* signify clazz as sutClass
*
* @param clazz
* @return
*/
Configuration sutClass(Class> clazz) {
testClasses.remove(clazz);
return this;
}
/**
* signify clazz as testclass
*
* @param clazz
* @return
*/
Configuration testClass(Class> clazz) {
testClasses.add(clazz);
final CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
if (codeSource != null)
testClassPaths.add(codeSource.getLocation());
return this;
}
public Configuration testClassCandidates(final Collection> classes) {
if(classes != null) {
for (Class> c : classes)
testClass(c)
.candidate(c);
}
return this;
}
/**
* signify clazz as to be included in starting configuration
*
* @param clazz
* @return
*/
Configuration obligatory(Class> clazz) {
obligatory.add(clazz);
available.add(clazz);
return this;
}
/**
* signify class as available for starting configuration
*
* @param clazz
* @return
*/
Configuration available(Class> clazz) {
if (!available.contains(clazz)) {
available.add(clazz);
availablesChanged = true;
}
return this;
}
public Configuration candidate(final Class> c) {
addCandidate(c);
return this;
}
public Configuration enabledAlternative(final Class> c) {
if(c.getAnnotation(Alternative.class) == null || c.isAnnotation() && c.getAnnotation(Stereotype.class) == null) {
logger.error("Invalid enabled Alternative {}", c.getName());
}
if(c.isAnnotation() && c.getAnnotation(Stereotype.class) != null) {
elseClasses.foundAlternativeStereotypes.add(c);
}
else {
enabledAlternatives.add(c);
}
return this;
}
public Configuration excluded(final Class> c) {
excluded.add(c);
return this;
}
public boolean isExcluded(final Class> c) {
return excluded.contains(c);
}
public Configuration tobeStarted(final Class> c) {
addToBeStarted(c);
return this;
}
public boolean isToBeStarted(Class> c) {
return beansToBeStarted.contains(c);
}
public void setTesterExtensionsConfigsFinder(final TesterExtensionsConfigsFinder testerExtensionsConfigsFinderP) {
this.testerExtensionsConfigsFinder = testerExtensionsConfigsFinderP;
}
public boolean isTestClass(final Class c) {
return testClasses.contains(c);
}
public Configuration inject(final QualifiedType i) {
logger.trace("Adding Inject {}", i);
injects.add(i);
if (i.isInstance() && produceInstanceInjectsByAvailables) {
logger.info("Found Instance-Inject {} will be filled by all found availables.",i);
instanceInjects.add(i);
} else {
injects.add(i);
}
return this;
}
Configuration elseClass(Class> c) {
elseClasses.elseClass(c);
return this;
}
public boolean isAvailable(final Class extends Annotation> annotationType) {
return available.contains(annotationType);
}
public ProducerMap getProducerMap() {
return producerMap;
}
public ProducerMap getAvailableProducerMap() {
return availableProducerMap;
}
public ProducerMap getAlternativesProducerMap() {
return alternativesProducerMap;
}
public Set getInjects() {
return injects;
}
public Set> getExcludedClasses() {
return excluded;
}
public boolean isActiveAlternativeStereoType(final Annotation c) {
logger.trace("Searching for alternative Stereotype {}", c);
for (Class stereoType : elseClasses.foundAlternativeStereotypes) {
if(stereoType.getName().equals(c.annotationType().getName())) {
logger.trace("Search found alternative Stereotype {}", c);
return true;
}
}
return false;
}
public boolean isEnabledAlternative(final Class declaringClass) {
return enabledAlternatives.contains(declaringClass);
}
public void addToBeStarted(Class> c) {
if(beansToBeStarted.contains(c)) {
logger.warn("Trying to add {} testerExtensionsConfigsFinder second time", c);
}
else {
beansToBeStarted.add(c);
obligatory.add(c);
}
}
public boolean isSuTClass(final Class declaringClass) {
return !testClasses.contains(declaringClass);
}
void injectHandled(QualifiedType inject, final QualifiedType producingType) {
injects.remove(inject);
handledInjects.add(inject);
if(producingType != null) {
classes2Injects.put(producingType.getDeclaringClass(), inject);
}
}
Set getInjectsForClass(Class> key) {
return classes2Injects.get(key);
}
public ElseClasses getElseClasses() {
return elseClasses;
}
public Set> getEnabledAlternatives() {
return enabledAlternatives;
}
public List> getObligatory() {
return obligatory;
}
public Set getInstanceInjects() {
return instanceInjects;
}
public boolean isAvailablesChanged() {
return availablesChanged;
}
public void setAvailablesChanged(final boolean availablesChanged) {
this.availablesChanged = availablesChanged;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy