diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-05-27 12:25:05 +0200 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-05-27 12:25:16 +0200 |
commit | 5e5916cd83e20df7331bb3534e82f3845951b160 (patch) | |
tree | ecd59c3f473109fd75050ace9d78dd924cdaab75 /sonar-plugin-api/src | |
parent | c073a325c80ef5d4c0d805b2545dd6be40b1892e (diff) | |
download | sonarqube-5e5916cd83e20df7331bb3534e82f3845951b160.tar.gz sonarqube-5e5916cd83e20df7331bb3534e82f3845951b160.zip |
SONAR-2468 new extension point org.sonar.api.bootstrap.ProjectBuilder
Diffstat (limited to 'sonar-plugin-api/src')
6 files changed, 561 insertions, 0 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectBuilder.java new file mode 100644 index 00000000000..bdd90512ede --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectBuilder.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import org.sonar.api.BatchExtension; +import org.sonar.api.batch.InstantiationStrategy; + +/** + * + * @since 2.9 + */ +@InstantiationStrategy(InstantiationStrategy.PER_BATCH) +public abstract class ProjectBuilder implements BatchExtension { + + private ProjectReactor reactor; + + protected ProjectBuilder(final ProjectReactor reactor) { + this.reactor = reactor; + } + + public final void start() { + build(reactor); + } + + protected abstract void build(ProjectReactor reactor); +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java new file mode 100644 index 00000000000..195b886fcbc --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java @@ -0,0 +1,245 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import com.google.common.collect.Lists; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.BatchComponent; +import org.sonar.api.CoreProperties; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +/** + * @since 2.9 + */ +public final class ProjectDefinition implements BatchComponent { + + public static final String SOURCES_PROPERTY = "sonar.sources"; + public static final String TESTS_PROPERTY = "sonar.tests"; + public static final String BINARIES_PROPERTY = "sonar.binaries"; + public static final String LIBRARIES_PROPERTY = "sonar.libraries"; + + private static final char SEPARATOR = ','; + + private File baseDir; + private File workDir; + private Properties properties; + private ProjectDefinition parent = null; + private List<ProjectDefinition> subProjects = Lists.newArrayList(); + private List<Object> containerExtensions = Lists.newArrayList(); + + /** + * TODO use factory methods + */ + public ProjectDefinition(File baseDir, File workDir, Properties properties) { + this.baseDir = baseDir; + this.workDir = workDir; + this.properties = properties; + } + + private ProjectDefinition() { + } + + public static ProjectDefinition create() { + return new ProjectDefinition(); + } + + public File getBaseDir() { + return baseDir; + } + + public ProjectDefinition setBaseDir(File baseDir) { + this.baseDir = baseDir; + return this; + } + + public ProjectDefinition setWorkDir(File workDir) { + this.workDir = workDir; + return this; + } + + public File getWorkDir() { + return workDir; + } + + public Properties getProperties() { + return properties; + } + + public ProjectDefinition setKey(String key) { + properties.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, key); + return this; + } + + public ProjectDefinition setVersion(String s) { + properties.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, StringUtils.defaultString(s)); + return this; + } + + public ProjectDefinition setName(String s) { + properties.setProperty(CoreProperties.PROJECT_NAME_PROPERTY, StringUtils.defaultString(s)); + return this; + } + + public ProjectDefinition setDescription(String s) { + properties.setProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY, StringUtils.defaultString(s)); + return this; + } + + public String getKey() { + return properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY); + } + + public String getVersion() { + return properties.getProperty(CoreProperties.PROJECT_VERSION_PROPERTY); + } + + public String getName() { + String name = properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY); + if (StringUtils.isBlank(name)) { + name = "Unnamed - " + getKey(); + } + return name; + } + + public String getDescription() { + return properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY); + } + + private void appendProperty(String key, String value) { + String newValue = properties.getProperty(key, "") + SEPARATOR + value; + properties.put(key, newValue); + } + + public List<String> getSourceDirs() { + String sources = properties.getProperty(SOURCES_PROPERTY, ""); + return Arrays.asList(StringUtils.split(sources, SEPARATOR)); + } + + /** + * @param path path to directory with main sources. + * It can be absolute or relative to project directory. + */ + public ProjectDefinition addSourceDir(String path) { + appendProperty(SOURCES_PROPERTY, path); + return this; + } + + public ProjectDefinition addSourceDir(File path) { + addSourceDir(path.getAbsolutePath()); + return this; + } + + public ProjectDefinition setSourceDir(String path) { + properties.setProperty(SOURCES_PROPERTY, path); + return this; + } + + public ProjectDefinition setSourceDir(File path) { + setSourceDir(path.getAbsolutePath()); + return this; + } + + public List<String> getTestDirs() { + String sources = properties.getProperty(TESTS_PROPERTY, ""); + return Arrays.asList(StringUtils.split(sources, SEPARATOR)); + } + + /** + * @param path path to directory with test sources. + * It can be absolute or relative to project directory. + */ + public ProjectDefinition addTestDir(String path) { + appendProperty(TESTS_PROPERTY, path); + return this; + } + + public List<String> getBinaries() { + String sources = properties.getProperty(BINARIES_PROPERTY, ""); + return Arrays.asList(StringUtils.split(sources, SEPARATOR)); + } + + /** + * @param path path to directory with compiled source. In case of Java this is directory with class files. + * It can be absolute or relative to project directory. + * @TODO currently Sonar supports only one such directory due to dependency on MavenProject + */ + public ProjectDefinition addBinaryDir(String path) { + appendProperty(BINARIES_PROPERTY, path); + return this; + } + + public List<String> getLibraries() { + String sources = properties.getProperty(LIBRARIES_PROPERTY, ""); + return Arrays.asList(StringUtils.split(sources, SEPARATOR)); + } + + /** + * @param path path to file with third-party library. In case of Java this is path to jar file. + * It can be absolute or relative to project directory. + */ + public void addLibrary(String path) { + appendProperty(LIBRARIES_PROPERTY, path); + } + + /** + * Adds an extension, which would be available in PicoContainer during analysis of this project. + * + * @since 2.8 + */ + public ProjectDefinition addContainerExtension(Object extension) { + containerExtensions.add(extension); + return this; + } + + /** + * @since 2.8 + */ + public List<Object> getContainerExtensions() { + return containerExtensions; + } + + /** + * @since 2.8 + */ + public ProjectDefinition addSubProject(ProjectDefinition child) { + subProjects.add(child); + child.setParent(this); + return this; + } + + public ProjectDefinition getParent() { + return parent; + } + + private void setParent(ProjectDefinition parent) { + this.parent = parent; + } + + /** + * @since 2.8 + */ + public List<ProjectDefinition> getSubProjects() { + return subProjects; + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectReactor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectReactor.java new file mode 100644 index 00000000000..4cbe4c0a3f7 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectReactor.java @@ -0,0 +1,59 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import org.sonar.api.BatchComponent; + +import java.util.ArrayList; +import java.util.List; + +/** + * @since 2.9 + */ +public final class ProjectReactor implements BatchComponent { + + private ProjectDefinition root; + + public ProjectReactor(ProjectDefinition root) { + if (root.getParent()!=null) { + throw new IllegalArgumentException("Not a root project: " + root); + } + this.root = root; + } + + public List<ProjectDefinition> getProjects() { + return collectProjects(root, new ArrayList<ProjectDefinition>()); + } + + /** + * Populates list of projects from hierarchy. + */ + private static List<ProjectDefinition> collectProjects(ProjectDefinition def, List<ProjectDefinition> collected) { + collected.add(def); + for (ProjectDefinition child : def.getSubProjects()) { + collectProjects(child, collected); + } + return collected; + } + + public ProjectDefinition getRoot() { + return root; + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java new file mode 100644 index 00000000000..a4f6811cde3 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java @@ -0,0 +1,52 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import org.junit.Test; + +import java.io.File; +import java.util.Properties; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class ProjectBuilderTest { + + @Test + public void shouldBuild() { + FakeProjectBuilder builder = new FakeProjectBuilder(new ProjectReactor(new ProjectDefinition(new File("."), new File("."), new Properties()))); + builder.start(); + + assertThat(builder.built, is(true)); + } + + private static class FakeProjectBuilder extends ProjectBuilder { + private boolean built=false; + + FakeProjectBuilder(final ProjectReactor reactor) { + super(reactor); + } + + @Override + protected void build(ProjectReactor reactor) { + built=true; + } + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java new file mode 100644 index 00000000000..49f1e1c916a --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java @@ -0,0 +1,111 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import org.junit.Test; +import org.sonar.api.CoreProperties; + +import java.io.File; +import java.util.List; +import java.util.Properties; + +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ProjectDefinitionTest { + + @Test + public void shouldSetKey() { + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); + def.setKey("mykey"); + assertThat(def.getKey(), is("mykey")); + } + + @Test + public void shouldSetOptionalFields() { + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); + def.setName("myname"); + def.setDescription("desc"); + assertThat(def.getName(), is("myname")); + assertThat(def.getDescription(), is("desc")); + } + + @Test + public void shouldSupportDefaultName() { + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); + def.setKey("myKey"); + assertThat(def.getName(), is("Unnamed - myKey")); + } + @Test + public void shouldGetKeyFromProperties() { + Properties props = new Properties(); + props.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo"); + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), props); + assertThat(def.getKey(), is("foo")); + } + + @Test + public void testDefaultValues() { + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); + assertThat(def.getSourceDirs().size(), is(0)); + assertThat(def.getTestDirs().size(), is(0)); + assertThat(def.getBinaries().size(), is(0)); + assertThat(def.getLibraries().size(), is(0)); + } + + @Test + public void shouldAddDirectories() { + ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties()); + def.addSourceDir("src/main/java"); + def.addSourceDir("src/main/java2"); + def.addTestDir("src/test/java"); + def.addTestDir("src/test/java2"); + def.addBinaryDir("target/classes"); + def.addBinaryDir("target/classes2"); + def.addLibrary("junit.jar"); + def.addLibrary("mockito.jar"); + + assertDirs(def.getSourceDirs(), "src/main/java", "src/main/java2"); + assertDirs(def.getTestDirs(), "src/test/java", "src/test/java2"); + assertDirs(def.getBinaries(), "target/classes", "target/classes2"); + assertDirs(def.getLibraries(), "junit.jar", "mockito.jar"); + } + + @Test + public void shouldManageRelationships() { + ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); + ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); + root.addSubProject(child); + + assertThat(root.getSubProjects().size(), is(1)); + assertThat(child.getSubProjects().size(), is(0)); + + assertThat(root.getParent(), nullValue()); + assertThat(child.getParent(), is(root)); + } + + private static void assertDirs(List<String> dirs, String... values) { + assertThat(dirs.size(), is(values.length)); + for (int i = 0; i < values.length; i++) { + assertThat(dirs.get(i), is(values[i])); + } + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectReactorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectReactorTest.java new file mode 100644 index 00000000000..4385cb1455a --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectReactorTest.java @@ -0,0 +1,51 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * 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.bootstrap; + +import org.junit.Test; + +import java.io.File; +import java.util.Properties; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ProjectReactorTest { + + @Test + public void shouldSupportMultipleProjects() { + ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); + ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); + root.addSubProject(child); + + ProjectReactor reactor = new ProjectReactor(root); + assertThat(reactor.getProjects().size(), is(2)); + assertThat(reactor.getRoot(), is(root)); + } + + @Test(expected = IllegalArgumentException.class) + public void shouldFailIfNotRoot() { + ProjectDefinition root = new ProjectDefinition(new File("."), new File("."), new Properties()); + ProjectDefinition child = new ProjectDefinition(new File("."), new File("."), new Properties()); + root.addSubProject(child); + + new ProjectReactor(child); + } +} |