You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2024/11/26 09:17:03 UTC
(maven-changes-plugin) branch master updated: [MCHANGES-428] Use HttpClient in RestJiraDownloader
This is an automated email from the ASF dual-hosted git repository.
sjaranowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-changes-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 4502d7c [MCHANGES-428] Use HttpClient in RestJiraDownloader
4502d7c is described below
commit 4502d7c93e8fa6400848f247612ee517ce1d8400
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Sat Nov 23 19:51:20 2024 +0100
[MCHANGES-428] Use HttpClient in RestJiraDownloader
---
pom.xml | 16 +-
src/it/report-jira/pom.xml | 78 +++
src/it/report-jira/setup.groovy | 124 +++++
.../report-jira/verify.groovy} | 30 +-
src/it/settings-security.xml | 22 +
src/it/settings.xml | 9 +
.../plugins/announcement/AnnouncementMojo.java | 33 +-
.../org/apache/maven/plugins/issues/Issue.java | 13 -
.../maven/plugins/jira/AbstractJiraDownloader.java | 357 -------------
.../org/apache/maven/plugins/jira/JiraReport.java | 57 +-
.../org/apache/maven/plugins/jira/JiraXML.java | 198 -------
.../maven/plugins/jira/RestJiraDownloader.java | 583 +++++++++++++++------
.../apache/maven/plugins/jira/JiraReportTest.java | 2 +-
.../maven/plugins/jira/JiraUnicodeTestCase.java | 26 +-
.../maven/plugins/jira/MockJiraDownloader.java | 57 --
.../maven/plugins/jira/unicode-jira-results.xml | 330 ------------
16 files changed, 733 insertions(+), 1202 deletions(-)
diff --git a/pom.xml b/pom.xml
index 474e20c..0b2ab70 100644
--- a/pom.xml
+++ b/pom.xml
@@ -300,12 +300,6 @@ under the License.
<version>${doxiaVersion}</version>
</dependency>
- <!-- rest client for jira -->
- <dependency>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-frontend-jaxrs</artifactId>
- <version>2.6.11</version>
- </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
@@ -459,7 +453,17 @@ under the License.
<goal>clean</goal>
<goal>site</goal>
</goals>
+ <properties>
+ <settings.security>${project.basedir}/src/it/settings-security.xml</settings.security>
+ </properties>
</configuration>
+ <dependencies>
+ <dependency>
+ <groupId>com.github.tomakehurst</groupId>
+ <artifactId>wiremock-standalone</artifactId>
+ <version>2.27.2</version>
+ </dependency>
+ </dependencies>
</plugin>
</plugins>
</pluginManagement>
diff --git a/src/it/report-jira/pom.xml b/src/it/report-jira/pom.xml
new file mode 100644
index 0000000..49c3ed5
--- /dev/null
+++ b/src/it/report-jira/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+<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>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin-test</artifactId>
+ <version>99.0</version>
+ <name>Maven</name>
+ <packaging>jar</packaging>
+
+ <properties>
+ <changesPluginVersion>@project.version@</changesPluginVersion>
+ </properties>
+
+ <issueManagement>
+ <system>jira</system>
+ <url>${mockServerUrl}/browse/TEST_PROJECT</url>
+ </issueManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changesPluginVersion}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>@sitePluginVersion@</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <reporting>
+ <excludeDefaults>true</excludeDefaults>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>@project.version@</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>jira-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <jiraServerId>jira</jiraServerId>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
diff --git a/src/it/report-jira/setup.groovy b/src/it/report-jira/setup.groovy
new file mode 100644
index 0000000..dee803d
--- /dev/null
+++ b/src/it/report-jira/setup.groovy
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+
+import com.github.tomakehurst.wiremock.WireMockServer
+import com.github.tomakehurst.wiremock.client.WireMock
+import com.github.tomakehurst.wiremock.common.ConsoleNotifier
+import com.github.tomakehurst.wiremock.core.WireMockConfiguration
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse
+import static com.github.tomakehurst.wiremock.client.WireMock.configureFor
+import static com.github.tomakehurst.wiremock.client.WireMock.equalTo
+import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson
+import static com.github.tomakehurst.wiremock.client.WireMock.get
+import static com.github.tomakehurst.wiremock.client.WireMock.post
+import static com.github.tomakehurst.wiremock.client.WireMock.stubFor
+
+WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.options()
+ .dynamicPort()
+ .notifier(new ConsoleNotifier(false)))
+wireMockServer.start()
+
+def userProperties = context.get('userProperties')
+userProperties.put('mockServerUrl', wireMockServer.baseUrl())
+
+configureFor(wireMockServer.port())
+
+stubFor(get('/rest/api/2/serverInfo')
+ .withHeader('accept', equalTo('application/json'))
+ .willReturn(aResponse().withStatus(200)))
+
+stubFor(post('/rest/auth/1/session')
+ .withHeader('accept', equalTo('application/json'))
+ .withHeader('content-type', equalTo('application/json'))
+ .withRequestBody(equalToJson('{"username" : "jira-test", "password" : "jira-password"}'))
+ .willReturn(aResponse()
+ .withStatus(200)
+ .withHeader('Set-Cookie', 'JSESSIONID=D6961281D4A029FFA4E6BC8A526CF5CC; Path=/; HttpOnly')))
+
+stubFor(get('/rest/api/2/status')
+ .withHeader('accept', equalTo('application/json'))
+ .withCookie('JSESSIONID', equalTo('D6961281D4A029FFA4E6BC8A526CF5CC'))
+ .willReturn(aResponse().withStatus(200)
+ .withBody('[{"name": "Closed","id": "6"}]')))
+
+stubFor(get('/rest/api/2/resolution')
+ .withHeader('accept', equalTo('application/json'))
+ .withCookie('JSESSIONID', equalTo('D6961281D4A029FFA4E6BC8A526CF5CC'))
+ .willReturn(aResponse().withStatus(200)
+ .withBody('[{"name": "Fixed","id": "1"}]')))
+
+stubFor(post('/rest/api/2/search')
+ .withHeader('accept', equalTo('application/json'))
+ .withHeader('content-type', equalTo('application/json'))
+ .withCookie('JSESSIONID', equalTo('D6961281D4A029FFA4E6BC8A526CF5CC'))
+ .withRequestBody(equalToJson('''
+ {"jql":"project = TEST_PROJECT AND status in (6) AND resolution in (1) ORDER BY priority DESC, created DESC",
+ "maxResults":100, "fields":["*all"]}
+'''))
+ .willReturn(aResponse().withStatus(200)
+ .withBody('''
+{
+ "issues": [
+ {
+ "id": "13036790",
+ "key": "TEST_PROJECT-1",
+ "fields": {
+ "assignee": {
+ "name": "assigned-user",
+ "displayName": "Assigned User"
+ },
+ "created": "2024-11-21T12:10:35.000+0000",
+ "updated": "2024-11-22T20:05:52.000+0000",
+ "components": [
+ { "name": "jira" }
+ ],
+ "fixVersions": [
+ { "name": "2.1" },
+ { "name": "3.1" }
+ ],
+ "issuetype": {
+ "name": "Bug"
+ },
+ "priority": {
+ "name": "Bug"
+ },
+ "reporter": {
+ "name": "reporter-user",
+ "displayName": "~Reporter User"
+ },
+ "resolution": {
+ "name": "Fixed"
+ },
+ "status": {
+ "name": "Closed"
+ },
+ "summary": "Authentication does not work after Upgrade",
+ "versions": [
+ { "name": "2.12.1" }
+ ]
+ }
+ }]
+}
+''')))
+
+context.put("wireMockServer", wireMockServer)
+true
+
diff --git a/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java b/src/it/report-jira/verify.groovy
similarity index 54%
copy from src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java
copy to src/it/report-jira/verify.groovy
index a27babf..20f8f59 100644
--- a/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java
+++ b/src/it/report-jira/verify.groovy
@@ -16,26 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.maven.plugins.jira;
-import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import com.github.tomakehurst.wiremock.WireMockServer
-/**
- * Unit tests for {@link JiraReport}.
- *
- * @author jrh3k5
- * @since 2.8
- */
-public class JiraReportTest extends AbstractMojoTestCase {
- private final JiraReport mojo = new JiraReport();
+WireMockServer wireMockServer = context.get("wireMockServer")
+wireMockServer.stop()
+
+content = new File( basedir, 'target/site/jira-report.html' ).text;
- /**
- * If the mojo has been marked to be skipped, then it should indicate that the report cannot be generated.
- *
- * @throws Exception If any errors occur during the test run.
- */
- public void testCanGenerateReportSkipped() throws Exception {
- setVariableValueToObject(mojo, "skip", Boolean.TRUE);
- assertFalse(mojo.canGenerateReport());
- }
-}
+assert content.contains('/browse/TEST_PROJECT-1">TEST_PROJECT-1</a>');
+assert content.contains('<td>Authentication does not work after Upgrade</td>');
+assert content.contains('<td>Closed</td>');
+assert content.contains('<td>Fixed</td>');
+assert content.contains('<td>Assigned User</td>');
diff --git a/src/it/settings-security.xml b/src/it/settings-security.xml
new file mode 100644
index 0000000..4a6047f
--- /dev/null
+++ b/src/it/settings-security.xml
@@ -0,0 +1,22 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+
+<settingsSecurity>
+ <master>{6TQXSXGMHWkHu6psfqOMMkXdy+tezkPMk5wcTB9B0VY=}</master>
+</settingsSecurity>
diff --git a/src/it/settings.xml b/src/it/settings.xml
index c8f77f0..a57ccfa 100644
--- a/src/it/settings.xml
+++ b/src/it/settings.xml
@@ -52,4 +52,13 @@ under the License.
</pluginRepositories>
</profile>
</profiles>
+
+ <servers>
+ <server>
+ <id>jira</id>
+ <username>jira-test</username>
+ <!-- <password>jira-password</password> -->
+ <password>{xZLx2669VMsHnW8pO9Ehd1FLMrPsCOQ3g2MiRNNA5vI=}</password>
+ </server>
+ </servers>
</settings>
diff --git a/src/main/java/org/apache/maven/plugins/announcement/AnnouncementMojo.java b/src/main/java/org/apache/maven/plugins/announcement/AnnouncementMojo.java
index a86ca3f..aa3f356 100644
--- a/src/main/java/org/apache/maven/plugins/announcement/AnnouncementMojo.java
+++ b/src/main/java/org/apache/maven/plugins/announcement/AnnouncementMojo.java
@@ -44,13 +44,11 @@ import org.apache.maven.plugins.github.GitHubIssueManagementSystem;
import org.apache.maven.plugins.issues.Issue;
import org.apache.maven.plugins.issues.IssueManagementSystem;
import org.apache.maven.plugins.issues.IssueUtils;
-import org.apache.maven.plugins.jira.AbstractJiraDownloader;
import org.apache.maven.plugins.jira.JIRAIssueManagmentSystem;
import org.apache.maven.plugins.jira.RestJiraDownloader;
import org.apache.maven.plugins.trac.TracDownloader;
import org.apache.maven.plugins.trac.TracIssueManagmentSystem;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.apache.velocity.Template;
@@ -299,12 +297,6 @@ public class AnnouncementMojo extends AbstractAnnouncementMojo {
@Parameter(property = "changes.jiraServerId")
private String jiraServerId;
- /**
- * Path to the JIRA XML file, which will be parsed.
- */
- @Parameter(defaultValue = "${project.build.directory}/jira-announcement.xml", required = true, readonly = true)
- private File jiraXML;
-
/**
* The maximum number of issues to fetch from JIRA.
*/
@@ -338,7 +330,9 @@ public class AnnouncementMojo extends AbstractAnnouncementMojo {
* Defines the http user for basic authentication into the JIRA webserver.
*
* @since 2.4
+ * @deprecated use {@link #jiraUser} or {@link #jiraServerId}
*/
+ @Deprecated
@Parameter(property = "changes.webUser")
private String webUser;
@@ -346,7 +340,9 @@ public class AnnouncementMojo extends AbstractAnnouncementMojo {
* Defines the http password for basic authentication into the JIRA webserver.
*
* @since 2.4
+ * @deprecated use {@link #jiraPassword} or {@link #jiraServerId}
*/
+ @Deprecated
@Parameter(property = "changes.webPassword")
private String webPassword;
@@ -684,14 +680,10 @@ public class AnnouncementMojo extends AbstractAnnouncementMojo {
}
protected List<Release> getJiraReleases() throws MojoExecutionException {
- AbstractJiraDownloader jiraDownloader = new RestJiraDownloader();
-
- File jiraXMLFile = jiraXML;
+ RestJiraDownloader jiraDownloader = new RestJiraDownloader();
jiraDownloader.setLog(getLog());
- jiraDownloader.setOutput(jiraXMLFile);
-
jiraDownloader.setStatusIds(statusIds);
jiraDownloader.setResolutionIds(resolutionIds);
@@ -699,24 +691,21 @@ public class AnnouncementMojo extends AbstractAnnouncementMojo {
jiraDownloader.setMavenProject(project);
jiraDownloader.setSettings(settings);
+ jiraDownloader.setSettingsDecrypter(settingsDecrypter);
jiraDownloader.setNbEntries(maxEntries);
jiraDownloader.setFilter(filter);
- if (jiraServerId != null) {
- final Server server = mavenSession.getSettings().getServer(jiraServerId);
- jiraDownloader.setJiraUser(server.getUsername());
- jiraDownloader.setJiraPassword(server.getPassword());
- } else {
+ jiraDownloader.setJiraServerId(jiraServerId);
+ if (jiraUser != null) {
jiraDownloader.setJiraUser(jiraUser);
jiraDownloader.setJiraPassword(jiraPassword);
+ } else if (webUser != null) {
+ jiraDownloader.setJiraUser(webUser);
+ jiraDownloader.setJiraPassword(webPassword);
}
- jiraDownloader.setWebUser(webUser);
-
- jiraDownloader.setWebPassword(webPassword);
-
jiraDownloader.setConnectionTimeout(jiraConnectionTimeout);
jiraDownloader.setReceiveTimout(jiraReceiveTimout);
diff --git a/src/main/java/org/apache/maven/plugins/issues/Issue.java b/src/main/java/org/apache/maven/plugins/issues/Issue.java
index 8947e0c..0ba003f 100644
--- a/src/main/java/org/apache/maven/plugins/issues/Issue.java
+++ b/src/main/java/org/apache/maven/plugins/issues/Issue.java
@@ -32,8 +32,6 @@ import java.util.List;
public class Issue {
private String assignee;
- private List<String> comments;
-
private List<String> components;
private Date created;
@@ -74,17 +72,6 @@ public class Issue {
this.assignee = assignee;
}
- public List<String> getComments() {
- return comments;
- }
-
- public void addComment(String comment) {
- if (comments == null) {
- comments = new ArrayList<>();
- }
- comments.add(comment);
- }
-
public List<String> getComponents() {
return components;
}
diff --git a/src/main/java/org/apache/maven/plugins/jira/AbstractJiraDownloader.java b/src/main/java/org/apache/maven/plugins/jira/AbstractJiraDownloader.java
deleted file mode 100644
index e417542..0000000
--- a/src/main/java/org/apache/maven/plugins/jira/AbstractJiraDownloader.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.maven.plugins.jira;
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.plugins.issues.Issue;
-import org.apache.maven.plugins.issues.IssueUtils;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.settings.Proxy;
-import org.apache.maven.settings.Settings;
-
-/**
- * Abstract API, more or less, to retrieve issue information from JIRA. Has a subclass that uses
- * the JIRA REST API.
- *
- * @author mfranken@xebia.com
- * @author jruiz@exist.com
- * @version $Id$
- */
-public abstract class AbstractJiraDownloader {
- protected static final String UTF_8 = "UTF-8";
-
- /** Log for debug output. */
- protected Log log;
-
- /** Output file for xml document. */
- protected File output;
-
- /** The maximum number of entries to show. */
- protected int nbEntriesMax;
-
- /** The filter to apply to query to JIRA. */
- protected String filter;
-
- /** Ids of fix versions to show, as comma separated string. */
- protected String fixVersionIds;
-
- /** Ids of status to show, as comma separated string. */
- protected String statusIds;
-
- /** Ids of resolution to show, as comma separated string. */
- protected String resolutionIds;
-
- /** Ids of priority to show, as comma separated string. */
- protected String priorityIds;
-
- /** The component to show. */
- protected String component;
-
- /** Ids of types to show, as comma separated string. */
- protected String typeIds;
-
- /** Column names to sort by, as comma separated string. */
- protected String sortColumnNames;
-
- /** The username to log into JIRA. */
- protected String jiraUser;
-
- /** The password to log into JIRA. */
- protected String jiraPassword;
-
- /** The username to log into webserver. */
- protected String webUser;
-
- /** The password to log into webserver. */
- protected String webPassword;
-
- /** The maven project. */
- protected MavenProject project;
-
- /** The maven settings. */
- protected Settings settings;
-
- /** Filter the JIRA query based on the current version */
- protected boolean onlyCurrentVersion;
-
- /** The versionPrefix to apply to the POM version */
- protected String versionPrefix;
-
- /** The pattern used to parse dates from the JIRA xml file. */
- protected String jiraDatePattern;
-
- protected String proxyHost;
-
- protected int proxyPort;
-
- protected String proxyUser;
-
- protected String proxyPass;
-
- protected int connectionTimeout;
-
- protected int receiveTimout;
-
- /**
- * Execute the query on the JIRA server.
- *
- * @throws Exception on error
- */
- public abstract void doExecute() throws Exception;
-
- /**
- * Check to see if we think that JIRA authentication is needed.
- *
- * @return <code>true</code> if jiraUser and jiraPassword are set, otherwise <code>false</code>
- */
- protected boolean isJiraAuthenticationConfigured() {
- return (jiraUser != null) && (jiraUser.length() > 0) && (jiraPassword != null);
- }
-
- protected void getProxyInfo(String jiraUrl) {
- // see whether there is any proxy defined in maven
- Proxy proxy = null;
-
- if (project == null) {
- getLog().error("No project set. No proxy info available.");
-
- return;
- }
-
- if (settings != null) {
- proxy = settings.getActiveProxy();
- }
-
- if (proxy != null) {
- /// TODO check proxy.getNonProxyHosts()
- proxyHost = settings.getActiveProxy().getHost();
- proxyPort = settings.getActiveProxy().getPort();
- proxyUser = settings.getActiveProxy().getUsername();
- proxyPass = settings.getActiveProxy().getPassword();
- }
- }
-
- /**
- * Override this method if you need to get issues for a specific Fix For.
- *
- * @return a Fix For id or <code>null</code> if you don't have that need
- */
- protected String getFixFor() {
- if (onlyCurrentVersion) {
- // Let JIRA do the filtering of the current version instead of the JIRA mojo.
- // This way JIRA returns less issues and we do not run into the "nbEntriesMax" limit that easily.
-
- String version = (versionPrefix == null ? "" : versionPrefix) + project.getVersion();
-
- // Remove "-SNAPSHOT" from the end of the version, if it's there
- if (version.endsWith(IssueUtils.SNAPSHOT_SUFFIX)) {
- return version.substring(0, version.length() - IssueUtils.SNAPSHOT_SUFFIX.length());
- } else {
- return version;
- }
- } else {
- return null;
- }
- }
-
- public abstract List<Issue> getIssueList() throws MojoExecutionException;
-
- public void setJiraDatePattern(String jiraDatePattern) {
- this.jiraDatePattern = jiraDatePattern;
- }
-
- /**
- * Set the output file for the log.
- *
- * @param thisOutput the output file
- */
- public void setOutput(File thisOutput) {
- this.output = thisOutput;
- }
-
- public File getOutput() {
- return this.output;
- }
-
- /**
- * Sets the project.
- *
- * @param thisProject The project to set
- */
- public void setMavenProject(Object thisProject) {
- this.project = (MavenProject) thisProject;
- }
-
- /**
- * Sets the maximum number of Issues to show.
- *
- * @param nbEntries The maximum number of Issues
- */
- public void setNbEntries(final int nbEntries) {
- nbEntriesMax = nbEntries;
- }
-
- /**
- * Sets the statusIds.
- *
- * @param thisStatusIds The id(s) of the status to show, as comma separated string
- */
- public void setStatusIds(String thisStatusIds) {
- statusIds = thisStatusIds;
- }
-
- /**
- * Sets the priorityIds.
- *
- * @param thisPriorityIds The id(s) of the priority to show, as comma separated string
- */
- public void setPriorityIds(String thisPriorityIds) {
- priorityIds = thisPriorityIds;
- }
-
- /**
- * Sets the resolutionIds.
- *
- * @param thisResolutionIds The id(s) of the resolution to show, as comma separated string
- */
- public void setResolutionIds(String thisResolutionIds) {
- resolutionIds = thisResolutionIds;
- }
-
- /**
- * Sets the sort column names.
- *
- * @param thisSortColumnNames The column names to sort by
- */
- public void setSortColumnNames(String thisSortColumnNames) {
- sortColumnNames = thisSortColumnNames;
- }
-
- /**
- * Sets the password for authentication against the webserver.
- *
- * @param thisWebPassword The password of the webserver
- */
- public void setWebPassword(String thisWebPassword) {
- this.webPassword = thisWebPassword;
- }
-
- /**
- * Sets the username for authentication against the webserver.
- *
- * @param thisWebUser The username of the webserver
- */
- public void setWebUser(String thisWebUser) {
- this.webUser = thisWebUser;
- }
-
- /**
- * Sets the password to log into a secured JIRA.
- *
- * @param thisJiraPassword The password for JIRA
- */
- public void setJiraPassword(final String thisJiraPassword) {
- this.jiraPassword = thisJiraPassword;
- }
-
- /**
- * Sets the username to log into a secured JIRA.
- *
- * @param thisJiraUser The username for JIRA
- */
- public void setJiraUser(String thisJiraUser) {
- this.jiraUser = thisJiraUser;
- }
-
- /**
- * Sets the filter to apply to query to JIRA.
- *
- * @param thisFilter The filter to query JIRA
- */
- public void setFilter(String thisFilter) {
- this.filter = thisFilter;
- }
-
- /**
- * Sets the component(s) to apply to query JIRA.
- *
- * @param theseComponents The id(s) of components to show, as comma separated string
- */
- public void setComponent(String theseComponents) {
- this.component = theseComponents;
- }
-
- /**
- * Sets the fix version id(s) to apply to query JIRA.
- *
- * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
- */
- public void setFixVersionIds(String theseFixVersionIds) {
- this.fixVersionIds = theseFixVersionIds;
- }
-
- /**
- * Sets the typeIds.
- *
- * @param theseTypeIds The id(s) of the types to show, as comma separated string
- */
- public void setTypeIds(String theseTypeIds) {
- typeIds = theseTypeIds;
- }
-
- public void setLog(Log log) {
- this.log = log;
- }
-
- protected Log getLog() {
- return log;
- }
-
- public void setSettings(Settings settings) {
- this.settings = settings;
- }
-
- public boolean isOnlyCurrentVersion() {
- return onlyCurrentVersion;
- }
-
- public void setOnlyCurrentVersion(boolean onlyCurrentVersion) {
- this.onlyCurrentVersion = onlyCurrentVersion;
- }
-
- public String getVersionPrefix() {
- return versionPrefix;
- }
-
- public void setVersionPrefix(String versionPrefix) {
- this.versionPrefix = versionPrefix;
- }
-
- public void setConnectionTimeout(int connectionTimeout) {
- this.connectionTimeout = connectionTimeout;
- }
-
- public void setReceiveTimout(int receiveTimout) {
- this.receiveTimout = receiveTimout;
- }
-}
diff --git a/src/main/java/org/apache/maven/plugins/jira/JiraReport.java b/src/main/java/org/apache/maven/plugins/jira/JiraReport.java
index 4b13c97..f67bdd6 100644
--- a/src/main/java/org/apache/maven/plugins/jira/JiraReport.java
+++ b/src/main/java/org/apache/maven/plugins/jira/JiraReport.java
@@ -18,7 +18,8 @@
*/
package org.apache.maven.plugins.jira;
-import java.io.File;
+import javax.inject.Inject;
+
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -35,8 +36,8 @@ import org.apache.maven.plugins.issues.IssueUtils;
import org.apache.maven.plugins.issues.IssuesReportGenerator;
import org.apache.maven.plugins.issues.IssuesReportHelper;
import org.apache.maven.reporting.MavenReportException;
-import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
/**
* Goal which downloads issues from the Issue Tracking System and generates a report.
@@ -144,12 +145,6 @@ public class JiraReport extends AbstractChangesReport {
@Parameter(property = "changes.jiraServerId")
private String jiraServerId;
- /**
- * Path to the JIRA XML file, which will be parsed.
- */
- @Parameter(defaultValue = "${project.build.directory}/jira-results.xml", required = true, readonly = true)
- private File jiraXmlPath;
-
/**
* Maximum number of entries to be fetched from JIRA.
*/
@@ -264,20 +259,36 @@ public class JiraReport extends AbstractChangesReport {
/**
* Defines the http password for basic authentication into the JIRA webserver.
+ *
+ * @deprecated use {@link #jiraPassword} or {@link #jiraServerId}
*/
+ @Deprecated
@Parameter
private String webPassword;
/**
* Defines the http user for basic authentication into the JIRA webserver.
+ *
+ * @deprecated use {@link #jiraUser} or {@link #jiraServerId}
*/
+ @Deprecated
@Parameter
private String webUser;
/*
* Used for tests.
*/
- private AbstractJiraDownloader mockDownloader;
+ private RestJiraDownloader mockDownloader;
+
+ /**
+ * Component used to decrypt server information.
+ */
+ private final SettingsDecrypter settingsDecrypter;
+
+ @Inject
+ public JiraReport(SettingsDecrypter settingsDecrypter) {
+ this.settingsDecrypter = settingsDecrypter;
+ }
/* --------------------------------------------------------------------- */
/* Public methods */
@@ -318,7 +329,7 @@ public class JiraReport extends AbstractChangesReport {
try {
// Download issues
- AbstractJiraDownloader issueDownloader;
+ RestJiraDownloader issueDownloader;
if (mockDownloader != null) {
issueDownloader = mockDownloader;
} else {
@@ -379,13 +390,11 @@ public class JiraReport extends AbstractChangesReport {
return ResourceBundle.getBundle("jira-report", locale, this.getClass().getClassLoader());
}
- private void configureIssueDownloader(AbstractJiraDownloader issueDownloader) {
+ private void configureIssueDownloader(RestJiraDownloader issueDownloader) {
issueDownloader.setLog(getLog());
issueDownloader.setMavenProject(project);
- issueDownloader.setOutput(jiraXmlPath);
-
issueDownloader.setNbEntries(maxEntries);
issueDownloader.setComponent(component);
@@ -404,33 +413,27 @@ public class JiraReport extends AbstractChangesReport {
issueDownloader.setJiraDatePattern(jiraDatePattern);
- if (jiraServerId != null) {
- final Server server = mavenSession.getSettings().getServer(jiraServerId);
- issueDownloader.setJiraUser(server.getUsername());
- issueDownloader.setJiraPassword(server.getPassword());
- } else {
+ issueDownloader.setJiraServerId(jiraServerId);
+
+ if (jiraUser != null) {
issueDownloader.setJiraUser(jiraUser);
issueDownloader.setJiraPassword(jiraPassword);
+ } else if (webUser != null) {
+ issueDownloader.setJiraUser(webUser);
+ issueDownloader.setJiraPassword(webPassword);
}
issueDownloader.setTypeIds(typeIds);
- issueDownloader.setWebUser(webUser);
-
- issueDownloader.setWebPassword(webPassword);
-
issueDownloader.setSettings(settings);
+ issueDownloader.setSettingsDecrypter(settingsDecrypter);
issueDownloader.setOnlyCurrentVersion(onlyCurrentVersion);
issueDownloader.setVersionPrefix(versionPrefix);
}
- public void setMockDownloader(AbstractJiraDownloader mockDownloader) {
+ public void setMockDownloader(RestJiraDownloader mockDownloader) {
this.mockDownloader = mockDownloader;
}
-
- public AbstractJiraDownloader getMockDownloader() {
- return mockDownloader;
- }
}
diff --git a/src/main/java/org/apache/maven/plugins/jira/JiraXML.java b/src/main/java/org/apache/maven/plugins/jira/JiraXML.java
deleted file mode 100644
index 2967c19..0000000
--- a/src/main/java/org/apache/maven/plugins/jira/JiraXML.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.maven.plugins.jira;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.logging.Log;
-import org.apache.maven.plugins.issues.Issue;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * XML parser that extracts <code>Issue</code>s from JIRA. This works on an XML file downloaded from JIRA and creates a
- * <code>List</code> of issues that is exposed to the user of the class.
- *
- * @version $Id$
- */
-public class JiraXML extends DefaultHandler {
- private final List<Issue> issueList;
-
- private final StringBuilder currentElement = new StringBuilder(1024);
-
- private String currentParent = "";
-
- private final String datePattern;
-
- private Issue issue;
-
- private String jiraVersion = null;
-
- private final Log log;
-
- private SimpleDateFormat sdf;
-
- /**
- * @param log not null
- * @param datePattern may be null
- * @since 2.4
- */
- public JiraXML(Log log, String datePattern) {
- this.log = log;
- this.datePattern = datePattern;
-
- if (datePattern == null) {
- sdf = null;
- } else {
- // @todo Do we need to be able to configure the locale of the JIRA server as well?
- sdf = new SimpleDateFormat(datePattern, Locale.ENGLISH);
- }
-
- this.issueList = new ArrayList<>(16);
- }
-
- /**
- * Parse the given XML file. The list of issues can then be retrieved with {@link #getIssueList()}.
- *
- * @param xmlPath the file to parse
- * @throws MojoExecutionException in case of errors
- * @since 2.4
- */
- public void parseXML(File xmlPath) throws MojoExecutionException {
- try (InputStream xmlStream = new FileInputStream(xmlPath)) {
- InputSource inputSource = new InputSource(xmlStream);
- parse(inputSource);
- } catch (FileNotFoundException e) {
- throw new MojoExecutionException("Failed to open JIRA XML file " + xmlPath, e);
- } catch (IOException e) {
- throw new MojoExecutionException("Failed to read JIRA XML file " + xmlPath, e);
- }
- }
-
- void parse(InputSource xmlSource) throws MojoExecutionException {
- try {
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser saxParser = factory.newSAXParser();
-
- saxParser.parse(xmlSource, this);
- } catch (Throwable t) {
- throw new MojoExecutionException("Failed to parse JIRA XML.", t);
- }
- }
-
- public void startElement(String namespaceURI, String sName, String qName, Attributes attrs) {
- switch (qName) {
- case "item":
- issue = new Issue();
-
- currentParent = "item";
- break;
- case "key":
- String id = attrs.getValue("id");
- if (id != null) {
- issue.setId(id.trim());
- }
- break;
- case "build-info":
- currentParent = "build-info";
- break;
- default:
- // none
- }
- }
-
- public void endElement(String namespaceURI, String sName, String qName) {
- if (qName.equals("item")) {
- issueList.add(issue);
-
- currentParent = "";
- } else if (qName.equals("key")) {
- issue.setKey(currentElement.toString().trim());
- } else if (qName.equals("summary")) {
- issue.setSummary(currentElement.toString().trim());
- } else if (qName.equals("type")) {
- issue.setType(currentElement.toString().trim());
- } else if (qName.equals("link") && currentParent.equals("item")) {
- issue.setLink(currentElement.toString().trim());
- } else if (qName.equals("priority")) {
- issue.setPriority(currentElement.toString().trim());
- } else if (qName.equals("status")) {
- issue.setStatus(currentElement.toString().trim());
- } else if (qName.equals("resolution")) {
- issue.setResolution(currentElement.toString().trim());
- } else if (qName.equals("assignee")) {
- issue.setAssignee(currentElement.toString().trim());
- } else if (qName.equals("reporter")) {
- issue.setReporter(currentElement.toString().trim());
- } else if (qName.equals("version") && currentParent.equals("item")) {
- issue.setVersion(currentElement.toString().trim());
- } else if (qName.equals("version") && currentParent.equals("build-info")) {
- jiraVersion = currentElement.toString().trim();
- } else if (qName.equals("fixVersion")) {
- issue.addFixVersion(currentElement.toString().trim());
- } else if (qName.equals("component")) {
- issue.addComponent(currentElement.toString().trim());
- } else if (qName.equals("comment")) {
- issue.addComment(currentElement.toString().trim());
- } else if (qName.equals("title") && currentParent.equals("item")) {
- issue.setTitle(currentElement.toString().trim());
- } else if (qName.equals("created") && currentParent.equals("item") && sdf != null) {
- try {
- issue.setCreated(sdf.parse(currentElement.toString().trim()));
- } catch (ParseException e) {
- log.warn("Element \"Created\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"");
- }
- } else if (qName.equals("updated") && currentParent.equals("item") && sdf != null) {
- try {
- issue.setUpdated(sdf.parse(currentElement.toString().trim()));
- } catch (ParseException e) {
- log.warn("Element \"Updated\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"");
- }
- }
-
- currentElement.setLength(0);
- }
-
- public void characters(char[] buf, int offset, int len) {
- currentElement.append(buf, offset, len);
- }
-
- public List<Issue> getIssueList() {
- return Collections.unmodifiableList(this.issueList);
- }
-
- public String getJiraVersion() {
- return jiraVersion;
- }
-}
diff --git a/src/main/java/org/apache/maven/plugins/jira/RestJiraDownloader.java b/src/main/java/org/apache/maven/plugins/jira/RestJiraDownloader.java
index f6a427e..abcda41 100644
--- a/src/main/java/org/apache/maven/plugins/jira/RestJiraDownloader.java
+++ b/src/main/java/org/apache/maven/plugins/jira/RestJiraDownloader.java
@@ -18,16 +18,15 @@
*/
package org.apache.maven.plugins.jira;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
+import java.net.URI;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -37,25 +36,104 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingJsonFactory;
-import org.apache.cxf.configuration.security.AuthorizationPolicy;
-import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
-import org.apache.cxf.interceptor.LoggingInInterceptor;
-import org.apache.cxf.interceptor.LoggingOutInterceptor;
-import org.apache.cxf.jaxrs.client.ClientConfiguration;
-import org.apache.cxf.jaxrs.client.WebClient;
-import org.apache.cxf.message.Message;
-import org.apache.cxf.transport.http.HTTPConduit;
-import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
-import org.apache.cxf.transports.http.configuration.ProxyServerType;
+import org.apache.http.HttpHeaders;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicHeader;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.issues.Issue;
+import org.apache.maven.plugins.issues.IssueUtils;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
+import org.apache.maven.settings.crypto.SettingsDecryptionResult;
/**
* Use the JIRA REST API to download issues. This class assumes that the URL points to a copy of JIRA that
* implements the REST API.
*/
-public class RestJiraDownloader extends AbstractJiraDownloader {
+public class RestJiraDownloader {
+
+ /** Log for debug output. */
+ private Log log;
+
+ /** The maven project. */
+ private MavenProject project;
+
+ /** The maven settings. */
+ private Settings settings;
+
+ private SettingsDecrypter settingsDecrypter;
+
+ /** Filter the JIRA query based on the current version */
+ private boolean onlyCurrentVersion;
+
+ /** The versionPrefix to apply to the POM version */
+ protected String versionPrefix;
+
+ /** The maximum number of entries to show. */
+ protected int nbEntriesMax;
+
+ /** The filter to apply to query to JIRA. */
+ protected String filter;
+
+ /** Ids of fix versions to show, as comma separated string. */
+ protected String fixVersionIds;
+
+ /** Ids of status to show, as comma separated string. */
+ protected String statusIds;
+
+ /** Ids of resolution to show, as comma separated string. */
+ protected String resolutionIds;
+
+ /** Ids of priority to show, as comma separated string. */
+ protected String priorityIds;
+
+ /** The component to show. */
+ protected String component;
+
+ /** Ids of types to show, as comma separated string. */
+ protected String typeIds;
+
+ /** Column names to sort by, as comma separated string. */
+ protected String sortColumnNames;
+
+ /** The username to log into JIRA. */
+ protected String jiraUser;
+
+ /** The password to log into JIRA. */
+ protected String jiraPassword;
+
+ private String jiraServerId;
+
+ /** The pattern used to parse dates from the JIRA xml file. */
+ protected String jiraDatePattern;
+
+ protected int connectionTimeout;
+
+ protected int receiveTimout;
+
private List<Issue> issueList;
private JsonFactory jsonFactory;
@@ -74,6 +152,177 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
private List<String> resolvedPriorityIds;
+ /**
+ * Override this method if you need to get issues for a specific Fix For.
+ *
+ * @return a Fix For id or <code>null</code> if you don't have that need
+ */
+ protected String getFixFor() {
+ if (onlyCurrentVersion) {
+ // Let JIRA do the filtering of the current version instead of the JIRA mojo.
+ // This way JIRA returns less issues and we do not run into the "nbEntriesMax" limit that easily.
+
+ String version = (versionPrefix == null ? "" : versionPrefix) + project.getVersion();
+
+ // Remove "-SNAPSHOT" from the end of the version, if it's there
+ if (version.endsWith(IssueUtils.SNAPSHOT_SUFFIX)) {
+ return version.substring(0, version.length() - IssueUtils.SNAPSHOT_SUFFIX.length());
+ } else {
+ return version;
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Sets the project.
+ *
+ * @param thisProject The project to set
+ */
+ public void setMavenProject(MavenProject thisProject) {
+ this.project = thisProject;
+ }
+
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
+ protected Log getLog() {
+ return log;
+ }
+
+ public void setSettings(Settings settings) {
+ this.settings = settings;
+ }
+
+ public void setSettingsDecrypter(SettingsDecrypter settingsDecrypter) {
+ this.settingsDecrypter = settingsDecrypter;
+ }
+
+ public void setOnlyCurrentVersion(boolean onlyCurrentVersion) {
+ this.onlyCurrentVersion = onlyCurrentVersion;
+ }
+
+ public void setVersionPrefix(String versionPrefix) {
+ this.versionPrefix = versionPrefix;
+ }
+
+ public void setJiraDatePattern(String jiraDatePattern) {
+ this.jiraDatePattern = jiraDatePattern;
+ }
+
+ /**
+ * Sets the maximum number of Issues to show.
+ *
+ * @param nbEntries The maximum number of Issues
+ */
+ public void setNbEntries(final int nbEntries) {
+ nbEntriesMax = nbEntries;
+ }
+
+ /**
+ * Sets the statusIds.
+ *
+ * @param thisStatusIds The id(s) of the status to show, as comma separated string
+ */
+ public void setStatusIds(String thisStatusIds) {
+ statusIds = thisStatusIds;
+ }
+
+ /**
+ * Sets the priorityIds.
+ *
+ * @param thisPriorityIds The id(s) of the priority to show, as comma separated string
+ */
+ public void setPriorityIds(String thisPriorityIds) {
+ priorityIds = thisPriorityIds;
+ }
+
+ /**
+ * Sets the resolutionIds.
+ *
+ * @param thisResolutionIds The id(s) of the resolution to show, as comma separated string
+ */
+ public void setResolutionIds(String thisResolutionIds) {
+ resolutionIds = thisResolutionIds;
+ }
+
+ /**
+ * Sets the sort column names.
+ *
+ * @param thisSortColumnNames The column names to sort by
+ */
+ public void setSortColumnNames(String thisSortColumnNames) {
+ sortColumnNames = thisSortColumnNames;
+ }
+
+ /**
+ * Sets the password to log into a secured JIRA.
+ *
+ * @param thisJiraPassword The password for JIRA
+ */
+ public void setJiraPassword(final String thisJiraPassword) {
+ this.jiraPassword = thisJiraPassword;
+ }
+
+ /**
+ * Sets the username to log into a secured JIRA.
+ *
+ * @param thisJiraUser The username for JIRA
+ */
+ public void setJiraUser(String thisJiraUser) {
+ this.jiraUser = thisJiraUser;
+ }
+
+ public void setJiraServerId(String jiraServerId) {
+ this.jiraServerId = jiraServerId;
+ }
+
+ /**
+ * Sets the filter to apply to query to JIRA.
+ *
+ * @param thisFilter The filter to query JIRA
+ */
+ public void setFilter(String thisFilter) {
+ this.filter = thisFilter;
+ }
+
+ /**
+ * Sets the component(s) to apply to query JIRA.
+ *
+ * @param theseComponents The id(s) of components to show, as comma separated string
+ */
+ public void setComponent(String theseComponents) {
+ this.component = theseComponents;
+ }
+
+ /**
+ * Sets the fix version id(s) to apply to query JIRA.
+ *
+ * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
+ */
+ public void setFixVersionIds(String theseFixVersionIds) {
+ this.fixVersionIds = theseFixVersionIds;
+ }
+
+ /**
+ * Sets the typeIds.
+ *
+ * @param theseTypeIds The id(s) of the types to show, as comma separated string
+ */
+ public void setTypeIds(String theseTypeIds) {
+ typeIds = theseTypeIds;
+ }
+
+ public void setConnectionTimeout(int connectionTimeout) {
+ this.connectionTimeout = connectionTimeout;
+ }
+
+ public void setReceiveTimout(int receiveTimout) {
+ this.receiveTimout = receiveTimout;
+ }
+
public static class NoRest extends Exception {
private static final long serialVersionUID = 6970088805270319624L;
@@ -105,24 +354,16 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
String jiraUrl = urlMap.get("url");
String jiraProject = urlMap.get("project");
- WebClient client = setupWebClient(jiraUrl);
-
- // We use version 2 of the REST API, that first appeared in JIRA 5
- // Check if version 2 of the REST API is supported
- // http://docs.atlassian.com/jira/REST/5.0/
- // Note that serverInfo can always be accessed without authentication
- client.replacePath("/rest/api/2/serverInfo");
- client.accept(MediaType.APPLICATION_JSON);
- Response siResponse = client.get();
- if (siResponse.getStatus() != Response.Status.OK.getStatusCode()) {
- throw new NoRest("This JIRA server does not support version 2 of the REST API, "
- + "which maven-changes-plugin requires.");
+ try (CloseableHttpClient client = setupHttpClient(jiraUrl)) {
+ checkRestApi(client, jiraUrl);
+ doSessionAuth(client, jiraUrl);
+ resolveIds(client, jiraUrl, jiraProject);
+ search(client, jiraProject, jiraUrl);
}
+ }
- doSessionAuth(client);
-
- resolveIds(client, jiraProject);
-
+ private void search(CloseableHttpClient client, String jiraProject, String jiraUrl)
+ throws IOException, MojoExecutionException {
String jqlQuery = new JqlQueryBuilder(log)
.urlEncode(false)
.project(jiraProject)
@@ -137,6 +378,8 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
.filter(filter)
.build();
+ log.debug("JIRA jql=" + jqlQuery);
+
StringWriter searchParamStringWriter = new StringWriter();
try (JsonGenerator gen = jsonFactory.createGenerator(searchParamStringWriter)) {
gen.writeStartObject();
@@ -148,32 +391,53 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
gen.writeEndArray();
gen.writeEndObject();
}
- client.replacePath("/rest/api/2/search");
- client.type(MediaType.APPLICATION_JSON_TYPE);
- client.accept(MediaType.APPLICATION_JSON_TYPE);
- Response searchResponse = client.post(searchParamStringWriter.toString());
- if (searchResponse.getStatus() != Response.Status.OK.getStatusCode()) {
- reportErrors(searchResponse);
+
+ HttpPost httpPost = new HttpPost(jiraUrl + "/rest/api/2/search");
+ httpPost.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
+ httpPost.setEntity(new StringEntity(searchParamStringWriter.toString()));
+
+ try (CloseableHttpResponse response = client.execute(httpPost)) {
+
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ reportErrors(response);
+ }
+
+ JsonNode issueTree = getResponseTree(response);
+
+ assertIsObject(issueTree);
+ JsonNode issuesNode = issueTree.get("issues");
+ assertIsArray(issuesNode);
+ buildIssues(issuesNode, jiraUrl);
}
+ }
- JsonNode issueTree = getResponseTree(searchResponse);
- assert issueTree.isObject();
- JsonNode issuesNode = issueTree.get("issues");
- assert issuesNode.isArray();
- buildIssues(issuesNode, jiraUrl, jiraProject);
+ private void checkRestApi(CloseableHttpClient client, String jiraUrl) throws IOException, NoRest {
+ // We use version 2 of the REST API, that first appeared in JIRA 5
+ // Check if version 2 of the REST API is supported
+ // http://docs.atlassian.com/jira/REST/5.0/
+ // Note that serverInfo can always be accessed without authentication
+
+ HttpGet httpGet = new HttpGet(jiraUrl + "/rest/api/2/serverInfo");
+ try (CloseableHttpResponse response = client.execute(httpGet)) {
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ throw new NoRest("This JIRA server does not support version 2 of the REST API, "
+ + "which maven-changes-plugin requires.");
+ }
+ }
}
- private JsonNode getResponseTree(Response response) throws IOException {
- JsonParser jsonParser = jsonFactory.createParser((InputStream) response.getEntity());
- return (JsonNode) jsonParser.readValueAsTree();
+ private JsonNode getResponseTree(HttpResponse response) throws IOException {
+ try (InputStream inputStream = response.getEntity().getContent();
+ JsonParser jsonParser = jsonFactory.createParser(inputStream)) {
+ return jsonParser.readValueAsTree();
+ }
}
- private void reportErrors(Response resp) throws IOException, MojoExecutionException {
- if (MediaType.APPLICATION_JSON_TYPE
- .getType()
- .equals(getResponseMediaType(resp).getType())) {
+ private void reportErrors(HttpResponse resp) throws IOException, MojoExecutionException {
+ ContentType contentType = ContentType.get(resp.getEntity());
+ if (contentType != null && contentType.getMimeType().equals(ContentType.APPLICATION_JSON.getMimeType())) {
JsonNode errorTree = getResponseTree(resp);
- assert errorTree.isObject();
+ assertIsObject(errorTree);
JsonNode messages = errorTree.get("errorMessages");
if (messages != null) {
for (int mx = 0; mx < messages.size(); mx++) {
@@ -186,59 +450,50 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
}
}
}
- throw new MojoExecutionException(String.format("Failed to query issues; response %d", resp.getStatus()));
+ throw new MojoExecutionException(String.format(
+ "Failed to query issues; response %d", resp.getStatusLine().getStatusCode()));
}
- private void resolveIds(WebClient client, String jiraProject)
+ private void resolveIds(CloseableHttpClient client, String jiraUrl, String jiraProject)
throws IOException, MojoExecutionException, MojoFailureException {
resolveList(
resolvedComponentIds,
client,
"components",
component,
- "/rest/api/2/project/{key}/components",
- jiraProject);
+ jiraUrl + "/rest/api/2/project/" + jiraProject + "/components");
resolveList(
resolvedFixVersionIds,
client,
"fixVersions",
fixVersionIds,
- "/rest/api/2/project/{key}/versions",
- jiraProject);
- resolveList(resolvedStatusIds, client, "status", statusIds, "/rest/api/2/status");
- resolveList(resolvedResolutionIds, client, "resolution", resolutionIds, "/rest/api/2/resolution");
- resolveList(resolvedTypeIds, client, "type", typeIds, "/rest/api/2/issuetype");
- resolveList(resolvedPriorityIds, client, "priority", priorityIds, "/rest/api/2/priority");
+ jiraUrl + "/rest/api/2/project/" + jiraProject + "/versions");
+ resolveList(resolvedStatusIds, client, "status", statusIds, jiraUrl + "/rest/api/2/status");
+ resolveList(resolvedResolutionIds, client, "resolution", resolutionIds, jiraUrl + "/rest/api/2/resolution");
+ resolveList(resolvedTypeIds, client, "type", typeIds, jiraUrl + "/rest/api/2/issuetype");
+ resolveList(resolvedPriorityIds, client, "priority", priorityIds, jiraUrl + "/rest/api/2/priority");
}
private void resolveList(
- List<String> targetList,
- WebClient client,
- String what,
- String input,
- String listRestUrlPattern,
- String... listUrlArgs)
+ List<String> targetList, CloseableHttpClient client, String what, String input, String listRestUrlPattern)
throws IOException, MojoExecutionException, MojoFailureException {
- if (input == null || input.length() == 0) {
+ if (input == null || input.isEmpty()) {
return;
}
- if (listUrlArgs != null && listUrlArgs.length != 0) {
- client.replacePath("/");
- client.path(listRestUrlPattern, listUrlArgs);
- } else {
- client.replacePath(listRestUrlPattern);
- }
- client.accept(MediaType.APPLICATION_JSON);
- Response resp = client.get();
- if (resp.getStatus() != Response.Status.OK.getStatusCode()) {
- getLog().error(String.format("Could not get %s list from %s", what, listRestUrlPattern));
- reportErrors(resp);
- }
- JsonNode items = getResponseTree(resp);
- String[] pieces = input.split(",");
- for (String item : pieces) {
- targetList.add(resolveOneItem(items, what, item.trim()));
+ HttpGet httpGet = new HttpGet(listRestUrlPattern);
+
+ try (CloseableHttpResponse response = client.execute(httpGet)) {
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ getLog().error(String.format("Could not get %s list from %s", what, listRestUrlPattern));
+ reportErrors(response);
+ }
+
+ JsonNode items = getResponseTree(response);
+ String[] pieces = input.split(",");
+ for (String item : pieces) {
+ targetList.add(resolveOneItem(items, what, item.trim()));
+ }
}
}
@@ -254,16 +509,11 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
throw new MojoFailureException(String.format("Could not find %s %s.", what, nameOrId));
}
- private MediaType getResponseMediaType(Response response) {
- String header = (String) response.getMetadata().getFirst(HttpHeaders.CONTENT_TYPE);
- return header == null ? null : MediaType.valueOf(header);
- }
-
- private void buildIssues(JsonNode issuesNode, String jiraUrl, String jiraProject) {
+ private void buildIssues(JsonNode issuesNode, String jiraUrl) {
issueList = new ArrayList<>();
for (int ix = 0; ix < issuesNode.size(); ix++) {
JsonNode issueNode = issuesNode.get(ix);
- assert issueNode.isObject();
+ assertIsObject(issueNode);
Issue issue = new Issue();
JsonNode val;
@@ -287,9 +537,6 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
val = fieldsNode.get("created");
processCreated(issue, val);
- val = fieldsNode.get("comment");
- processComments(issue, val);
-
val = fieldsNode.get("components");
processComponents(issue, val);
@@ -419,7 +666,7 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
private void processFixVersions(Issue issue, JsonNode val) {
if (val != null) {
- assert val.isArray();
+ assertIsArray(val);
for (int vx = 0; vx < val.size(); vx++) {
JsonNode fvNode = val.get(vx);
issue.addFixVersion(fvNode.get("name").asText());
@@ -427,19 +674,9 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
}
}
- private void processComments(Issue issue, JsonNode val) {
- if (val != null) {
- JsonNode commentsArray = val.get("comments");
- for (int cx = 0; cx < commentsArray.size(); cx++) {
- JsonNode cnode = commentsArray.get(cx);
- issue.addComment(cnode.get("body").asText());
- }
- }
- }
-
private void processComponents(Issue issue, JsonNode val) {
if (val != null) {
- assert val.isArray();
+ assertIsArray(val);
for (int cx = 0; cx < val.size(); cx++) {
JsonNode cnode = val.get(cx);
issue.addComponent(cnode.get("name").asText());
@@ -453,11 +690,35 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
}
}
- private void doSessionAuth(WebClient client) throws IOException, MojoExecutionException, NoRest {
- /* if JiraUser is specified instead of WebUser, we need to make a session. */
+ private void assertIsObject(JsonNode node) {
+ if (!node.isObject()) {
+ throw new IllegalArgumentException("json node: " + node + " is not an object");
+ }
+ }
+
+ private void assertIsArray(JsonNode node) {
+ if (!node.isArray()) {
+ throw new IllegalArgumentException("json node: " + node + " is not an array");
+ }
+ }
+
+ private void doSessionAuth(CloseableHttpClient client, String jiraUrl)
+ throws IOException, MojoExecutionException, NoRest {
+
+ Server server = settings.getServer(jiraServerId);
+ if (server != null) {
+ SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
+ if (!result.getProblems().isEmpty()) {
+ for (SettingsProblem problem : result.getProblems()) {
+ log.error(problem.getMessage());
+ }
+ } else {
+ jiraUser = result.getServer().getUsername();
+ jiraPassword = result.getServer().getPassword();
+ }
+ }
+
if (jiraUser != null) {
- client.replacePath("/rest/auth/1/session");
- client.type(MediaType.APPLICATION_JSON_TYPE);
StringWriter jsWriter = new StringWriter();
try (JsonGenerator gen = jsonFactory.createGenerator(jsWriter)) {
gen.writeStartObject();
@@ -465,68 +726,72 @@ public class RestJiraDownloader extends AbstractJiraDownloader {
gen.writeStringField("password", jiraPassword);
gen.writeEndObject();
}
- Response authRes = client.post(jsWriter.toString());
- if (authRes.getStatus() != Response.Status.OK.getStatusCode()) {
- if (authRes.getStatus() != Response.Status.UNAUTHORIZED.getStatusCode()
- && authRes.getStatus() != Response.Status.FORBIDDEN.getStatusCode()) {
- // if not one of the documented failures, assume that there's no rest in there in the first place.
- throw new NoRest();
+
+ HttpPost post = new HttpPost(jiraUrl + "/rest/auth/1/session");
+ post.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
+ post.setEntity(new StringEntity(jsWriter.toString()));
+
+ try (CloseableHttpResponse response = client.execute(post)) {
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != HttpStatus.SC_OK) {
+ if (statusCode != HttpStatus.SC_UNAUTHORIZED && statusCode != HttpStatus.SC_FORBIDDEN) {
+ // if not one of the documented failures, assume that there's no rest in there in the first
+ // place.
+ throw new NoRest();
+ }
+ throw new MojoExecutionException(String.format("Authentication failure status %d.", statusCode));
}
- throw new MojoExecutionException(
- String.format("Authentication failure status %d.", authRes.getStatus()));
}
}
}
- private WebClient setupWebClient(String jiraUrl) {
- WebClient client = WebClient.create(jiraUrl);
-
- ClientConfiguration clientConfiguration = WebClient.getConfig(client);
- HTTPConduit http = clientConfiguration.getHttpConduit();
- // MCHANGES-324 - Maintain the client session
- clientConfiguration.getRequestContext().put(Message.MAINTAIN_SESSION, Boolean.TRUE);
-
- if (getLog().isDebugEnabled()) {
- clientConfiguration.getInInterceptors().add(new LoggingInInterceptor());
- clientConfiguration.getOutInterceptors().add(new LoggingOutInterceptor());
+ private CloseableHttpClient setupHttpClient(String jiraUrl) {
+
+ HttpClientBuilder httpClientBuilder = HttpClients.custom()
+ .setDefaultCookieStore(new BasicCookieStore())
+ .setDefaultRequestConfig(RequestConfig.custom()
+ .setConnectionRequestTimeout(receiveTimout)
+ .setConnectTimeout(connectionTimeout)
+ .build())
+ .setDefaultHeaders(Collections.singletonList(new BasicHeader("Accept", "application/json")));
+
+ Proxy proxy = getProxy(jiraUrl);
+ if (proxy != null) {
+ if (proxy.getUsername() != null && proxy.getPassword() != null) {
+ CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+ credentialsProvider.setCredentials(
+ new AuthScope(proxy.getHost(), proxy.getPort()),
+ new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()));
+ httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+ }
+ httpClientBuilder.setProxy(new HttpHost(proxy.getHost(), proxy.getPort()));
}
+ return httpClientBuilder.build();
+ }
- HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
-
- // MCHANGES-341 Externalize JIRA server timeout values to the configuration section
- getLog().debug("RestJiraDownloader: connectionTimeout: " + connectionTimeout);
- httpClientPolicy.setConnectionTimeout(connectionTimeout);
- httpClientPolicy.setAllowChunking(false);
- getLog().debug("RestJiraDownloader: receiveTimout: " + receiveTimout);
- httpClientPolicy.setReceiveTimeout(receiveTimout);
-
- // MCHANGES-334 RestJiraDownloader doesn't honor proxy settings
- getProxyInfo(jiraUrl);
-
- if (proxyHost != null) {
- getLog().debug("Using proxy: " + proxyHost + " at port " + proxyPort);
- httpClientPolicy.setProxyServer(proxyHost);
- httpClientPolicy.setProxyServerPort(proxyPort);
- httpClientPolicy.setProxyServerType(ProxyServerType.HTTP);
- if (proxyUser != null) {
- ProxyAuthorizationPolicy proxyAuthorizationPolicy = new ProxyAuthorizationPolicy();
- proxyAuthorizationPolicy.setAuthorizationType("Basic");
- proxyAuthorizationPolicy.setUserName(proxyUser);
- proxyAuthorizationPolicy.setPassword(proxyPass);
- http.setProxyAuthorization(proxyAuthorizationPolicy);
+ private Proxy getProxy(String jiraUrl) {
+ Proxy proxy = settings.getActiveProxy();
+ if (proxy != null) {
+ SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(proxy));
+ if (!result.getProblems().isEmpty()) {
+ for (SettingsProblem problem : result.getProblems()) {
+ log.error(problem.getMessage());
+ }
+ } else {
+ proxy = result.getProxy();
}
}
- if (webUser != null) {
- AuthorizationPolicy authPolicy = new AuthorizationPolicy();
- authPolicy.setAuthorizationType("Basic");
- authPolicy.setUserName(webUser);
- authPolicy.setPassword(webPassword);
- http.setAuthorization(authPolicy);
+ if (proxy != null && proxy.getNonProxyHosts() != null) {
+ URI jiraUri = URI.create(jiraUrl);
+ boolean nonProxy = Arrays.stream(proxy.getNonProxyHosts().split("\\|"))
+ .anyMatch(host -> !host.equalsIgnoreCase(jiraUri.getHost()));
+ if (nonProxy) {
+ return null;
+ }
}
- http.setClient(httpClientPolicy);
- return client;
+ return proxy;
}
public List<Issue> getIssueList() {
diff --git a/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java b/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java
index a27babf..fefab6a 100644
--- a/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java
+++ b/src/test/java/org/apache/maven/plugins/jira/JiraReportTest.java
@@ -27,7 +27,7 @@ import org.apache.maven.plugin.testing.AbstractMojoTestCase;
* @since 2.8
*/
public class JiraReportTest extends AbstractMojoTestCase {
- private final JiraReport mojo = new JiraReport();
+ private final JiraReport mojo = new JiraReport(null);
/**
* If the mojo has been marked to be skipped, then it should indicate that the report cannot be generated.
diff --git a/src/test/java/org/apache/maven/plugins/jira/JiraUnicodeTestCase.java b/src/test/java/org/apache/maven/plugins/jira/JiraUnicodeTestCase.java
index b429704..c5928b3 100644
--- a/src/test/java/org/apache/maven/plugins/jira/JiraUnicodeTestCase.java
+++ b/src/test/java/org/apache/maven/plugins/jira/JiraUnicodeTestCase.java
@@ -19,23 +19,23 @@
package org.apache.maven.plugins.jira;
import java.io.File;
-import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.plugins.issues.Issue;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
-import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
/**
* @version $Id$
@@ -53,7 +53,7 @@ public class JiraUnicodeTestCase extends AbstractMojoTestCase {
assertNotNull(pom);
assertTrue(pom.exists());
- JiraReport mojo = (JiraReport) lookupMojo("jira-report", pom);
+ JiraReport mojo = lookupMojo("jira-report", pom);
MavenProject project = new JiraUnicodeTestProjectStub();
MavenSession session = newMavenSession(project);
@@ -80,15 +80,17 @@ public class JiraUnicodeTestCase extends AbstractMojoTestCase {
setVariableValueToObject(mojo, "mavenSession", session);
setVariableValueToObject(mojo, "mojoExecution", new MojoExecution(new Plugin(), "jira-report", "default"));
- String jiraXml;
- try (InputStream testJiraXmlStream =
- JiraUnicodeTestCase.class.getResourceAsStream("unicode-jira-results.xml")) {
- jiraXml = IOUtils.toString(testJiraXmlStream, UTF_8);
- }
+ RestJiraDownloader mock = mock(RestJiraDownloader.class);
+ Issue issue = new Issue();
+ issue.setKey("PCSUNIT-2");
+ issue.setLink("http://pcsjira.slg.gr/browse/PCSUNIT-2");
+ issue.setSummary("海龟一路下跌。 Απεικόνιση σε EXCEL των data των φορμών. Περίπτωση με πολλά blocks");
+ issue.setStatus("Closed");
+ issue.setResolution("Fixed");
+ issue.setAssignee("Nikolaos Stais");
+ when(mock.getIssueList()).thenReturn(Collections.singletonList(issue));
- MockJiraDownloader mockDownloader = new MockJiraDownloader();
- mockDownloader.setJiraXml(jiraXml);
- mojo.setMockDownloader(mockDownloader);
+ mojo.setMockDownloader(mock);
File outputDir = new File("target/jira-test-output");
outputDir.mkdirs();
mojo.setReportOutputDirectory(outputDir);
diff --git a/src/test/java/org/apache/maven/plugins/jira/MockJiraDownloader.java b/src/test/java/org/apache/maven/plugins/jira/MockJiraDownloader.java
deleted file mode 100644
index 1063e93..0000000
--- a/src/test/java/org/apache/maven/plugins/jira/MockJiraDownloader.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.maven.plugins.jira;
-
-import java.io.StringReader;
-import java.util.List;
-
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.issues.Issue;
-import org.xml.sax.InputSource;
-
-/**
- * Allow test cases in the jira mojo without actually talking to jira.
- *
- * @version $Id$
- */
-public class MockJiraDownloader extends AbstractJiraDownloader {
- @Override
- public void doExecute() {
- // do nothing
- }
-
- private String jiraXml;
-
- @Override
- public List<Issue> getIssueList() throws MojoExecutionException {
- JiraXML jira = new JiraXML(log, jiraDatePattern);
- InputSource inputSource = new InputSource(new StringReader(jiraXml));
- jira.parse(inputSource);
- log.info("The JIRA version is '" + jira.getJiraVersion() + "'");
- return jira.getIssueList();
- }
-
- public void setJiraXml(String jiraXml) {
- this.jiraXml = jiraXml;
- }
-
- public String getJiraXml() {
- return jiraXml;
- }
-}
diff --git a/src/test/resources/org/apache/maven/plugins/jira/unicode-jira-results.xml b/src/test/resources/org/apache/maven/plugins/jira/unicode-jira-results.xml
deleted file mode 100644
index 2b268cc..0000000
--- a/src/test/resources/org/apache/maven/plugins/jira/unicode-jira-results.xml
+++ /dev/null
@@ -1,330 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you 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.
--->
-
-<!-- RSS generated by JIRA (Enterprise Edition, Version: 3.13.2-#335) at Wed Aug 05 14:43:20 EEST 2009 -->
-<!-- If you wish to do custom client-side styling of RSS, uncomment this:
-<?xml-stylesheet href="http://pcsjira.slg.gr/styles/jiraxml2html.xsl" type="text/xsl"?>
--->
-<rss version="0.92" >
-<channel>
- <title>Professional Computer Services S.A. JIRA</title>
- <link>http://pcsjira.slg.gr/secure/IssueNavigator.jspa?reset=true&pid=10101&status=6&resolution=1&sorter/field=created&sorter/order=DESC&sorter/field=priority&sorter/order=DESC</link>
- <description>An XML representation of a search request</description>
- <language>en-us</language> <issue start="0" end="2" total="2" /> <build-info>
- <version>3.13.2</version>
- <build-number>335</build-number>
- <build-date>26-11-2008</build-date>
- <edition>Enterprise</edition>
- </build-info>
-
-<item>
-<title>[PCSUNIT-2] 海龟一路下跌。 Απεικόνιση σε EXCEL των data των φορμών. Περίπτωση με πολλά blocks</title>
-<link>http://pcsjira.slg.gr/browse/PCSUNIT-2</link>
-
- <description></description>
- <environment></environment>
- <key id="11137">PCSUNIT-2</key>
- <summary>海龟一路下跌。 Απεικόνιση σε EXCEL των data των φορμών. Περίπτωση με πολλά blocks</summary>
-
- <type id="4" iconUrl="http://pcsjira.slg.gr/images/icons/improvement.gif">Improvement</type>
-
-
- <priority id="6" iconUrl="http://pcsjira.slg.gr/images/icons/priority_minor.gif">Normal</priority>
- <status id="6" iconUrl="http://pcsjira.slg.gr/images/icons/status_closed.gif">Closed</status>
- <resolution id="1">Fixed</resolution>
-
- <security id="10000">Internal Issue</security>
-
- <assignee username="nikoss">Nikolaos Stais</assignee>
-
- <reporter username="nikoss">Nikolaos Stais</reporter>
-
- <created>Wed, 18 Mar 2009 11:04:28 +0200 (EET)</created>
- <updated>Thu, 23 Apr 2009 13:22:19 +0300 (EEST)</updated>
-
-
-
-
- <due></due>
-
- <votes>0</votes>
-
-
-
- <comments>
- <comment id="11583" author="nikoss" created="Thu, 19 Mar 2009 16:25:17 +0200 (EET)" rolelevel="PCS Internal" >Εχει πραγματοποιηθεί μια πρώτη προσέγγιση κ υλοποίηση, χρειάζεται Τ	 [...]
- </comments>
-
- <attachments>
- </attachments>
-
- <subtasks>
- </subtasks>
-
- <customfields>
- <customfield id="customfield_10011" key="com.atlassian.jira.plugin.system.customfieldtypes:float">
- <customfieldname>Α/Η</customfieldname>
- <customfieldvalues>
- <customfieldvalue>2.0</customfieldvalue>
- </customfieldvalues>
- </customfield>
- </customfields>
-
-</item>
-
-<item>
-<title>[PCSUNIT-1] ΔΗΜΙΟΥΡΓΙΑ ΔΙΑΔΙΚΑΣΙΑΣ ΓΙΑ UNDO CHANGES</title>
-<link>http://pcsjira.slg.gr/browse/PCSUNIT-1</link>
-
- <description></description>
- <environment></environment>
- <key id="10051">PCSUNIT-1</key>
- <summary>ΔΗΜΙΟΥΡΓΙΑ ΔΙΑΔΙΚΑΣΙΑΣ ΓΙΑ UNDO CHANGES</summary>
-
- <type id="2" iconUrl="http://pcsjira.slg.gr/images/icons/newfeature.gif">New Feature</type>
-
-
- <priority id="4" iconUrl="http://pcsjira.slg.gr/images/icons/priority_minor.gif">Minor</priority>
- <status id="6" iconUrl="http://pcsjira.slg.gr/images/icons/status_closed.gif">Closed</status>
- <resolution id="1">Fixed</resolution>
-
- <security id="10000">Internal Issue</security>
-
- <assignee username="nikoss">Nikolaos Stais</assignee>
-
- <reporter username="nikoss">Nikolaos Stais</reporter>
-
- <created>Wed, 4 Feb 2009 13:47:25 +0200 (EET)</created>
- <updated>Wed, 13 May 2009 13:32:49 +0300 (EEST)</updated>
-
-
-
-
- <due></due>
-
- <votes>0</votes>
-
-
-
- <comments>
- <comment id="10039" author="nikoss" created="Thu, 5 Feb 2009 10:07:35 +0200 (EET)" >Έγινε μια πρώτη προσέγγιση και ενημέρωση συναδέλφων. Σε αναμονή δοκιμής α` [...]
- <comment id="13509" author="nikoss" created="Wed, 13 May 2009 13:32:34 +0300 (EEST)" >&nbsp;
-<br/>
-
-<br/>
-Έχοντας λάβει κάποια requests από πελάτες οι οποίοι επιθυμούν να κάνουν undo σε batch ροές,
-<br/>
-
-<br/>
-θεωρώ ότι υπάρχει ένας εύκολος τρόπος να το πετύχουμε, προκειμένου να αποφύγουμε να κρατάμε ισ	 [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Το συγκεκριμένο θέμα δεν έχει εφαρμοστεί (από όσο ξέρω) με τρόπο που να εισάγουμε δεδομένα και να [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Τολμώ να κάνω μια πρόταση προς διερεύνηση ... J
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Θεωρητικά θα μπορούμε π.χ. να κάνουμε ενημέρωση με τιμή να βλέπουμε τι μερίδια έχουν κοπεί (καλών [...]
-<br/>
-
-<br/>
-οθόνη θα είναι σαν να μην έχουμε κάνει τίποτα.
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Η όλη δουλεία γίνεται με αλλαγές στα εξής σημεία.
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Στον ON-COMMIT trigger (form-level).
-<br/>
-
-<br/>
-Στον ΚΕΥ-COMMIT trigger (form-level)
-<br/>
-
-<br/>
-Στον KEY-EXIT trigger (form-level)
-<br/>
-
-<br/>
-Στον KEY-ENTQRY trigger (form-level)
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Οπωσδήποτε αν υπάρχουν αντίστοιχοι triggers σε block-level, τότε πρέπει να επεξεργαστούν κατάλληλα.
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Στην ουσία, δεν κάνουμε ποτέ commit (αλλά POST;?στέλνει τα records στη βάση), παρά μόνο πατώντας το κουμπί REAL COMMIT.
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Μπορείτε να δείτε τα form1.fmb , form2.fmb που υπάρχουν στο Y:\MFHELLAS_10G\Exedir
-<br/>
-
-<br/>
-ή και να τεστάρετε το εξής σενάριο(<a href="http://dioskouros:7778/forms90/f90servlet?config=test_undo">http://dioskouros:7778/forms90/f90servlet?config=test_undo</a>)
-<br/>
-
-<br/>
-στην πράξη:
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Η form1 βλέπει ένα απλό πίνακα με 2 στήλες. Κάθε φορά που εισάγω μια εγγραφή και πατάω F10 βλέπω μήνυμα
-<br/>
-
-<br/>
-&quot;1 record applied&quot; (η διαφορά φαίνεται κ εδώ, δηλ. δεν λέει: &quot;1 record applied and saved&quot;, λείπει το &quot;saved&quot;=δεν έχει κάνει commit στη βάση αλ& [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Αν καλέσουμε τη δεύτερη οθόνη form2, μπορούμε να κάνουμε query τις αλλαγές(insert,delete,update + F10) που πραγματοποιήσαμε στ [...]
-<br/>
-
-<br/>
-Αν στην ίδια οθόνη (form1) κάνουμε F7 χωρίς να κάνουμε F10 (μετά την αλλαγή) η οθόνη χάνει τις αλλαγές (προγρα&# [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Βγαίνοντας από τις δύο οθόνες χωρίς να πατήσουμε το button REAL COMMIT, όλες οι αλλαγές που κάναμε στην form1 και τις [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Τα insert, update, delete μπορούν να γίνουν και προγραμματιστικά. Στην οθόνη form1 στον ON-INSERT trigger του block, υπάρχει για λόγους τε` [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Παρακαλώ για τα σχόλια σας και ιδιαίτερα για τους ενδεχόμενους κινδύνους, αν σας το επιτρέπει ο & [...]
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-&nbsp;
-<br/>
-
-<br/>
-Ευχαριστώ πολύ,
-<br/>
-
-<br/>
-</comment>
- </comments>
-
- <attachments>
- </attachments>
-
- <subtasks>
- </subtasks>
-
- <customfields>
- <customfield id="customfield_10001" key="com.atlassian.jira.plugin.system.customfieldtypes:textfield">
- <customfieldname>Screen Code</customfieldname>
- <customfieldvalues>
- <customfieldvalue>ΘΕΩΡΙΤΙΚ Α ΕΦΑΡΜΟΓΗ ΣΕ ΟΛΕΣ ΤΙΣ ΟΘΟΝΕΣ</customfieldvalue>
-
- </customfieldvalues>
- </customfield>
- </customfields>
-
-</item>
-</channel>
-</rss>