/* * Copyright 2012 the original author or authors. * * Licensed 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.gradle.api.plugins.quality.internal; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Callables; import org.gradle.api.Action; import org.gradle.api.Plugin; import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.internal.ConventionMapping; import org.gradle.api.internal.IConventionAware; import org.gradle.api.internal.project.ProjectInternal; import org.gradle.api.plugins.JavaBasePlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.ReportingBasePlugin; import org.gradle.api.plugins.quality.CodeQualityExtension; import org.gradle.api.reporting.ReportingExtension; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import java.io.File; import java.util.ArrayList; import java.util.Map; import java.util.concurrent.Callable; public abstract class AbstractCodeQualityPlugin<T> implements Plugin<ProjectInternal> { protected static ConventionMapping conventionMappingOf(Object object) { return ((IConventionAware) object).getConventionMapping(); } protected ProjectInternal project; protected CodeQualityExtension extension; @Override public final void apply(ProjectInternal project) { this.project = project; beforeApply(); project.getPluginManager().apply(ReportingBasePlugin.class); createConfigurations(); extension = createExtension(); configureExtensionRule(); configureTaskRule(); configureSourceSetRule(); configureCheckTask(); } protected abstract String getToolName(); protected abstract Class<T> getTaskType(); private Class<? extends Task> getCastedTaskType() { return (Class<? extends Task>) getTaskType(); } protected String getTaskBaseName() { return getToolName().toLowerCase(); } protected String getConfigurationName() { return getToolName().toLowerCase(); } protected String getReportName() { return getToolName().toLowerCase(); } protected Class<? extends Plugin> getBasePlugin() { return JavaBasePlugin.class; } protected void beforeApply() { } protected void createConfigurations() { Configuration configuration = project.getConfigurations().create(getConfigurationName()); configuration.setVisible(false); configuration.setTransitive(true); configuration.setDescription("The " + getToolName() + " libraries to be used for this project."); // Don't need these things, they're provided by the runtime configuration.exclude(excludeProperties("ant", "ant")); configuration.exclude(excludeProperties("org.apache.ant", "ant")); configuration.exclude(excludeProperties("org.apache.ant", "ant-launcher")); configuration.exclude(excludeProperties("org.slf4j", "slf4j-api")); configuration.exclude(excludeProperties("org.slf4j", "jcl-over-slf4j")); configuration.exclude(excludeProperties("org.slf4j", "log4j-over-slf4j")); configuration.exclude(excludeProperties("commons-logging", "commons-logging")); configuration.exclude(excludeProperties("log4j", "log4j")); } private Map<String, String> excludeProperties(String group, String module) { return ImmutableMap.<String, String>builder() .put("group", group) .put("module", module) .build(); } protected abstract CodeQualityExtension createExtension(); private void configureExtensionRule() { final ConventionMapping extensionMapping = conventionMappingOf(extension); extensionMapping.map("sourceSets", Callables.returning(new ArrayList())); extensionMapping.map("reportsDir", new Callable<File>() { @Override public File call() { return project.getExtensions().getByType(ReportingExtension.class).file(getReportName()); } }); withBasePlugin(new Action<Plugin>() { @Override public void execute(Plugin plugin) { extensionMapping.map("sourceSets", new Callable<SourceSetContainer>() { @Override public SourceSetContainer call() { return getJavaPluginConvention().getSourceSets(); } }); } }); } private void configureTaskRule() { project.getTasks().withType(getCastedTaskType(), new Action<Task>() { @Override public void execute(Task task) { String prunedName = task.getName().replaceFirst(getTaskBaseName(), ""); if (prunedName.isEmpty()) { prunedName = task.getName(); } prunedName = ("" + prunedName.charAt(0)).toLowerCase() + prunedName.substring(1); configureTaskDefaults((T) task, prunedName); } }); } protected void configureTaskDefaults(T task, String baseName) { } private void configureSourceSetRule() { withBasePlugin(new Action<Plugin>() { @Override public void execute(Plugin plugin) { configureForSourceSets(getJavaPluginConvention().getSourceSets()); } }); } private void configureForSourceSets(SourceSetContainer sourceSets) { sourceSets.all(new Action<SourceSet>() { @Override public void execute(SourceSet sourceSet) { Task task = project.getTasks().create(sourceSet.getTaskName(getTaskBaseName(), null), getCastedTaskType()); configureForSourceSet(sourceSet, (T)task); } }); } protected void configureForSourceSet(SourceSet sourceSet, T task) { } private void configureCheckTask() { withBasePlugin(new Action<Plugin>() { @Override public void execute(Plugin plugin) { configureCheckTaskDependents(); } }); } private void configureCheckTaskDependents() { final String taskBaseName = getTaskBaseName(); project.getTasks().getByName("check").dependsOn(new Callable() { @Override public Object call() { return Iterables.transform(extension.getSourceSets(), new Function<SourceSet, String>() { @Override public String apply(SourceSet sourceSet) { return sourceSet.getTaskName(taskBaseName, null); } }); } }); } protected void withBasePlugin(Action<Plugin> action) { project.getPlugins().withType(getBasePlugin(), action); } protected JavaPluginConvention getJavaPluginConvention() { return project.getConvention().getPlugin(JavaPluginConvention.class); } }