Commits

Joe Clark committed 45c955b Merge

Merged pull request with local changes

Comments (0)

Files changed (11)

+target
+*.iml
+*.ipr
+*.iws
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-    <groupId>com.atlassian.bamboo.plugins.deploy</groupId>
-    <artifactId>continuous-plugin-deployment</artifactId>
-    <version>1.0-SNAPSHOT</version>
-
-    <organization>
-        <name>Atlassian</name>
-        <url>http://www.atlassian.com/</url>
-    </organization>
-
-    <name>continuous-plugin-deployment</name>
-    <description>Provides custom Bamboo tasks for continuously deploying Atlassian plugins to Confluence and JIRA.</description>
-    <packaging>atlassian-plugin</packaging>
-
-    <properties>
-        <bamboo.version>3.4</bamboo.version>
-        <bamboo.data.version>3.2.2</bamboo.data.version>
-    </properties>
-
-    <dependencies>
-        <!-- HTTP Client for multipart/form-data win -->
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient</artifactId>
-            <version>4.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpmime</artifactId>
-            <version>4.1</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.atlassian.bamboo</groupId>
-            <artifactId>atlassian-bamboo-web</artifactId>
-            <version>${bamboo.version}</version>
-            <scope>provided</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>commons-codec</groupId>
-                    <artifactId>commons-codec</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>commons-codec</groupId>
-            <artifactId>commons-codec</artifactId>
-            <version>1.4</version>
-        </dependency>
-
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.6</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-	 <distributionManagement>
-        <repository>
-            <id>atlassian-contrib</id>
-            <name>Atlassian Contrib Repository</name>
-            <url>dav:https://maven.atlassian.com/contrib/</url>
-        </repository>
-        <snapshotRepository>
-            <id>atlassian-contrib-snapshot</id>
-            <name>Atlassian Contrib Snapshot Repository</name>
-            <url>dav:https://maven.atlassian.com/contrib-snapshot</url>
-        </snapshotRepository>
-    </distributionManagement>
-	
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.atlassian.maven.plugins</groupId>
-                <artifactId>maven-bamboo-plugin</artifactId>
-                <version>3.4</version>
-                <extensions>true</extensions>
-                <configuration>
-                    <productVersion>${bamboo.version}</productVersion>
-                    <productDataVersion>${bamboo.data.version}</productDataVersion>
-                </configuration>
-            </plugin>
-	          <!--
-              If you have dependencies that ship with your plugin you should use the shade plugin to include them in the final jar
-              Uncomment the section below and add any jars you want to include by adding <include>groupId:artifactId</include> between the artifactSet elements.
-              See http://atlss.in/mhgZm6 for more information
-            -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-shade-plugin</artifactId>
-		            <version>1.4</version>
-                <executions>
-                   <execution>
-                     <phase>package</phase>
-                     <goals>
-                       <goal>shade</goal>
-                     </goals>
-                     <!--
-                     <configuration>
-                       <artifactSet>
-                          <includes>
-                            <include>com.mygroupid:my-artifact-id</include>
-                          </includes>
-                        </artifactSet>
-                      </configuration>
-                      -->
-                   </execution>
-                </executions>
-            </plugin>
-          
-            <plugin>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.6</source>
-                    <target>1.6</target>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.atlassian.bamboo.plugins.deploy</groupId>
+    <artifactId>continuous-plugin-deployment</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <organization>
+        <name>Atlassian</name>
+        <url>http://www.atlassian.com/</url>
+    </organization>
+
+    <name>continuous-plugin-deployment</name>
+    <description>Provides custom Bamboo tasks for continuously deploying Atlassian plugins to Confluence and JIRA.</description>
+    <packaging>atlassian-plugin</packaging>
+
+    <properties>
+        <bamboo.version>3.4</bamboo.version>
+        <bamboo.data.version>3.2.2</bamboo.data.version>
+    </properties>
+
+    <dependencies>
+        <!-- HTTP Client for multipart/form-data win -->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpmime</artifactId>
+            <version>4.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.atlassian.bamboo</groupId>
+            <artifactId>atlassian-bamboo-web</artifactId>
+            <version>${bamboo.version}</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-codec</groupId>
+                    <artifactId>commons-codec</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.atlassian.sal</groupId>
+            <artifactId>sal-api</artifactId>
+            <version>2.5.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.6</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+	 <distributionManagement>
+        <repository>
+            <id>atlassian-contrib</id>
+            <name>Atlassian Contrib Repository</name>
+            <url>dav:https://maven.atlassian.com/contrib/</url>
+        </repository>
+        <snapshotRepository>
+            <id>atlassian-contrib-snapshot</id>
+            <name>Atlassian Contrib Snapshot Repository</name>
+            <url>dav:https://maven.atlassian.com/contrib-snapshot</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>commons-logging</groupId>
+                <artifactId>commons-logging</artifactId>
+                <version>1.1.1</version>
+                <scope>provided</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.atlassian.maven.plugins</groupId>
+                <artifactId>maven-bamboo-plugin</artifactId>
+                <version>3.4</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <productVersion>${bamboo.version}</productVersion>
+                    <productDataVersion>${bamboo.data.version}</productDataVersion>
+                </configuration>
+            </plugin>
+	          <!--
+              If you have dependencies that ship with your plugin you should use the shade plugin to include them in the final jar
+              Uncomment the section below and add any jars you want to include by adding <include>groupId:artifactId</include> between the artifactSet elements.
+              See http://atlss.in/mhgZm6 for more information
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+		            <version>1.4</version>
+                <executions>
+                   <execution>
+                     <phase>package</phase>
+                     <goals>
+                       <goal>shade</goal>
+                     </goals>
+                     <!--
+                     <configuration>
+                       <artifactSet>
+                          <includes>
+                            <include>com.mygroupid:my-artifact-id</include>
+                          </includes>
+                        </artifactSet>
+                      </configuration>
+                      -->
+                   </execution>
+                </executions>
+            </plugin>
+          
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.6</source>
+                    <target>1.6</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

src/main/java/com/atlassian/bamboo/plugins/confdeploy/AutoDeployConfigurator.java

-package com.atlassian.bamboo.plugins.confdeploy;
-
-import com.atlassian.bamboo.build.Job;
-import com.atlassian.bamboo.collections.ActionParametersMap;
-import com.atlassian.bamboo.plan.artifact.ArtifactDefinition;
-import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionManager;
-import com.atlassian.bamboo.task.AbstractTaskConfigurator;
-import com.atlassian.bamboo.task.TaskDefinition;
-import com.atlassian.bamboo.utils.Pair;
-import com.atlassian.bamboo.utils.error.ErrorCollection;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.opensymphony.xwork.TextProvider;
-import org.apache.commons.lang.StringUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implements the logic for editing and configuring the task.
- */
-public class AutoDeployConfigurator extends AbstractTaskConfigurator
-{
-    private TextProvider textProvider;
-    private ArtifactSubscriptionManager artifactSubscriptionManager;
-
-    private static final Set<String> FIELDS_TO_COPY = Sets.newHashSet(
-            AutoDeployTask.PLUGIN_ARTIFACT,
-            AutoDeployTask.CONFLUENCE_BASE_URL,
-            AutoDeployTask.CONFLUENCE_ADMIN_USER
-    );
-
-    /**
-     * Converts the user's selected configuration into a persistable String/String map - this is the configuration map
-     * that will be passed into the task when it executes.
-     * <p/>
-     * The {@link AutoDeployConfigurator#validate(com.atlassian.bamboo.collections.ActionParametersMap, com.atlassian.bamboo.utils.error.ErrorCollection)}
-     * method is called, and must have succeeded, before this method is called.
-     *
-     * @param params                 The parameters entered in by the user.
-     * @param previousTaskDefinition
-     * @return
-     */
-    @NotNull
-    @Override
-    public Map<String, String> generateTaskConfigMap(@NotNull final ActionParametersMap params, @Nullable final TaskDefinition previousTaskDefinition)
-    {
-        final Map<String, String> config = super.generateTaskConfigMap(params, previousTaskDefinition);
-        config.put(AutoDeployTask.CONFLUENCE_BASE_URL, params.getString(AutoDeployTask.CONFLUENCE_BASE_URL));
-        config.put(AutoDeployTask.CONFLUENCE_ADMIN_USER, params.getString(AutoDeployTask.CONFLUENCE_ADMIN_USER));
-
-        // Encrypt the password before persisting
-        final String rawPassword = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD);
-        final Pair<String, String> encryptedPassword = Crypto.encrypt(rawPassword);
-        config.put(AutoDeployTask.CONFLUENCE_KEY, encryptedPassword.getFirst());
-        config.put(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD, encryptedPassword.getSecond());
-
-        // TODO: It would be better to store the unique ID of the artifact, but not sure how to get it from the WebWork front-end, just yet.
-        // Store the name instead.
-        config.put(AutoDeployTask.PLUGIN_ARTIFACT, params.getString(AutoDeployTask.PLUGIN_ARTIFACT));
-        return config;
-    }
-
-    /**
-     * Populates the default configuration for a new instance of the task (ie. this is where you should populate the
-     * {@param context} with sensible default values.... I think?
-     */
-    @Override
-    public void populateContextForCreate(@NotNull final Map<String, Object> context)
-    {
-        super.populateContextForCreate(context);
-
-        // Get all available subscribed artifacts from the parent Job
-        if (!context.containsKey("plan"))
-            return;
-
-        Job parent = (Job) context.get("plan");
-        List<AvailableArtifact> artifacts = Lists.transform(artifactSubscriptionManager.findSubscriptionsPossibleForPlan(parent),
-                new Function<ArtifactDefinition, AvailableArtifact>()
-                {
-                    @Override
-                    public AvailableArtifact apply(ArtifactDefinition artifactDefinition)
-                    {
-                        return new AvailableArtifact(artifactDefinition);
-                    }
-                });
-        context.put("artifacts", artifacts);
-
-        if (artifacts.size() > 0)
-            context.put(AutoDeployTask.PLUGIN_ARTIFACT, artifacts.get(0)); // select a default
-
-        context.put(AutoDeployTask.CONFLUENCE_BASE_URL, "eg. 'http://localhost:1990/confluence'");
-    }
-
-    /**
-     * Populates the configuration with its previously persisted config (ie. this is where you implement re-loading a
-     * saved configuration).
-     */
-    @Override
-    public void populateContextForEdit(@NotNull final Map<String, Object> context, @NotNull final TaskDefinition taskDefinition)
-    {
-        super.populateContextForEdit(context, taskDefinition);
-
-        // Get all available subscribed artifacts from the parent Job
-        if (!context.containsKey("plan"))
-            return;
-
-        Job parent = (Job) context.get("plan");
-        List<AvailableArtifact> artifacts = Lists.transform(artifactSubscriptionManager.findSubscriptionsPossibleForPlan(parent),
-                new Function<ArtifactDefinition, AvailableArtifact>()
-                {
-                    @Override
-                    public AvailableArtifact apply(ArtifactDefinition artifactDefinition)
-                    {
-                        return new AvailableArtifact(artifactDefinition);
-                    }
-                });
-        context.put("artifacts", artifacts);
-        taskConfiguratorHelper.populateContextWithConfiguration(context, taskDefinition, FIELDS_TO_COPY);
-    }
-
-    /**
-     * Populates the configuration in a read-only context.
-     *
-     * @param context
-     * @param taskDefinition
-     */
-    @Override
-    public void populateContextForView(@NotNull final Map<String, Object> context, @NotNull final TaskDefinition taskDefinition)
-    {
-        super.populateContextForView(context, taskDefinition);
-        taskConfiguratorHelper.populateContextWithConfiguration(context, taskDefinition, FIELDS_TO_COPY);
-    }
-
-    /**
-     * Called when the configuration is saved by the user - ensures that the selected configuration is valid. Add new errors
-     * if it is not.
-     */
-    @Override
-    public void validate(@NotNull final ActionParametersMap params, @NotNull final ErrorCollection errorCollection)
-    {
-        super.validate(params, errorCollection);
-
-        final String baseURL = params.getString(AutoDeployTask.CONFLUENCE_BASE_URL);
-        if (StringUtils.isBlank(baseURL))
-        {
-            errorCollection.addError(AutoDeployTask.CONFLUENCE_BASE_URL, textProvider.getText("confdeploy.url.error"));
-        }
-
-        final String username = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_USER);
-        if (StringUtils.isBlank(username))
-        {
-            errorCollection.addError(AutoDeployTask.CONFLUENCE_ADMIN_USER, textProvider.getText("confdeploy.username.error"));
-        }
-
-        final String password = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD);
-        if (StringUtils.isBlank(password))
-        {
-            errorCollection.addError(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD, textProvider.getText("confdeploy.password.error"));
-        }
-
-
-        final String artifactName = params.getString(AutoDeployTask.PLUGIN_ARTIFACT);
-        if (StringUtils.isBlank(artifactName))
-        {
-            // TODO: Ensure artifact is a single jar file
-            errorCollection.addError(AutoDeployTask.PLUGIN_ARTIFACT, textProvider.getText("confdeploy.artifact.error"));
-        }
-
-    }
-
-    /**
-     * Setter injection
-     */
-    public void setArtifactSubscriptionManager(final ArtifactSubscriptionManager artifactSubscriptionManager)
-    {
-        this.artifactSubscriptionManager = artifactSubscriptionManager;
-    }
-
-    /**
-     * Setter injection
-     */
-    public void setTextProvider(final TextProvider textProvider)
-    {
-        this.textProvider = textProvider;
-    }
-}
+package com.atlassian.bamboo.plugins.confdeploy;
+
+import com.atlassian.bamboo.build.Job;
+import com.atlassian.bamboo.collections.ActionParametersMap;
+import com.atlassian.bamboo.plan.artifact.ArtifactDefinition;
+import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionManager;
+import com.atlassian.bamboo.task.AbstractTaskConfigurator;
+import com.atlassian.bamboo.task.TaskDefinition;
+import com.atlassian.bamboo.utils.Pair;
+import com.atlassian.bamboo.utils.error.ErrorCollection;
+import com.atlassian.plugin.util.ContextClassLoaderSwitchingUtil;
+import com.atlassian.sal.api.component.ComponentLocator;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.opensymphony.xwork.TextProvider;
+import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Implements the logic for editing and configuring the task.
+ */
+public class AutoDeployConfigurator extends AbstractTaskConfigurator
+{
+    private static final Set<String> FIELDS_TO_COPY = Sets.newHashSet(
+            AutoDeployTask.PLUGIN_ARTIFACT,
+            AutoDeployTask.CONFLUENCE_BASE_URL,
+            AutoDeployTask.CONFLUENCE_ADMIN_USER
+    );
+
+    /**
+     * Converts the user's selected configuration into a persistable String/String map - this is the configuration map
+     * that will be passed into the task when it executes.
+     * <p/>
+     * The {@link AutoDeployConfigurator#validate(com.atlassian.bamboo.collections.ActionParametersMap, com.atlassian.bamboo.utils.error.ErrorCollection)}
+     * method is called, and must have succeeded, before this method is called.
+     *
+     * @param params                 The parameters entered in by the user.
+     * @param previousTaskDefinition
+     * @return
+     */
+    @NotNull
+    @Override
+    public Map<String, String> generateTaskConfigMap(@NotNull final ActionParametersMap params, @Nullable final TaskDefinition previousTaskDefinition)
+    {
+        final Map<String, String> config = super.generateTaskConfigMap(params, previousTaskDefinition);
+        config.put(AutoDeployTask.CONFLUENCE_BASE_URL, params.getString(AutoDeployTask.CONFLUENCE_BASE_URL));
+        config.put(AutoDeployTask.CONFLUENCE_ADMIN_USER, params.getString(AutoDeployTask.CONFLUENCE_ADMIN_USER));
+
+        // Encrypt the password before persisting
+        final String rawPassword = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD);
+        final Pair<String, String> encryptedPassword = Crypto.encrypt(rawPassword);
+        config.put(AutoDeployTask.CONFLUENCE_KEY, encryptedPassword.getFirst());
+        config.put(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD, encryptedPassword.getSecond());
+
+        // TODO: It would be better to store the unique ID of the artifact, but not sure how to get it from the WebWork front-end, just yet.
+        // Store the name instead.
+        config.put(AutoDeployTask.PLUGIN_ARTIFACT, params.getString(AutoDeployTask.PLUGIN_ARTIFACT));
+        return config;
+    }
+
+    /**
+     * Populates the default configuration for a new instance of the task (ie. this is where you should populate the
+     * {@param context} with sensible default values.... I think?
+     */
+    @Override
+    public void populateContextForCreate(@NotNull final Map<String, Object> context)
+    {
+        super.populateContextForCreate(context);
+
+        // Get all available subscribed artifacts from the parent Job
+        if (!context.containsKey("plan"))
+            return;
+
+        Job parent = (Job) context.get("plan");
+        ArtifactSubscriptionManager artifactSubscriptionManager = ServiceAccessor.getArtifactSubscriptionManager();
+        List<String> artifacts = Lists.transform(artifactSubscriptionManager.findSubscriptionsPossibleForPlan(parent),
+                new Function<ArtifactDefinition, String>()
+                {
+                    @Override
+                    public String apply(ArtifactDefinition artifactDefinition)
+                    {
+                        return new AvailableArtifact(artifactDefinition).toString();
+                    }
+                });
+        context.put("artifacts", artifacts);
+
+        if (artifacts.size() > 0)
+            context.put(AutoDeployTask.PLUGIN_ARTIFACT, artifacts.get(0)); // select a default
+
+        context.put(AutoDeployTask.CONFLUENCE_BASE_URL, "eg. 'http://localhost:1990/confluence'");
+    }
+
+    /**
+     * Populates the configuration with its previously persisted config (ie. this is where you implement re-loading a
+     * saved configuration).
+     */
+    @Override
+    public void populateContextForEdit(@NotNull final Map<String, Object> context, @NotNull final TaskDefinition taskDefinition)
+    {
+        super.populateContextForEdit(context, taskDefinition);
+
+        // Get all available subscribed artifacts from the parent Job
+        if (!context.containsKey("plan"))
+            return;
+
+        Job parent = (Job) context.get("plan");
+        ArtifactSubscriptionManager artifactSubscriptionManager = ServiceAccessor.getArtifactSubscriptionManager();
+        List<String> artifacts = Lists.transform(artifactSubscriptionManager.findSubscriptionsPossibleForPlan(parent),
+                new Function<ArtifactDefinition, String>()
+                {
+                    @Override
+                    public String apply(ArtifactDefinition artifactDefinition)
+                    {
+                        return new AvailableArtifact(artifactDefinition).toString();
+                    }
+                });
+        context.put("artifacts", artifacts);
+        taskConfiguratorHelper.populateContextWithConfiguration(context, taskDefinition, FIELDS_TO_COPY);
+    }
+
+    /**
+     * Populates the configuration in a read-only context.
+     *
+     * @param context
+     * @param taskDefinition
+     */
+    @Override
+    public void populateContextForView(@NotNull final Map<String, Object> context, @NotNull final TaskDefinition taskDefinition)
+    {
+        super.populateContextForView(context, taskDefinition);
+        taskConfiguratorHelper.populateContextWithConfiguration(context, taskDefinition, FIELDS_TO_COPY);
+    }
+
+    /**
+     * Called when the configuration is saved by the user - ensures that the selected configuration is valid. Add new errors
+     * if it is not.
+     */
+    @Override
+    public void validate(@NotNull final ActionParametersMap params, @NotNull final ErrorCollection errorCollection)
+    {
+        super.validate(params, errorCollection);
+
+        // this is all a shitty workaround for https://jira.atlassian.com/browse/BAM-10549
+        ContextClassLoaderSwitchingUtil.runInContext(getClass().getClassLoader(), new Runnable()
+        {
+            @Override
+            public void run()
+            {
+                TextProvider textProvider = ComponentLocator.getComponent(TextProvider.class);
+                final String baseURL = params.getString(AutoDeployTask.CONFLUENCE_BASE_URL);
+                if (StringUtils.isBlank(baseURL))
+                {
+                    errorCollection.addError(AutoDeployTask.CONFLUENCE_BASE_URL, textProvider.getText("confdeploy.url.error"));
+                }
+
+                final String username = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_USER);
+                if (StringUtils.isBlank(username))
+                {
+                    errorCollection.addError(AutoDeployTask.CONFLUENCE_ADMIN_USER, textProvider.getText("confdeploy.username.error"));
+                }
+
+                final String password = params.getString(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD);
+                if (StringUtils.isBlank(password))
+                {
+                    errorCollection.addError(AutoDeployTask.CONFLUENCE_ADMIN_PASSWORD, textProvider.getText("confdeploy.password.error"));
+                }
+
+
+                final String artifactName = params.getString(AutoDeployTask.PLUGIN_ARTIFACT);
+                if (StringUtils.isBlank(artifactName))
+                {
+                    // TODO: Ensure artifact is a single jar file
+                    errorCollection.addError(AutoDeployTask.PLUGIN_ARTIFACT, textProvider.getText("confdeploy.jar.error"));
+                }
+            }
+        });
+
+
+    }
+}

src/main/java/com/atlassian/bamboo/plugins/confdeploy/AutoDeployTask.java

-package com.atlassian.bamboo.plugins.confdeploy;
-
-import com.atlassian.bamboo.build.logger.BuildLogger;
-import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionContext;
-import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionManager;
-import com.atlassian.bamboo.task.TaskContext;
-import com.atlassian.bamboo.task.TaskException;
-import com.atlassian.bamboo.task.TaskResult;
-import com.atlassian.bamboo.task.TaskResultBuilder;
-import com.atlassian.bamboo.task.TaskType;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-
-public abstract class AutoDeployTask implements TaskType
-{
-    public static final String PLUGIN_ARTIFACT = "confDeployJar";
-    public static final String CONFLUENCE_BASE_URL = "confDeployURL";
-    public static final String CONFLUENCE_ADMIN_USER = "confDeployUsername";
-    public static final String CONFLUENCE_ADMIN_PASSWORD = "confDeployPassword";
-    public static final String CONFLUENCE_KEY = "confDeployKey";
-
-    private static final String ENDPOINT_RELATIVE_URL = "rpc/soap-axis/confluenceservice-v2";
-
-    private ArtifactSubscriptionManager artifactSubscriptionManager;
-
-    public void setArtifactSubscriptionManager(ArtifactSubscriptionManager artifactSubscriptionManager)
-    {
-        this.artifactSubscriptionManager = artifactSubscriptionManager;
-    }
-
-    public abstract Product getTargetProduct();
-
-    private static String urlConcat(String base, String relative)
-    {
-        if (base.endsWith("/"))
-        {
-            return base + relative;
-        }
-        return base + "/" + relative;
-    }
-
-    @NotNull
-    @java.lang.Override
-    public TaskResult execute(@NotNull final TaskContext taskContext) throws TaskException
-    {
-        final BuildLogger buildLogger = taskContext.getBuildLogger();
-
-        // Extract the required parameters
-        final String confluenceBaseURL = taskContext.getConfigurationMap().get(CONFLUENCE_BASE_URL);
-        final String actualURL = urlConcat(confluenceBaseURL, ENDPOINT_RELATIVE_URL);
-
-        final String username = taskContext.getConfigurationMap().get(CONFLUENCE_ADMIN_USER);
-        final String encryptedPassword = taskContext.getConfigurationMap().get(CONFLUENCE_ADMIN_PASSWORD);
-        final String passwordKey = taskContext.getConfigurationMap().get(CONFLUENCE_KEY);
-        final String rawPassword = Crypto.decrypt(passwordKey, encryptedPassword);
-
-        // Retrieve the referenced artifact definition
-        final String artifactKey = taskContext.getConfigurationMap().get(PLUGIN_ARTIFACT);
-
-        // TODO: Retrieve the artifact subscription by ID
-        //final ArtifactSubscription pluginArtifact = artifactSubscriptionManager.findSubscription(Long.valueOf(artifactKey));
-
-        // Ensure that the artifact exists and is accessible.
-        File pluginJar = null;
-        for (ArtifactSubscriptionContext context : taskContext.getBuildContext().getArtifactContext().getSubscriptionContexts())
-        {
-            if (context.getArtifactDefinitionContext().getName().equals(artifactKey))
-            {
-                pluginJar = new File(context.getEffectiveDestinationPath());
-                break;
-            }
-        }
-        if (pluginJar == null)
-        {
-            final String msg = String.format("Unable to find the artifact with id %s in this task's context", artifactKey);
-            buildLogger.addErrorLogEntry(msg);
-            throw new TaskException(msg);
-        }
-
-        if (!pluginJar.exists() || !pluginJar.isFile())
-        {
-            final String msg = String.format("Artifact file %s is either missing or not a file.", pluginJar.getAbsolutePath());
-            buildLogger.addErrorLogEntry(msg);
-            throw new TaskException(msg);
-        }
-
-        UniversalPluginUploader uploader = new UniversalPluginUploader(buildLogger);
-        uploader.upload(getTargetProduct(), pluginJar, confluenceBaseURL, username, rawPassword);
-
-
-        return TaskResultBuilder.create(taskContext).success().build();
-    }
+package com.atlassian.bamboo.plugins.confdeploy;
+
+import com.atlassian.bamboo.build.logger.BuildLogger;
+import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionContext;
+import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionManager;
+import com.atlassian.bamboo.task.TaskContext;
+import com.atlassian.bamboo.task.TaskException;
+import com.atlassian.bamboo.task.TaskResult;
+import com.atlassian.bamboo.task.TaskResultBuilder;
+import com.atlassian.bamboo.task.TaskType;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public abstract class AutoDeployTask implements TaskType
+{
+    public static final String PLUGIN_ARTIFACT = "confDeployJar";
+    public static final String CONFLUENCE_BASE_URL = "confDeployURL";
+    public static final String CONFLUENCE_ADMIN_USER = "confDeployUsername";
+    public static final String CONFLUENCE_ADMIN_PASSWORD = "confDeployPassword";
+    public static final String CONFLUENCE_KEY = "confDeployKey";
+
+    private static final String ENDPOINT_RELATIVE_URL = "rpc/soap-axis/confluenceservice-v2";
+
+    public abstract Product getTargetProduct();
+
+    private static String urlConcat(String base, String relative)
+    {
+        if (base.endsWith("/"))
+        {
+            return base + relative;
+        }
+        return base + "/" + relative;
+    }
+
+    @NotNull
+    @java.lang.Override
+    public TaskResult execute(@NotNull final TaskContext taskContext) throws TaskException
+    {
+        final BuildLogger buildLogger = taskContext.getBuildLogger();
+
+        // Extract the required parameters
+        final String confluenceBaseURL = taskContext.getConfigurationMap().get(CONFLUENCE_BASE_URL);
+        final String actualURL = urlConcat(confluenceBaseURL, ENDPOINT_RELATIVE_URL);
+
+        final String username = taskContext.getConfigurationMap().get(CONFLUENCE_ADMIN_USER);
+        final String encryptedPassword = taskContext.getConfigurationMap().get(CONFLUENCE_ADMIN_PASSWORD);
+        final String passwordKey = taskContext.getConfigurationMap().get(CONFLUENCE_KEY);
+        final String rawPassword = Crypto.decrypt(passwordKey, encryptedPassword);
+
+        // Retrieve the referenced artifact definition
+        final String artifactKey = taskContext.getConfigurationMap().get(PLUGIN_ARTIFACT);
+
+        // TODO: Retrieve the artifact subscription by ID
+        //final ArtifactSubscription pluginArtifact = artifactSubscriptionManager.findSubscription(Long.valueOf(artifactKey));
+
+        // Ensure that the artifact exists and is accessible.
+        File pluginJar = null;
+        for (ArtifactSubscriptionContext context : taskContext.getBuildContext().getArtifactContext().getSubscriptionContexts())
+        {
+            if (context.getArtifactDefinitionContext().getName().equals(artifactKey))
+            {
+                pluginJar = new File(context.getEffectiveDestinationPath());
+                break;
+            }
+        }
+        if (pluginJar == null)
+        {
+            final String msg = String.format("Unable to find the artifact with id %s in this task's context", artifactKey);
+            buildLogger.addErrorLogEntry(msg);
+            throw new TaskException(msg);
+        }
+
+        if (!pluginJar.exists() || !pluginJar.isFile())
+        {
+            final String msg = String.format("Artifact file %s is either missing or not a file.", pluginJar.getAbsolutePath());
+            buildLogger.addErrorLogEntry(msg);
+            throw new TaskException(msg);
+        }
+
+        UniversalPluginUploader uploader = new UniversalPluginUploader(buildLogger);
+        uploader.upload(getTargetProduct(), pluginJar, confluenceBaseURL, username, rawPassword);
+
+
+        return TaskResultBuilder.create(taskContext).success().build();
+    }
 }

src/main/java/com/atlassian/bamboo/plugins/confdeploy/ServiceAccessor.java

+package com.atlassian.bamboo.plugins.confdeploy;
+
+import com.atlassian.bamboo.plan.artifact.ArtifactSubscriptionManager;
+import com.atlassian.sal.api.component.ComponentLocator;
+
+/**
+ *
+ */
+public class ServiceAccessor
+{
+    public static ArtifactSubscriptionManager getArtifactSubscriptionManager()
+    {
+        return ComponentLocator.getComponent(ArtifactSubscriptionManager.class);
+    }
+}

src/main/resources/atlassian-plugin.xml

-<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="1">
-    <!--
-    note that this plugin has to be a plugins-version '1' plugin as build module types (repositories, tasks, pre/post processors)
-    are plugins v1 only. Module types such as REST, Gadgets, Servlets and Filters are plugins v2 and cannot be mixed in the same
-    plugin as plugins v1 module types for the time being
-    -->
+<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
     <plugin-info>
         <description>${project.description}</description>
         <version>${project.version}</version>
         <description>Automatically deploys an Atlassian plugin artifact to a Confluence server.</description>
         <category name="deployment"/>
         <configuration class="com.atlassian.bamboo.plugins.confdeploy.AutoDeployConfigurator"/>
-        <resource type="freemarker" name="edit" location="editExampleTask.ftl"/>
-        <resource type="freemarker" name="view" location="viewExampleTask.ftl"/>
+        <resource type="freemarker" name="edit" location="editTask.ftl"/>
+        <resource type="freemarker" name="view" location="viewTask.ftl"/>
     </taskType>
 
     <taskType name="Deploy JIRA Plugin" class="com.atlassian.bamboo.plugins.confdeploy.JiraDeployTask" key="jiradeploy">
         <description>Automatically deploys an Atlassian plugin artifact to a JIRA Server.</description>
         <category name="deployment"/>
         <configuration class="com.atlassian.bamboo.plugins.confdeploy.AutoDeployConfigurator"/>
-        <resource type="freemarker" name="edit" location="editExampleTask.ftl"/>
-        <resource type="freemarker" name="view" location="viewExampleTask.ftl"/>
+        <resource type="freemarker" name="edit" location="editTask.ftl"/>
+        <resource type="freemarker" name="view" location="viewTask.ftl"/>
     </taskType>
+
 </atlassian-plugin>
 

src/main/resources/editExampleTask.ftl

-[#-- ftlvariable name="context" type="java.util.Map<String, Object." --]
-
-[@ww.select cssClass="builderSelectWidget" labelKey="confdeploy.jar" name="confDeployJar" list=context.get("artifacts") required="true" /]
-[@ww.textfield cssClass="long-field" labelKey="confdeploy.url" name="confDeployURL" required="true" /]
-[@ww.textfield cssClass="long-field" labelKey="confdeploy.username" name="confDeployUsername" /]
-[@ww.textfield cssClass="long-field" labelKey="confdeploy.password" name="confDeployPassword" /]
-
-
-
-

src/main/resources/editTask.ftl

+[#-- ftlvariable name="context" type="java.util.Map<String, Object." --]
+
+[@ww.select cssClass="builderSelectWidget" labelKey="confdeploy.jar" name="confDeployJar" list=context.get("artifacts") required="true" /]
+[@ww.textfield cssClass="long-field" labelKey="confdeploy.url" name="confDeployURL" required="true" /]
+[@ww.textfield cssClass="long-field" labelKey="confdeploy.username" name="confDeployUsername" required="true"/]
+[@ww.textfield cssClass="long-field" labelKey="confdeploy.password" name="confDeployPassword" required="true" /]
+
+
+
+

src/main/resources/english.properties

 confdeploy.jar.description = The Plugin Artifact to be installed
 confdeploy.jar.error = Plugin artifact must be specified
 
-confdeploy.url = Confluence Base URL
-confdeploy.url.description = The Base URL of the target Confluence instance
+confdeploy.url = Atlassian Application Base URL
+confdeploy.url.description = The Base URL of the target Atlassian Application instance
 confdeploy.url.error = Confluence Base URL is invalid
 
 confdeploy.username = Username
-confdeploy.username.description = Confluence System Administrator username
+confdeploy.username.description = Atlassian Application System Administrator username
 confdeploy.username.error = Username must be specified
 
 confdeploy.password = Password
-confdeploy.password.description = Confluence System Administrator password
+confdeploy.password.description = Atlassian Application System Administrator password
 confdeploy.password.error = Password must be specified
 
 

src/main/resources/viewExampleTask.ftl

-[@ww.label labelKey="confdeploy.jar" name="confDeployJar" /]
-[@ww.label labelKey="confdeploy.url" name="confDeployURL" /]
-[@ww.label labelKey="confdeploy.username" name="confDeployUsername" /]

src/main/resources/viewTask.ftl

+[@ww.label labelKey="confdeploy.jar" name="confDeployJar" /]
+[@ww.label labelKey="confdeploy.url" name="confDeployURL" /]
+[@ww.label labelKey="confdeploy.username" name="confDeployUsername" /]