You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by bi...@apache.org on 2012/11/22 01:29:18 UTC

svn commit: r1412388 - in /maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira: JiraQueryBuilder.java JqlQueryBuilder.java ParameterQueryBuilder.java RestJiraDownloader.java

Author: bimargulies
Date: Thu Nov 22 00:29:17 2012
New Revision: 1412388

URL: http://svn.apache.org/viewvc?rev=1412388&view=rev
Log:
MCHANGES-295: Remove need for numeric component ID's etc when using REST with JIRA

Modified:
    maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JiraQueryBuilder.java
    maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JqlQueryBuilder.java
    maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/ParameterQueryBuilder.java
    maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/RestJiraDownloader.java

Modified: maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JiraQueryBuilder.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JiraQueryBuilder.java?rev=1412388&r1=1412387&r2=1412388&view=diff
==============================================================================
--- maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JiraQueryBuilder.java (original)
+++ maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JiraQueryBuilder.java Thu Nov 22 00:29:17 2012
@@ -21,6 +21,8 @@ package org.apache.maven.plugin.jira;
 
 import org.apache.maven.plugin.logging.Log;
 
+import java.util.List;
+
 /**
  * An interface for building a search query for JIRA.
  *
@@ -34,23 +36,35 @@ public interface JiraQueryBuilder
 
     JiraQueryBuilder components( String components );
 
+    JiraQueryBuilder components( List<String> components );
+
     JiraQueryBuilder filter( String filter );
 
     JiraQueryBuilder fixVersion( String fixVersion );
 
     JiraQueryBuilder fixVersionIds( String fixVersionIds );
 
+    JiraQueryBuilder fixVersionIds( List<String> fixVersionIds );
+
     Log getLog();
 
     JiraQueryBuilder priorityIds( String priorityIds );
 
+    JiraQueryBuilder priorityIds( List<String> priorityIds );
+
     JiraQueryBuilder project( String project );
 
     JiraQueryBuilder resolutionIds( String resolutionIds );
 
+    JiraQueryBuilder resolutionIds( List<String> resolutionIds );
+
     JiraQueryBuilder sortColumnNames( String sortColumnNames );
 
     JiraQueryBuilder statusIds( String statusIds );
 
+    JiraQueryBuilder statusIds( List<String> statusIds );
+
     JiraQueryBuilder typeIds( String typeIds );
+
+    JiraQueryBuilder typeIds( List<String> typeIds );
 }

Modified: maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JqlQueryBuilder.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JqlQueryBuilder.java?rev=1412388&r1=1412387&r2=1412388&view=diff
==============================================================================
--- maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JqlQueryBuilder.java (original)
+++ maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/JqlQueryBuilder.java Thu Nov 22 00:29:17 2012
@@ -23,6 +23,7 @@ import org.apache.maven.plugin.logging.L
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -93,6 +94,12 @@ public class JqlQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder components( List<String> components )
+    {
+        addValues( "component", components );
+        return this;
+    }
+
     public JiraQueryBuilder filter( String filter )
     {
         this.filter = filter;
@@ -103,7 +110,7 @@ public class JqlQueryBuilder
      * When both {@link #fixVersion(String)} and {@link #fixVersionIds(String)} are used then you will probably
      * end up with a JQL query that is valid, but returns nothing. Unless they both only reference the same fixVersion
      *
-     * @param fixVersion
+     * @param fixVersion a single fix version
      * @return
      */
     public JiraQueryBuilder fixVersion( String fixVersion )
@@ -116,7 +123,7 @@ public class JqlQueryBuilder
      * When both {@link #fixVersion(String)} and {@link #fixVersionIds(String)} are used then you will probably
      * end up with a JQL query that is valid, but returns nothing. Unless they both only reference the same fixVersion
      *
-     * @param fixVersionIds
+     * @param fixVersionIds a comma-separated list of version ids.
      * @return
      */
     public JiraQueryBuilder fixVersionIds( String fixVersionIds )
@@ -125,6 +132,17 @@ public class JqlQueryBuilder
         return this;
     }
 
+    /**
+     * Add a sequence of version IDs already in a list.
+     * @param fixVersionIds the version ids.
+     * @return
+     */
+    public JiraQueryBuilder fixVersionIds( List<String> fixVersionIds )
+    {
+        addValues( "fixVersion", fixVersionIds );
+        return this;
+    }
+
     public Log getLog()
     {
         return log;
@@ -136,6 +154,12 @@ public class JqlQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder priorityIds( List<String> priorityIds )
+    {
+        addValues( "priority", priorityIds );
+        return this;
+    }
+
     public JiraQueryBuilder project( String project )
     {
         addSingleValue( "project", project );
@@ -148,6 +172,12 @@ public class JqlQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder resolutionIds( List<String> resolutionIds )
+    {
+        addValues( "resolution", resolutionIds );
+        return this;
+    }
+
     public JiraQueryBuilder sortColumnNames( String sortColumnNames )
     {
         if ( sortColumnNames != null )
@@ -172,6 +202,12 @@ public class JqlQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder statusIds( List<String> statusIds )
+    {
+        addValues( "status", statusIds );
+        return this;
+    }
+
 
     public JiraQueryBuilder typeIds( String typeIds )
     {
@@ -179,6 +215,12 @@ public class JqlQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder typeIds( List<String> typeIds )
+    {
+        addValues( "type", typeIds );
+        return this;
+    }
+
     public JiraQueryBuilder urlEncode( boolean doEncoding )
     {
         urlEncode = doEncoding;
@@ -217,6 +259,27 @@ public class JqlQueryBuilder
         }
     }
 
+    private void addValues( String key, List<String> values )
+    {
+        if ( values != null && values.size() > 0 )
+        {
+            if ( query.length() > 0 )
+            {
+                query.append( " AND " );
+            }
+
+            query.append( key ).append( " in (" );
+
+            for ( int i = 0; i < ( values.size() - 1 ); i++ )
+            {
+                trimAndQuoteValue( values.get( i ) );
+                query.append( ", " );
+            }
+            trimAndQuoteValue( values.get ( values.size() - 1 ) );
+            query.append( ")" );
+        }
+    }
+
     private void addSingleSortColumn( String name )
     {
         boolean descending = false;

Modified: maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/ParameterQueryBuilder.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/ParameterQueryBuilder.java?rev=1412388&r1=1412387&r2=1412388&view=diff
==============================================================================
--- maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/ParameterQueryBuilder.java (original)
+++ maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/ParameterQueryBuilder.java Thu Nov 22 00:29:17 2012
@@ -19,12 +19,13 @@ package org.apache.maven.plugin.jira;
  * under the License.
  */
 
+import org.apache.maven.plugin.logging.Log;
+
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.maven.plugin.logging.Log;
-
 /**
  * JIRA 3.x way of constructing a search query based on URL parameters.
  * 
@@ -113,6 +114,23 @@ public class ParameterQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder components( List<String> components )
+    {
+        // add components
+        if ( components != null )
+        {
+            for ( String component : components )
+            {
+                component = component.trim();
+                if ( component.length() > 0 )
+                {
+                    query.append( "&component=" ).append( component );
+                }
+            }
+        }
+        return this;
+    }
+
     public JiraQueryBuilder filter( String filter )
     {
         this.filter = filter;
@@ -145,6 +163,11 @@ public class ParameterQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder fixVersionIds( List<String> fixVersionIds )
+    {
+        throw new RuntimeException( "fixVersionIds(List) not supported for very old parameter queries." );
+    }
+
     public Log getLog()
     {
         return log;
@@ -171,6 +194,11 @@ public class ParameterQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder priorityIds( List<String> priorityIds )
+    {
+        throw new RuntimeException( "priorityIds(List) not supported for old parameter queries." );
+    }
+
     /**
      * This method has no effect in this implementation.
      */
@@ -200,6 +228,11 @@ public class ParameterQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder resolutionIds( List<String> resolutionIds )
+    {
+        throw new RuntimeException( "resolutionIds(List) not supported for old ParameterQueryBuilder" );
+    }
+
     public JiraQueryBuilder sortColumnNames( String sortColumnNames )
     {
         // get the Sort order
@@ -335,6 +368,11 @@ public class ParameterQueryBuilder
         return this;
     }
 
+    public JiraQueryBuilder statusIds( List<String> statusIds )
+    {
+        throw new RuntimeException( "statusIds(List) not supported for old parameter queries." );
+    }
+
     public JiraQueryBuilder typeIds( String typeIds )
     {
         // get the Type Ids
@@ -354,4 +392,9 @@ public class ParameterQueryBuilder
         }
         return this;
     }
+
+    public JiraQueryBuilder typeIds( List<String> typeIds )
+    {
+        throw new RuntimeException( "typeIds(List) not supported for old ParameterQueryBuilder" );
+    }
 }

Modified: maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/RestJiraDownloader.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/RestJiraDownloader.java?rev=1412388&r1=1412387&r2=1412388&view=diff
==============================================================================
--- maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/RestJiraDownloader.java (original)
+++ maven/plugins/trunk/maven-changes-plugin/src/main/java/org/apache/maven/plugin/jira/RestJiraDownloader.java Thu Nov 22 00:29:17 2012
@@ -34,6 +34,7 @@ import org.apache.cxf.transport.http.HTT
 import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
 import org.apache.cxf.transports.http.configuration.ProxyServerType;
 import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.issues.Issue;
 
 import javax.ws.rs.core.HttpHeaders;
@@ -62,6 +63,15 @@ public class RestJiraDownloader extends 
     private JsonFactory jsonFactory;
     private SimpleDateFormat dateFormat;
 
+    private List<String> resolvedFixVersionIds;
+    private List<String> resolvedStatusIds;
+    private List<String> resolvedComponentIds;
+    private List<String> resolvedTypeIds;
+    private List<String> resolvedResolutionIds;
+    private List<String> resolvedPriorityIds;
+
+    private String jiraProject;
+
     public static class NoRest extends Exception {
         public NoRest( )
         {
@@ -73,6 +83,12 @@ public class RestJiraDownloader extends 
         jsonFactory = new MappingJsonFactory(  );
         //2012-07-17T06:26:47.723-0500
         dateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ" );
+        resolvedFixVersionIds = new ArrayList<String>(  );
+        resolvedStatusIds = new ArrayList<String>(  );
+        resolvedComponentIds = new ArrayList<String>(  );
+        resolvedTypeIds = new ArrayList<String>(  );
+        resolvedResolutionIds = new ArrayList<String>(  );
+        resolvedPriorityIds = new ArrayList<String>(  );
     }
 
     public void doExecute() throws Exception
@@ -80,7 +96,7 @@ public class RestJiraDownloader extends 
 
         Map<String, String> urlMap = JiraHelper.getJiraUrlAndProjectName( project.getIssueManagement().getUrl() );
         String jiraUrl = urlMap.get( "url" );
-        String jiraProject = urlMap.get( "project" ); // assumed to be a 'project key'
+        jiraProject = urlMap.get( "project" );
         WebClient client = setupWebClient( jiraUrl );
         /*
          If there is no session auth, explicitly probe to see if there is any REST.
@@ -97,16 +113,18 @@ public class RestJiraDownloader extends 
         }
         doSessionAuth( client );
 
+        resolveIds( client, jiraProject );
+
         String jqlQuery = new JqlQueryBuilder( log )
             .urlEncode( false )
             .project( jiraProject )
             .fixVersion( getFixFor() )
-            .fixVersionIds( fixVersionIds )
-            .statusIds( statusIds )
-            .priorityIds( priorityIds )
-            .resolutionIds( resolutionIds )
-            .components( component )
-            .typeIds( typeIds )
+            .fixVersionIds( resolvedFixVersionIds )
+            .statusIds( resolvedStatusIds )
+            .priorityIds( resolvedPriorityIds )
+            .resolutionIds( resolvedResolutionIds )
+            .components( resolvedComponentIds )
+            .typeIds( resolvedTypeIds )
             .sortColumnNames( sortColumnNames )
             .build();
 
@@ -127,37 +145,109 @@ public class RestJiraDownloader extends 
         Response searchResponse = client.post( searchParamStringWriter.toString() );
         if ( searchResponse.getStatus() != Response.Status.OK.getStatusCode() )
         {
-            if ( MediaType.APPLICATION_JSON_TYPE.getType().equals( getResponseMediaType( searchResponse ).getType() ) )
+            reportErrors( searchResponse );
+        }
+
+        JsonNode issueTree = getResponseTree( searchResponse );
+        assert issueTree.isObject();
+        JsonNode issuesNode = issueTree.get( "issues" );
+        assert issuesNode.isArray();
+        buildIssues( issuesNode, jiraUrl, jiraProject );
+    }
+
+    private JsonNode getResponseTree( Response response )
+        throws IOException
+    {
+        JsonParser jsonParser = jsonFactory.createJsonParser( (InputStream) response.getEntity() );
+        return (JsonNode) jsonParser.readValueAsTree();
+    }
+
+    private void reportErrors( Response resp )
+        throws IOException, MojoExecutionException
+    {
+        if ( MediaType.APPLICATION_JSON_TYPE.getType().equals( getResponseMediaType( resp ).getType() ) )
+        {
+            JsonNode errorTree = getResponseTree( resp );
+            assert errorTree.isObject();
+            JsonNode messages = errorTree.get( "errorMessages" );
+            if ( messages != null )
             {
-                JsonParser jsonParser = jsonFactory.createJsonParser( ( InputStream ) searchResponse.getEntity() );
-                JsonNode errorTree = jsonParser.readValueAsTree();
-                assert errorTree.isObject();
-                JsonNode messages = errorTree.get( "errorMessages" );
-                if ( messages != null )
+                for ( int mx = 0; mx < messages.size(); mx ++ )
                 {
-                    for ( int mx = 0; mx < messages.size(); mx ++ )
-                    {
-                        getLog().error( messages.get( mx ).asText() );
-                    }
+                    getLog().error( messages.get( mx ).asText() );
                 }
-                else
+            }
+            else
+            {
+                JsonNode message = errorTree.get( "message" );
+                if ( message != null )
                 {
-                    JsonNode message = errorTree.get( "message" );
-                    if ( message != null )
-                    {
-                        getLog().error( message.asText() );
-                    }
+                    getLog().error( message.asText() );
                 }
             }
-            throw new MojoExecutionException( String.format( "Failed to query issues; response %d", searchResponse.getStatus() ) );
         }
+        throw new MojoExecutionException( String.format( "Failed to query issues; response %d", resp.getStatus() ) );
+    }
 
-        JsonParser jsonParser = jsonFactory.createJsonParser( ( InputStream ) searchResponse.getEntity() );
-        JsonNode issueTree = jsonParser.readValueAsTree();
-        assert issueTree.isObject();
-        JsonNode issuesNode = issueTree.get( "issues" );
-        assert issuesNode.isArray();
-        buildIssues( issuesNode, jiraUrl, jiraProject );
+    private void resolveIds( WebClient client, String jiraProject )
+        throws IOException, MojoExecutionException, MojoFailureException
+    {
+        resolveList( resolvedComponentIds, client, "components",  component, "/rest/api/2/project/{key}/components", jiraProject );
+        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" );
+    }
+
+    private void resolveList( List<String> targetList, WebClient client, String what, String input,
+                              String listRestUrlPattern, String... listUrlArgs )
+        throws IOException, MojoExecutionException, MojoFailureException
+    {
+        if ( input == null || input.length() == 0 )
+        {
+            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() != 200 )
+        {
+            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 ) );
+        }
+    }
+
+    private String resolveOneItem( JsonNode items, String what, String nameOrId )
+        throws IOException, MojoExecutionException, MojoFailureException
+    {
+        for ( int cx = 0; cx < items.size(); cx ++ )
+        {
+            JsonNode item = items.get( cx );
+            if ( nameOrId.equals( item.get( "id" ).asText() ) )
+            {
+                return nameOrId;
+            }
+            else if ( nameOrId.equals( item.get( "name" ).asText() ) )
+            {
+                return item.get( "id" ).asText();
+            }
+        }
+        throw new MojoFailureException( String.format("Could not find %s %s.", what, nameOrId ) );
     }
 
     private MediaType getResponseMediaType( Response response )
@@ -369,9 +459,7 @@ public class RestJiraDownloader extends 
                 JsonNode fvNode = val.get( vx );
                 issue.addFixVersion( fvNode.get( "name" ).asText() );
             }
-
         }
-
     }
 
     private void processComments( Issue issue, JsonNode val )