diff options
Diffstat (limited to 'sonar-plugin-api/src')
6 files changed, 187 insertions, 43 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index fdacc52dfbd..6d51b51a2a8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -344,8 +344,13 @@ public interface CoreProperties { String TASK = "sonar.task"; /** + * @since 3.6 + */ + String SCAN_TASK = "scan"; + + /** * @deprecated replaced in v3.4 by properties specific to languages, for example sonar.java.coveragePlugin - * See http://jira.codehaus.org/browse/SONARJAVA-39 for more details. + * See http://jira.codehaus.org/browse/SONARJAVA-39 for more details. */ @Deprecated String CORE_COVERAGE_PLUGIN_PROPERTY = "sonar.core.codeCoveragePlugin"; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/task/Task.java b/sonar-plugin-api/src/main/java/org/sonar/api/task/Task.java index 42bfdddcaac..e705c2725b6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/task/Task.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/task/Task.java @@ -22,7 +22,7 @@ package org.sonar.api.task; /** * Implement this interface to provide the behavior of a task. - * @since 3.5 + * @since 3.6 */ public interface Task extends TaskExtension { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskComponent.java b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskComponent.java index 346b8bcf351..7cf26d1b132 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskComponent.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskComponent.java @@ -20,10 +20,9 @@ package org.sonar.api.task; /** - * Dependency Injection : all the classes implementing this interface are available in the task IoC container. - * Just add a parameter to the constructor of your component. + * All the classes implementing this interface can be injected in public constructors of {@link TaskExtension}. * - * @since 3.5 + * @since 3.6 */ public interface TaskComponent { } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java index 2d7d595bd78..1fba731dd49 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskDefinition.java @@ -19,64 +19,104 @@ */ package org.sonar.api.task; +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +import java.util.regex.Pattern; + /** - * Implement this interface to provide a new task. - * @since 3.5 + * Register and describe a {@link TaskExtension}. + * + * @since 3.6 */ -public class TaskDefinition implements TaskComponent { +public class TaskDefinition implements TaskExtension, Comparable<TaskDefinition> { + static final String KEY_PATTERN = "[a-zA-Z0-9\\-\\_]+"; - private String name; - private String description; - private String command; - private Class<? extends Task> task; - - private TaskDefinition() { + private final String key; + private final String description; + private final Class<? extends Task> taskClass; + private TaskDefinition(Builder builder) { + this.key = builder.key; + this.description = builder.description; + this.taskClass = builder.taskClass; } - public static TaskDefinition create() { - return new TaskDefinition(); + public String description() { + return description; } - public String getName() { - return name; + public String key() { + return key; } - public TaskDefinition setName(String name) { - this.name = name; - return this; + public Class<? extends Task> taskClass() { + return taskClass; } - public String getDescription() { - return description; + @Override + public String toString() { + return "Task " + key + "[class=" + taskClass.getName() + ", desc=" + description + "]"; } - public TaskDefinition setDescription(String description) { - this.description = description; - return this; + public static Builder builder() { + return new Builder(); } - public String getCommand() { - return command; - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } - public TaskDefinition setCommand(String command) { - this.command = command; - return this; + TaskDefinition that = (TaskDefinition) o; + if (!key.equals(that.key)) { + return false; + } + return true; } - public Class<? extends Task> getTask() { - return task; + @Override + public int hashCode() { + return key.hashCode(); } - public TaskDefinition setTask(Class<? extends Task> task) { - this.task = task; - return this; + public int compareTo(TaskDefinition o) { + return key.compareTo(o.key); } - @Override - public String toString() { - return "Definition of task " + task + " with command " + command; - } + public static class Builder { + private String key; + private String description; + private Class<? extends Task> taskClass; + + private Builder() { + } + public Builder key(String key) { + this.key = key; + return this; + } + + public Builder description(String s) { + this.description = s; + return this; + } + + public Builder taskClass(Class<? extends Task> taskClass) { + this.taskClass = taskClass; + return this; + } + + public TaskDefinition build() { + Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Task key must be set"); + Preconditions.checkArgument(Pattern.matches(KEY_PATTERN, key), "Task key '" + key + "' must match " + KEY_PATTERN); + Preconditions.checkArgument(!Strings.isNullOrEmpty(description), "Description must be set for task '" + key + "'"); + Preconditions.checkArgument(taskClass != null, "Class must be set for task '" + key + "'"); + return new TaskDefinition(this); + } + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskExtension.java b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskExtension.java index 92c3c7230de..8406650ef79 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskExtension.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/task/TaskExtension.java @@ -22,9 +22,9 @@ package org.sonar.api.task; import org.sonar.api.Extension; /** - * Task extension point. + * Task extension point * - * @since 3.5 + * @since 3.6 */ public interface TaskExtension extends Extension, TaskComponent { } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/task/TaskDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/task/TaskDefinitionTest.java new file mode 100644 index 00000000000..dcd581946aa --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/task/TaskDefinitionTest.java @@ -0,0 +1,100 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 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.task; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.fest.assertions.Assertions.assertThat; + +public class TaskDefinitionTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void should_build() { + TaskDefinition def = TaskDefinition.builder().key("foo").taskClass(FooTask.class).description("Foo").build(); + assertThat(def.key()).isEqualTo("foo"); + assertThat(def.description()).isEqualTo("Foo"); + assertThat(def.taskClass()).isEqualTo(FooTask.class); + assertThat(def.toString()).isEqualTo("Task foo[class=org.sonar.api.task.TaskDefinitionTest$FooTask, desc=Foo]"); + } + + @Test + public void test_equals_and_hashcode() { + TaskDefinition def1 = TaskDefinition.builder().key("one").taskClass(FooTask.class).description("Foo").build(); + TaskDefinition def1bis = TaskDefinition.builder().key("one").taskClass(FooTask.class).description("Foo").build(); + TaskDefinition def2 = TaskDefinition.builder().key("two").taskClass(FooTask.class).description("Foo").build(); + + assertThat(def1).isEqualTo(def1); + assertThat(def1).isEqualTo(def1bis); + assertThat(def2).isNotEqualTo(def1); + assertThat(def2).isNotEqualTo("one"); + assertThat(def2).isNotEqualTo(null); + + assertThat(def1.hashCode()).isEqualTo(def1.hashCode()); + assertThat(def1.hashCode()).isEqualTo(def1bis.hashCode()); + } + + @Test + public void test_compare() { + TaskDefinition foo = TaskDefinition.builder().key("foo").taskClass(FooTask.class).description("Foo").build(); + TaskDefinition bar = TaskDefinition.builder().key("bar").taskClass(FooTask.class).description("Bar").build(); + + assertThat(foo.compareTo(bar)).isGreaterThan(0); + assertThat(foo.compareTo(foo)).isEqualTo(0); + assertThat(bar.compareTo(foo)).isLessThan(0); + } + + @Test + public void description_should_be_required() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Description must be set for task 'foo'"); + TaskDefinition.builder().key("foo").taskClass(FooTask.class).build(); + } + + @Test + public void key_should_be_required() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Task key must be set"); + TaskDefinition.builder().description("Foo").taskClass(FooTask.class).build(); + } + + @Test + public void key_should_not_contain_spaces() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Task key 'fo o' must match " + TaskDefinition.KEY_PATTERN); + TaskDefinition.builder().key("fo o").description("foo").taskClass(FooTask.class).build(); + } + + @Test + public void class_should_be_required() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Class must be set for task 'foo'"); + TaskDefinition.builder().key("foo").description("Foo").build(); + } + + private static class FooTask implements Task { + public void execute() { + } + } +} |