Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.api.batch;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import org.apache.commons.lang.ClassUtils;
import org.picocontainer.MutablePicoContainer;
import org.sonar.api.BatchExtension;
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.AnnotationUtils;
import org.sonar.api.utils.IocContainer;
import org.sonar.api.utils.dag.DirectAcyclicGraph;
import java.lang.annotation.Annotation;
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
*/
public class BatchExtensionDictionnary {
private MutablePicoContainer picoContainer;
public BatchExtensionDictionnary(IocContainer iocContainer) {
this.picoContainer = iocContainer.getPicoContainer();
}
public BatchExtensionDictionnary(MutablePicoContainer picoContainer) {
this.picoContainer = picoContainer;
}
public Collection select(Class type) {
return select(type, null, false);
}
public Collection select(Class type, Project project, boolean sort) {
List result = getFilteredExtensions(type, project);
if (sort) {
return sort(result);
}
return result;
}
public Collection selectMavenPluginHandlers(Project project) {
Collection selectedExtensions = select(DependsUponMavenPlugin.class, project, true);
List handlers = new ArrayList();
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 List getExtensions() {
return picoContainer.getComponents(BatchExtension.class);
}
private List getFilteredExtensions(Class type, Project project) {
List result = new ArrayList();
for (BatchExtension extension : getExtensions()) {
if (shouldKeep(type, extension, project)) {
result.add((T) extension);
}
}
return result;
}
private boolean shouldKeep(Class type, Object extension, 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 Collection sort(Collection 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 (Collection) Collections2.filter(sortedList, Predicates.in(extensions));
}
/**
* Extension dependencies
*/
private List getDependencies(T extension) {
return evaluateAnnotatedClasses(extension, DependsUpon.class);
}
/**
* Objects that depend upon this extension.
*/
public List getDependents(T extension) {
return evaluateAnnotatedClasses(extension, DependedUpon.class);
}
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 evaluateAnnotatedClasses(Object extension, Class annotation) {
List results = new ArrayList();
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 results) {
Annotation annotation = extensionClass.getAnnotation(annotationClass);
if (annotation != null) {
if (annotation.annotationType().isAssignableFrom(DependsUpon.class)) {
results.addAll(Arrays.asList(((DependsUpon) annotation).value()));
results.addAll(Arrays.asList(((DependsUpon) annotation).classes()));
} else if (annotation.annotationType().isAssignableFrom(DependedUpon.class)) {
results.addAll(Arrays.asList(((DependedUpon) annotation).value()));
results.addAll(Arrays.asList(((DependedUpon) annotation).classes()));
}
}
Class[] interfaces = extensionClass.getInterfaces();
for (Class anInterface : interfaces) {
evaluateClass(anInterface, annotationClass, results);
}
}
protected Phase.Name evaluatePhase(Object extension) {
Phase phaseAnnotation = AnnotationUtils.getClassAnnotation(extension, Phase.class);
if (phaseAnnotation != null) {
return phaseAnnotation.name();
}
return Phase.Name.DEFAULT;
}
private void evaluateMethod(Object extension, Method method, List results) {
try {
Object result = method.invoke(extension);
if (result != null) {
//TODO add arrays/collections of objects/classes
if (result instanceof Class) {
results.addAll(picoContainer.getComponents((Class) result));
} else if (result instanceof Collection) {
results.addAll((Collection) result);
} 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);
}
}
}