import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.Decorator;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Project;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import java.util.ArrayList;
import java.util.Collection;
}
public Collection<Decorator> select(Project project) {
- List<Decorator> decorators = new ArrayList<Decorator>(batchExtDictionnary.select(Decorator.class, project, false));
+ List<Decorator> decorators = new ArrayList<Decorator>(batchExtDictionnary.select(Decorator.class, project, false, null));
SetMultimap<Metric, Decorator> decoratorsByGeneratedMetric = getDecoratorsByMetric(decorators);
- for (Metric metric : batchExtDictionnary.select(Metric.class)) {
+ for (Metric metric : batchExtDictionnary.select(Metric.class, null, false, null)) {
if (metric.getFormula() != null) {
decorators.add(new FormulaDecorator(metric, decoratorsByGeneratedMetric.get(metric)));
}
*/
package org.sonar.batch.bootstrap;
-import org.sonar.batch.sensor.AnalyzerOptimizer;
-
+import com.google.common.base.Predicates;
+import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import org.apache.commons.lang.ClassUtils;
+import org.sonar.api.BatchExtension;
import org.sonar.api.batch.CheckProject;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.Phase;
+import org.sonar.api.batch.maven.DependsUponMavenPlugin;
+import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
+import org.sonar.api.utils.AnnotationUtils;
+import org.sonar.api.utils.dag.DirectAcyclicGraph;
import org.sonar.batch.scan.SensorWrapper;
+import org.sonar.batch.sensor.AnalyzerOptimizer;
import org.sonar.batch.sensor.DefaultSensorContext;
import javax.annotation.Nullable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @since 2.6
*/
-public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensionDictionnary {
+public class BatchExtensionDictionnary {
- private SensorContext context;
- private AnalyzerOptimizer analyzerOptimizer;
+ private final ComponentContainer componentContainer;
+ private final SensorContext context;
+ private final AnalyzerOptimizer analyzerOptimizer;
public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext context, AnalyzerOptimizer analyzerOptimizer) {
- super(componentContainer);
+ this.componentContainer = componentContainer;
this.context = context;
this.analyzerOptimizer = analyzerOptimizer;
}
return result;
}
- @Override
- protected Phase.Name evaluatePhase(Object extension) {
+ public Collection<MavenPluginHandler> selectMavenPluginHandlers(Project project) {
+ List<DependsUponMavenPlugin> selectedExtensions = Lists.newArrayList();
+ for (Object extension : getExtensions(null)) {
+ if (ClassUtils.isAssignable(extension.getClass(), DependsUponMavenPlugin.class)) {
+ selectedExtensions.add((DependsUponMavenPlugin) extension);
+ }
+ }
+ List<MavenPluginHandler> handlers = Lists.newArrayList();
+ for (DependsUponMavenPlugin extension : selectedExtensions) {
+ MavenPluginHandler handler = extension.getMavenPluginHandler(project);
+ if (handler != null) {
+ boolean ok = true;
+ if (handler instanceof CheckProject) {
+ ok = ((CheckProject) handler).shouldExecuteOnProject(project);
+ }
+ if (ok) {
+ handlers.add(handler);
+ }
+ }
+ }
+ return handlers;
+ }
+
+ private Phase.Name evaluatePhase(Object extension) {
+ Object extensionToEvaluate;
if (extension instanceof SensorWrapper) {
- return super.evaluatePhase(((SensorWrapper) extension).wrappedSensor());
+ extensionToEvaluate = ((SensorWrapper) extension).wrappedSensor();
} else {
- return super.evaluatePhase(extension);
+ extensionToEvaluate = extension;
+ }
+ Phase phaseAnnotation = AnnotationUtils.getAnnotation(extensionToEvaluate, Phase.class);
+ if (phaseAnnotation != null) {
+ return phaseAnnotation.name();
}
+ return Phase.Name.DEFAULT;
}
private <T> List<T> getFilteredExtensions(Class<T> type, @Nullable Project project, @Nullable ExtensionMatcher matcher) {
return result;
}
+ protected List<Object> getExtensions(@Nullable Class type) {
+ List<Object> extensions = Lists.newArrayList();
+ completeBatchExtensions(componentContainer, extensions, type);
+ return extensions;
+ }
+
+ private static void completeBatchExtensions(ComponentContainer container, List<Object> extensions, @Nullable Class type) {
+ if (container != null) {
+ extensions.addAll(container.getComponentsByType(type != null ? type : BatchExtension.class));
+ completeBatchExtensions(container.getParent(), extensions, type);
+ }
+ }
+
+ public <T> Collection<T> sort(Collection<T> extensions) {
+ DirectAcyclicGraph dag = new DirectAcyclicGraph();
+
+ for (T extension : extensions) {
+ dag.add(extension);
+ for (Object dependency : getDependencies(extension)) {
+ dag.add(extension, dependency);
+ }
+ for (Object generates : getDependents(extension)) {
+ dag.add(generates, extension);
+ }
+ completePhaseDependencies(dag, extension);
+ }
+ List sortedList = dag.sort();
+
+ return Collections2.filter(sortedList, Predicates.in(extensions));
+ }
+
+ /**
+ * Extension dependencies
+ */
+ private <T> List<Object> getDependencies(T extension) {
+ List<Object> result = new ArrayList<Object>();
+ result.addAll(evaluateAnnotatedClasses(extension, DependsUpon.class));
+ return result;
+ }
+
+ /**
+ * Objects that depend upon this extension.
+ */
+ public <T> List<Object> getDependents(T extension) {
+ List<Object> result = new ArrayList<Object>();
+ result.addAll(evaluateAnnotatedClasses(extension, DependedUpon.class));
+ return result;
+ }
+
+ private void completePhaseDependencies(DirectAcyclicGraph dag, Object extension) {
+ Phase.Name phase = evaluatePhase(extension);
+ dag.add(extension, phase);
+ for (Phase.Name name : Phase.Name.values()) {
+ if (phase.compareTo(name) < 0) {
+ dag.add(name, extension);
+ } else if (phase.compareTo(name) > 0) {
+ dag.add(extension, name);
+ }
+ }
+ }
+
+ protected List<Object> evaluateAnnotatedClasses(Object extension, Class<? extends Annotation> annotation) {
+ List<Object> results = Lists.newArrayList();
+ Class aClass = extension.getClass();
+ while (aClass != null) {
+ evaluateClass(aClass, annotation, results);
+
+ for (Method method : aClass.getDeclaredMethods()) {
+ if (method.getAnnotation(annotation) != null) {
+ checkAnnotatedMethod(method);
+ evaluateMethod(extension, method, results);
+ }
+ }
+ aClass = aClass.getSuperclass();
+ }
+
+ return results;
+ }
+
+ private void evaluateClass(Class extensionClass, Class annotationClass, List<Object> results) {
+ Annotation annotation = extensionClass.getAnnotation(annotationClass);
+ if (annotation != null) {
+ if (annotation.annotationType().isAssignableFrom(DependsUpon.class)) {
+ results.addAll(Arrays.asList(((DependsUpon) annotation).value()));
+
+ } else if (annotation.annotationType().isAssignableFrom(DependedUpon.class)) {
+ results.addAll(Arrays.asList(((DependedUpon) annotation).value()));
+ }
+ }
+
+ Class[] interfaces = extensionClass.getInterfaces();
+ for (Class anInterface : interfaces) {
+ evaluateClass(anInterface, annotationClass, results);
+ }
+ }
+
+ private void evaluateMethod(Object extension, Method method, List<Object> results) {
+ try {
+ Object result = method.invoke(extension);
+ if (result != null) {
+ if (result instanceof Class<?>) {
+ results.addAll(componentContainer.getComponentsByType((Class<?>) result));
+
+ } else if (result instanceof Collection<?>) {
+ results.addAll((Collection<?>) result);
+
+ } else if (result.getClass().isArray()) {
+ for (int i = 0; i < Array.getLength(result); i++) {
+ results.add(Array.get(result, i));
+ }
+
+ } else {
+ results.add(result);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException("Can not invoke method " + method, e);
+ }
+ }
+
+ private void checkAnnotatedMethod(Method method) {
+ if (!Modifier.isPublic(method.getModifiers())) {
+ throw new IllegalStateException("Annotated method must be public:" + method);
+ }
+ if (method.getParameterTypes().length > 0) {
+ throw new IllegalStateException("Annotated method must not have parameters:" + method);
+ }
+ }
+
private boolean shouldKeep(Class type, Object extension, @Nullable Project project, @Nullable ExtensionMatcher matcher) {
boolean keep = (ClassUtils.isAssignable(extension.getClass(), type)
|| (org.sonar.api.batch.Sensor.class.equals(type) && ClassUtils.isAssignable(extension.getClass(), Sensor.class)))
import com.google.common.collect.Lists;
import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.DecoratorsSelector;
import org.sonar.batch.DefaultDecoratorContext;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.scan.measure.MeasureCache;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.Initializer;
import org.sonar.api.batch.maven.DependsUponMavenPlugin;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.TimeProfiler;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
}
public void execute() {
- Collection<Initializer> initializers = selector.select(Initializer.class, project, true);
+ Collection<Initializer> initializers = selector.select(Initializer.class, project, true, null);
eventBus.fireEvent(new InitializersPhaseEvent(Lists.newArrayList(initializers), true));
if (LOG.isDebugEnabled()) {
LOG.debug("Initializers : {}", StringUtils.join(initializers, " -> "));
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.PostJob;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.maven.DependsUponMavenPlugin;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
private final EventBus eventBus;
public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor,
- EventBus eventBus) {
+ EventBus eventBus) {
this.selector = selector;
this.project = project;
this.fs = fs;
}
public void execute(SensorContext context) {
- Collection<PostJob> postJobs = selector.select(PostJob.class, project, true);
+ Collection<PostJob> postJobs = selector.select(PostJob.class, project, true, null);
eventBus.fireEvent(new PostJobPhaseEvent(Lists.newArrayList(postJobs), true));
execute(context, postJobs);
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.maven.MavenPlugin;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import java.io.File;
import java.io.FileOutputStream;
*/
package org.sonar.batch.source;
+import org.sonar.api.batch.Phase;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
+@Phase(name = Phase.Name.PRE)
public final class LinesSensor implements Sensor {
private final FileSystem fs;
import com.google.common.collect.Iterables;
import org.junit.Test;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import java.util.Arrays;
import java.util.Collection;
for (Object extension : extensions) {
ioc.addSingleton(extension);
}
- return new BatchExtensionDictionnary(ioc);
+ return new BatchExtensionDictionnary(ioc, null, null);
}
class FakeFormula implements Formula {
*/
package org.sonar.batch.bootstrap;
-import org.sonar.batch.sensor.AnalyzerOptimizer;
-
+import com.google.common.collect.Lists;
import org.junit.Test;
import org.sonar.api.BatchExtension;
+import org.sonar.api.batch.BuildBreaker;
+import org.sonar.api.batch.CheckProject;
+import org.sonar.api.batch.Decorator;
+import org.sonar.api.batch.DependedUpon;
+import org.sonar.api.batch.DependsUpon;
+import org.sonar.api.batch.Phase;
+import org.sonar.api.batch.PostJob;
import org.sonar.api.batch.Sensor;
+import org.sonar.api.batch.SensorContext;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
+import org.sonar.batch.sensor.AnalyzerOptimizer;
import org.sonar.batch.sensor.DefaultSensorContext;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
assertEquals(1, sensors.size());
}
+ @Test
+ public void testGetFilteredExtensions() {
+ Sensor sensor1 = new FakeSensor(), sensor2 = new FakeSensor();
+ Decorator decorator = mock(Decorator.class);
+
+ BatchExtensionDictionnary selector = newSelector(sensor1, sensor2, decorator);
+ Collection<Sensor> sensors = selector.select(Sensor.class, null, true, null);
+
+ assertThat(sensors).containsOnly(sensor1, sensor2);
+ }
+
+ @Test
+ public void shouldSearchInParentContainers() {
+ BatchExtension a = new FakeSensor();
+ BatchExtension b = new FakeSensor();
+ BatchExtension c = new FakeSensor();
+
+ ComponentContainer grandParent = new ComponentContainer();
+ grandParent.addSingleton(a);
+
+ ComponentContainer parent = grandParent.createChild();
+ parent.addSingleton(b);
+
+ ComponentContainer child = parent.createChild();
+ child.addSingleton(c);
+
+ BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class));
+ assertThat(dictionnary.select(BatchExtension.class, null, true, null)).containsOnly(a, b, c);
+ }
+
+ @Test
+ public void sortExtensionsByDependency() {
+ BatchExtension a = new MethodDependentOf(null);
+ BatchExtension b = new MethodDependentOf(a);
+ BatchExtension c = new MethodDependentOf(b);
+
+ BatchExtensionDictionnary selector = newSelector(b, c, a);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(3);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ assertThat(extensions.get(2)).isEqualTo(c);
+ }
+
+ @Test
+ public void useMethodAnnotationsToSortExtensions() {
+ BatchExtension a = new GeneratesSomething("foo");
+ BatchExtension b = new MethodDependentOf("foo");
+
+ BatchExtensionDictionnary selector = newSelector(a, b);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions.size()).isEqualTo(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // different initial order
+ selector = newSelector(b, a);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test
+ public void methodDependsUponCollection() {
+ BatchExtension a = new GeneratesSomething("foo");
+ BatchExtension b = new MethodDependentOf(Arrays.asList("foo"));
+
+ BatchExtensionDictionnary selector = newSelector(a, b);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // different initial order
+ selector = newSelector(b, a);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test
+ public void methodDependsUponArray() {
+ BatchExtension a = new GeneratesSomething("foo");
+ BatchExtension b = new MethodDependentOf(new String[] {"foo"});
+
+ BatchExtensionDictionnary selector = newSelector(a, b);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // different initial order
+ selector = newSelector(b, a);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test
+ public void useClassAnnotationsToSortExtensions() {
+ BatchExtension a = new ClassDependedUpon();
+ BatchExtension b = new ClassDependsUpon();
+
+ BatchExtensionDictionnary selector = newSelector(a, b);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // different initial order
+ selector = newSelector(b, a);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test
+ public void useClassAnnotationsOnInterfaces() {
+ BatchExtension a = new InterfaceDependedUpon() {
+ };
+ BatchExtension b = new InterfaceDependsUpon() {
+ };
+
+ BatchExtensionDictionnary selector = newSelector(a, b);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // different initial order
+ selector = newSelector(b, a);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test
+ public void checkProject() {
+ BatchExtension ok = new CheckProjectOK();
+ BatchExtension ko = new CheckProjectKO();
+
+ BatchExtensionDictionnary selector = newSelector(ok, ko);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, new Project("key"), true, null));
+
+ assertThat(extensions).hasSize(1);
+ assertThat(extensions.get(0)).isInstanceOf(CheckProjectOK.class);
+ }
+
+ @Test
+ public void inheritAnnotations() {
+ BatchExtension a = new SubClass("foo");
+ BatchExtension b = new MethodDependentOf("foo");
+
+ BatchExtensionDictionnary selector = newSelector(b, a);
+ List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+
+ // change initial order
+ selector = newSelector(a, b);
+ extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(2);
+ assertThat(extensions.get(0)).isEqualTo(a);
+ assertThat(extensions.get(1)).isEqualTo(b);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void annotatedMethodsCanNotBePrivate() {
+ BatchExtensionDictionnary selector = newSelector();
+ BatchExtension wrong = new BatchExtension() {
+ @DependsUpon
+ private Object foo() {
+ return "foo";
+ }
+ };
+ selector.evaluateAnnotatedClasses(wrong, DependsUpon.class);
+ }
+
+ @Test
+ public void dependsUponPhase() {
+ BatchExtension pre = new PreSensor();
+ BatchExtension analyze = new GeneratesSomething("something");
+ BatchExtension post = new PostSensor();
+
+ BatchExtensionDictionnary selector = newSelector(analyze, post, pre);
+ List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(3);
+ assertThat(extensions.get(0)).isEqualTo(pre);
+ assertThat(extensions.get(1)).isEqualTo(analyze);
+ assertThat(extensions.get(2)).isEqualTo(post);
+ }
+
+ @Test
+ public void dependsUponInheritedPhase() {
+ BatchExtension pre = new PreSensorSubclass();
+ BatchExtension analyze = new GeneratesSomething("something");
+ BatchExtension post = new PostSensorSubclass();
+
+ BatchExtensionDictionnary selector = newSelector(analyze, post, pre);
+ List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(3);
+ assertThat(extensions.get(0)).isEqualTo(pre);
+ assertThat(extensions.get(1)).isEqualTo(analyze);
+ assertThat(extensions.get(2)).isEqualTo(post);
+ }
+
+ @Test
+ public void buildStatusCheckersAreExecutedAfterOtherPostJobs() {
+ BuildBreaker checker = new BuildBreaker() {
+ public void executeOn(Project project, SensorContext context) {
+ }
+ };
+
+ BatchExtensionDictionnary selector = newSelector(new FakePostJob(), checker, new FakePostJob());
+ List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true, null));
+
+ assertThat(extensions).hasSize(3);
+ assertThat(extensions.get(2)).isEqualTo(checker);
+ }
+
class FakeSensor implements Sensor {
- @Override
- public void analyse(Project project, org.sonar.api.batch.SensorContext context) {
+ public void analyse(Project project, SensorContext context) {
+
+ }
+
+ public boolean shouldExecuteOnProject(Project project) {
+ return true;
+ }
+ }
+
+ class MethodDependentOf implements BatchExtension {
+ private Object dep;
+
+ MethodDependentOf(Object o) {
+ this.dep = o;
+ }
+
+ @DependsUpon
+ public Object dependsUponObject() {
+ return dep;
+ }
+ }
+
+ @DependsUpon("flag")
+ class ClassDependsUpon implements BatchExtension {
+ }
+
+ @DependedUpon("flag")
+ class ClassDependedUpon implements BatchExtension {
+ }
+
+ @DependsUpon("flag")
+ interface InterfaceDependsUpon extends BatchExtension {
+ }
+ @DependedUpon("flag")
+ interface InterfaceDependedUpon extends BatchExtension {
+ }
+
+ class GeneratesSomething implements BatchExtension {
+ private Object gen;
+
+ GeneratesSomething(Object o) {
+ this.gen = o;
}
- @Override
+ @DependedUpon
+ public Object generates() {
+ return gen;
+ }
+ }
+
+ class SubClass extends GeneratesSomething {
+ SubClass(Object o) {
+ super(o);
+ }
+ }
+
+ @Phase(name = Phase.Name.PRE)
+ class PreSensor implements BatchExtension {
+
+ }
+
+ class PreSensorSubclass extends PreSensor {
+
+ }
+
+ @Phase(name = Phase.Name.POST)
+ class PostSensor implements BatchExtension {
+
+ }
+
+ class PostSensorSubclass extends PostSensor {
+
+ }
+
+ class CheckProjectOK implements BatchExtension, CheckProject {
public boolean shouldExecuteOnProject(Project project) {
return true;
}
}
+
+ class CheckProjectKO implements BatchExtension, CheckProject {
+ public boolean shouldExecuteOnProject(Project project) {
+ return false;
+ }
+ }
+
+ private class FakePostJob implements PostJob {
+ public void executeOn(Project project, SensorContext context) {
+ }
+ }
}
package org.sonar.batch.phases;
import org.junit.Test;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.SonarIndex;
import org.sonar.api.resources.Resource;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.DefaultDecoratorContext;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.scan.measure.MeasureCache;
import org.junit.Before;
import org.junit.Test;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.PostJob;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.resources.Project;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
@Test
public void should_execute_post_jobs() {
- when(selector.select(PostJob.class, project, true)).thenReturn(Arrays.asList(job1, job2));
+ when(selector.select(PostJob.class, project, true, null)).thenReturn(Arrays.asList(job1, job2));
executor.execute(context);
import org.junit.Test;
import org.mockito.ArgumentMatcher;
-import org.sonar.api.batch.BatchExtensionDictionnary;
import org.sonar.api.batch.maven.MavenPlugin;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
import org.sonar.api.test.MavenTestUtils;
-import org.sonar.batch.scan.maven.MavenPluginsConfigurator;
+import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import java.util.Arrays;
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.batch;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.ClassUtils;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.batch.maven.DependsUponMavenPlugin;
-import org.sonar.api.batch.maven.MavenPluginHandler;
-import org.sonar.api.platform.ComponentContainer;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.AnnotationUtils;
-import org.sonar.api.utils.dag.DirectAcyclicGraph;
-
-import javax.annotation.Nullable;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * @since 1.11
- * @deprecated since 2.6 was only used by views
- */
-@Deprecated
-public class BatchExtensionDictionnary {
-
- private final ComponentContainer componentContainer;
-
- public BatchExtensionDictionnary(ComponentContainer componentContainer) {
- this.componentContainer = componentContainer;
- }
-
- public <T> Collection<T> select(Class<T> type) {
- return select(type, null, false);
- }
-
- public <T> Collection<T> select(Class<T> type, @Nullable Project project, boolean sort) {
- List<T> result = getFilteredExtensions(type, project);
- if (sort) {
- return sort(result);
- }
- return result;
- }
-
- public Collection<MavenPluginHandler> selectMavenPluginHandlers(Project project) {
- List<DependsUponMavenPlugin> selectedExtensions = Lists.newArrayList();
- for (Object extension : getExtensions(null)) {
- if (ClassUtils.isAssignable(extension.getClass(), DependsUponMavenPlugin.class)) {
- selectedExtensions.add((DependsUponMavenPlugin) extension);
- }
- }
- List<MavenPluginHandler> handlers = Lists.newArrayList();
- for (DependsUponMavenPlugin extension : selectedExtensions) {
- MavenPluginHandler handler = extension.getMavenPluginHandler(project);
- if (handler != null) {
- boolean ok = true;
- if (handler instanceof CheckProject) {
- ok = ((CheckProject) handler).shouldExecuteOnProject(project);
- }
- if (ok) {
- handlers.add(handler);
- }
- }
-
- }
- return handlers;
- }
-
- protected List<Object> getExtensions(@Nullable Class type) {
- List<Object> extensions = Lists.newArrayList();
- completeBatchExtensions(componentContainer, extensions, type);
- return extensions;
- }
-
- private static void completeBatchExtensions(ComponentContainer container, List<Object> extensions, @Nullable Class type) {
- if (container != null) {
- extensions.addAll(container.getComponentsByType(type != null ? type : BatchExtension.class));
- completeBatchExtensions(container.getParent(), extensions, type);
- }
- }
-
- private <T> List<T> getFilteredExtensions(Class<T> type, @Nullable Project project) {
- List<T> result = Lists.newArrayList();
- for (Object extension : getExtensions(type)) {
- if (shouldKeep(type, extension, project)) {
- result.add((T) extension);
- }
- }
- return result;
- }
-
- private boolean shouldKeep(Class type, Object extension, @Nullable Project project) {
- boolean keep = ClassUtils.isAssignable(extension.getClass(), type);
- if (keep && project != null && ClassUtils.isAssignable(extension.getClass(), CheckProject.class)) {
- keep = ((CheckProject) extension).shouldExecuteOnProject(project);
- }
- return keep;
- }
-
- public <T> Collection<T> sort(Collection<T> extensions) {
- DirectAcyclicGraph dag = new DirectAcyclicGraph();
-
- for (T extension : extensions) {
- dag.add(extension);
- for (Object dependency : getDependencies(extension)) {
- dag.add(extension, dependency);
- }
- for (Object generates : getDependents(extension)) {
- dag.add(generates, extension);
- }
- completePhaseDependencies(dag, extension);
- }
- List sortedList = dag.sort();
-
- return Collections2.filter(sortedList, Predicates.in(extensions));
- }
-
- /**
- * Extension dependencies
- */
- private <T> List<Object> getDependencies(T extension) {
- List<Object> result = new ArrayList<Object>();
- result.addAll(evaluateAnnotatedClasses(extension, DependsUpon.class));
- return result;
- }
-
- /**
- * Objects that depend upon this extension.
- */
- public <T> List<Object> getDependents(T extension) {
- List<Object> result = new ArrayList<Object>();
- result.addAll(evaluateAnnotatedClasses(extension, DependedUpon.class));
- return result;
- }
-
- private void completePhaseDependencies(DirectAcyclicGraph dag, Object extension) {
- Phase.Name phase = evaluatePhase(extension);
- dag.add(extension, phase);
- for (Phase.Name name : Phase.Name.values()) {
- if (phase.compareTo(name) < 0) {
- dag.add(name, extension);
- } else if (phase.compareTo(name) > 0) {
- dag.add(extension, name);
- }
- }
- }
-
- protected List<Object> evaluateAnnotatedClasses(Object extension, Class<? extends Annotation> annotation) {
- List<Object> results = Lists.newArrayList();
- Class aClass = extension.getClass();
- while (aClass != null) {
- evaluateClass(aClass, annotation, results);
-
- for (Method method : aClass.getDeclaredMethods()) {
- if (method.getAnnotation(annotation) != null) {
- checkAnnotatedMethod(method);
- evaluateMethod(extension, method, results);
- }
- }
- aClass = aClass.getSuperclass();
- }
-
- return results;
- }
-
- private void evaluateClass(Class extensionClass, Class annotationClass, List<Object> results) {
- Annotation annotation = extensionClass.getAnnotation(annotationClass);
- if (annotation != null) {
- if (annotation.annotationType().isAssignableFrom(DependsUpon.class)) {
- results.addAll(Arrays.asList(((DependsUpon) annotation).value()));
-
- } else if (annotation.annotationType().isAssignableFrom(DependedUpon.class)) {
- results.addAll(Arrays.asList(((DependedUpon) annotation).value()));
- }
- }
-
- Class[] interfaces = extensionClass.getInterfaces();
- for (Class anInterface : interfaces) {
- evaluateClass(anInterface, annotationClass, results);
- }
- }
-
- protected Phase.Name evaluatePhase(Object extension) {
- Phase phaseAnnotation = AnnotationUtils.getAnnotation(extension, Phase.class);
- if (phaseAnnotation != null) {
- return phaseAnnotation.name();
- }
- return Phase.Name.DEFAULT;
- }
-
- private void evaluateMethod(Object extension, Method method, List<Object> results) {
- try {
- Object result = method.invoke(extension);
- if (result != null) {
- if (result instanceof Class<?>) {
- results.addAll(componentContainer.getComponentsByType((Class<?>) result));
-
- } else if (result instanceof Collection<?>) {
- results.addAll((Collection<?>) result);
-
- } else if (result.getClass().isArray()) {
- for (int i = 0; i < Array.getLength(result); i++) {
- results.add(Array.get(result, i));
- }
-
- } else {
- results.add(result);
- }
- }
- } catch (Exception e) {
- throw new IllegalStateException("Can not invoke method " + method, e);
- }
- }
-
- private void checkAnnotatedMethod(Method method) {
- if (!Modifier.isPublic(method.getModifiers())) {
- throw new IllegalStateException("Annotated method must be public:" + method);
- }
- if (method.getParameterTypes().length > 0) {
- throw new IllegalStateException("Annotated method must not have parameters:" + method);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.batch;
-
-import com.google.common.collect.Lists;
-import org.junit.Test;
-import org.sonar.api.BatchExtension;
-import org.sonar.api.platform.ComponentContainer;
-import org.sonar.api.resources.Project;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-public class BatchExtensionDictionnaryTest {
-
- private BatchExtensionDictionnary newSelector(BatchExtension... extensions) {
- ComponentContainer iocContainer = new ComponentContainer();
- for (BatchExtension extension : extensions) {
- iocContainer.addSingleton(extension);
- }
- return new BatchExtensionDictionnary(iocContainer);
- }
-
- @Test
- public void testGetFilteredExtensions() {
- Sensor sensor1 = new FakeSensor(), sensor2 = new FakeSensor();
- Decorator decorator = mock(Decorator.class);
-
- BatchExtensionDictionnary selector = newSelector(sensor1, sensor2, decorator);
- Collection<Sensor> sensors = selector.select(Sensor.class, null, true);
-
- assertThat(sensors).containsOnly(sensor1, sensor2);
- }
-
- @Test
- public void shouldSearchInParentContainers() {
- BatchExtension a = new FakeSensor();
- BatchExtension b = new FakeSensor();
- BatchExtension c = new FakeSensor();
-
- ComponentContainer grandParent = new ComponentContainer();
- grandParent.addSingleton(a);
-
- ComponentContainer parent = grandParent.createChild();
- parent.addSingleton(b);
-
- ComponentContainer child = parent.createChild();
- child.addSingleton(c);
-
- BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child);
- assertThat(dictionnary.select(BatchExtension.class)).containsOnly(a, b, c);
- }
-
- @Test
- public void sortExtensionsByDependency() {
- BatchExtension a = new MethodDependentOf(null);
- BatchExtension b = new MethodDependentOf(a);
- BatchExtension c = new MethodDependentOf(b);
-
- BatchExtensionDictionnary selector = newSelector(b, c, a);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(3);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- assertThat(extensions.get(2)).isEqualTo(c);
- }
-
- @Test
- public void useMethodAnnotationsToSortExtensions() {
- BatchExtension a = new GeneratesSomething("foo");
- BatchExtension b = new MethodDependentOf("foo");
-
- BatchExtensionDictionnary selector = newSelector(a, b);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions.size()).isEqualTo(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test
- public void methodDependsUponCollection() {
- BatchExtension a = new GeneratesSomething("foo");
- BatchExtension b = new MethodDependentOf(Arrays.asList("foo"));
-
- BatchExtensionDictionnary selector = newSelector(a, b);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test
- public void methodDependsUponArray() {
- BatchExtension a = new GeneratesSomething("foo");
- BatchExtension b = new MethodDependentOf(new String[]{"foo"});
-
- BatchExtensionDictionnary selector = newSelector(a, b);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test
- public void useClassAnnotationsToSortExtensions() {
- BatchExtension a = new ClassDependedUpon();
- BatchExtension b = new ClassDependsUpon();
-
- BatchExtensionDictionnary selector = newSelector(a, b);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test
- public void useClassAnnotationsOnInterfaces() {
- BatchExtension a = new InterfaceDependedUpon() {
- };
- BatchExtension b = new InterfaceDependsUpon() {
- };
-
- BatchExtensionDictionnary selector = newSelector(a, b);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // different initial order
- selector = newSelector(b, a);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test
- public void checkProject() {
- BatchExtension ok = new CheckProjectOK();
- BatchExtension ko = new CheckProjectKO();
-
- BatchExtensionDictionnary selector = newSelector(ok, ko);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, new Project("key"), true));
-
- assertThat(extensions).hasSize(1);
- assertThat(extensions.get(0)).isInstanceOf(CheckProjectOK.class);
- }
-
- @Test
- public void inheritAnnotations() {
- BatchExtension a = new SubClass("foo");
- BatchExtension b = new MethodDependentOf("foo");
-
- BatchExtensionDictionnary selector = newSelector(b, a);
- List<BatchExtension> extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
-
- // change initial order
- selector = newSelector(a, b);
- extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(2);
- assertThat(extensions.get(0)).isEqualTo(a);
- assertThat(extensions.get(1)).isEqualTo(b);
- }
-
- @Test(expected = IllegalStateException.class)
- public void annotatedMethodsCanNotBePrivate() {
- BatchExtensionDictionnary selector = newSelector();
- BatchExtension wrong = new BatchExtension() {
- @DependsUpon
- private Object foo() {
- return "foo";
- }
- };
- selector.evaluateAnnotatedClasses(wrong, DependsUpon.class);
- }
-
- @Test
- public void dependsUponPhase() {
- BatchExtension pre = new PreSensor();
- BatchExtension analyze = new GeneratesSomething("something");
- BatchExtension post = new PostSensor();
-
- BatchExtensionDictionnary selector = newSelector(analyze, post, pre);
- List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(3);
- assertThat(extensions.get(0)).isEqualTo(pre);
- assertThat(extensions.get(1)).isEqualTo(analyze);
- assertThat(extensions.get(2)).isEqualTo(post);
- }
-
- @Test
- public void dependsUponInheritedPhase() {
- BatchExtension pre = new PreSensorSubclass();
- BatchExtension analyze = new GeneratesSomething("something");
- BatchExtension post = new PostSensorSubclass();
-
- BatchExtensionDictionnary selector = newSelector(analyze, post, pre);
- List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(3);
- assertThat(extensions.get(0)).isEqualTo(pre);
- assertThat(extensions.get(1)).isEqualTo(analyze);
- assertThat(extensions.get(2)).isEqualTo(post);
- }
-
- @Test
- public void buildStatusCheckersAreExecutedAfterOtherPostJobs() {
- BuildBreaker checker = new BuildBreaker() {
- public void executeOn(Project project, SensorContext context) {
- }
- };
-
- BatchExtensionDictionnary selector = newSelector(new FakePostJob(), checker, new FakePostJob());
- List extensions = Lists.newArrayList(selector.select(BatchExtension.class, null, true));
-
- assertThat(extensions).hasSize(3);
- assertThat(extensions.get(2)).isEqualTo(checker);
- }
-
- class FakeSensor implements Sensor {
-
- public void analyse(Project project, SensorContext context) {
-
- }
-
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
- }
-
- class MethodDependentOf implements BatchExtension {
- private Object dep;
-
- MethodDependentOf(Object o) {
- this.dep = o;
- }
-
- @DependsUpon
- public Object dependsUponObject() {
- return dep;
- }
- }
-
- @DependsUpon("flag")
- class ClassDependsUpon implements BatchExtension {
- }
-
- @DependedUpon("flag")
- class ClassDependedUpon implements BatchExtension {
- }
-
- @DependsUpon("flag")
- interface InterfaceDependsUpon extends BatchExtension {
- }
-
- @DependedUpon("flag")
- interface InterfaceDependedUpon extends BatchExtension {
- }
-
- class GeneratesSomething implements BatchExtension {
- private Object gen;
-
- GeneratesSomething(Object o) {
- this.gen = o;
- }
-
- @DependedUpon
- public Object generates() {
- return gen;
- }
- }
-
- class SubClass extends GeneratesSomething {
- SubClass(Object o) {
- super(o);
- }
- }
-
- @Phase(name = Phase.Name.PRE)
- class PreSensor implements BatchExtension {
-
- }
-
- class PreSensorSubclass extends PreSensor {
-
- }
-
- @Phase(name = Phase.Name.POST)
- class PostSensor implements BatchExtension {
-
- }
-
- class PostSensorSubclass extends PostSensor {
-
- }
-
- class CheckProjectOK implements BatchExtension, CheckProject {
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
- }
-
- class CheckProjectKO implements BatchExtension, CheckProject {
- public boolean shouldExecuteOnProject(Project project) {
- return false;
- }
- }
-
- private class FakePostJob implements PostJob {
- public void executeOn(Project project, SensorContext context) {
- }
- }
-}