Coverage Report - org.apache.maven.jira.JiraDownloader2
 
Classes in this File Line Coverage Branch Coverage Complexity
JiraDownloader2
0% 
0% 
2,905
 
 1  
 package org.apache.maven.jira;
 2  
 
 3  
 /*
 4  
  * Copyright 2001-2006 The Apache Software Foundation.
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *      http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import org.apache.commons.httpclient.Credentials;
 20  
 import org.apache.commons.httpclient.Header;
 21  
 import org.apache.commons.httpclient.HostConfiguration;
 22  
 import org.apache.commons.httpclient.HttpClient;
 23  
 import org.apache.commons.httpclient.HttpException;
 24  
 import org.apache.commons.httpclient.HttpState;
 25  
 import org.apache.commons.httpclient.HttpStatus;
 26  
 import org.apache.commons.httpclient.StatusLine;
 27  
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 28  
 import org.apache.commons.httpclient.methods.GetMethod;
 29  
 import org.apache.maven.plugin.logging.Log;
 30  
 import org.apache.maven.project.MavenProject;
 31  
 import org.apache.maven.settings.Proxy;
 32  
 import org.apache.maven.settings.Settings;
 33  
 
 34  
 import java.io.File;
 35  
 import java.io.FileWriter;
 36  
 import java.io.IOException;
 37  
 import java.io.PrintWriter;
 38  
 import java.util.HashMap;
 39  
 import java.util.Map;
 40  
 
 41  
 /**
 42  
  * Gets relevant issues in RSS from a given JIRA installation.
 43  
  *
 44  
  * Based on version 1.1.2 and patch by Dr. Spock (MPJIRA-8).
 45  
  *
 46  
  * @author mfranken@xebia.com
 47  
  * @author jruiz@exist.com
 48  
  * @version $Id: org.apache.maven.jira.JiraDownloader2.html 816584 2012-05-08 12:33:35Z hboutemy $
 49  0
  */
 50  0
 public final class JiraDownloader2
 51  0
 {
 52  
 
 53  
     /** Log for debug output. */
 54  
     private org.apache.maven.plugin.logging.Log log;
 55  
 
 56  
     /** Output file for xml document. */
 57  
     private File output;
 58  
 
 59  
     /** The maximum number of entries to show. */
 60  
     private int nbEntriesMax;
 61  
 
 62  
     /** The filter to apply to query to JIRA. */
 63  
     private String filter;
 64  
 
 65  
     /** Ids of status to show, as comma separated string. */
 66  
     private String statusIds;
 67  
 
 68  
     /** Ids of resolution to show, as comma separated string. */
 69  
     private String resolutionIds;
 70  
 
 71  
     /** Ids of priority to show, as comma separated string. */
 72  
     private String priorityIds;
 73  
 
 74  
     /** The component to show. */
 75  
     private String component;
 76  
 
 77  
     /** The username to log into JIRA. */
 78  
     private String jiraUser;
 79  
 
 80  
     /** The password to log into JIRA. */
 81  
     private String jiraPassword;
 82  
 
 83  
     /** The username to log into webserver. */
 84  
     private String webUser;
 85  
 
 86  
     /** The password to log into webserver. */
 87  
     private String webPassword;
 88  
 
 89  
     /** The maven project. */
 90  
     private MavenProject project;
 91  
 
 92  
     /** The maven settings. */
 93  
     private Settings settings;
 94  
 
 95  0
     /** Mapping containing all JIRA status values. */
 96  0
     private static Map statusMap = new HashMap();
 97  0
 
 98  0
     /** Mapping containing all JIRA resolution values. */
 99  0
     private static Map resolutionMap = new HashMap();
 100  0
 
 101  0
     /** Mapping containing all JIRA priority values. */
 102  0
     private static Map priorityMap = new HashMap();
 103  0
 
 104  
     static
 105  0
     {
 106  0
         statusMap.put( "Open", "1" );
 107  0
         statusMap.put( "In Progress", "3" );
 108  0
         statusMap.put( "Reopened", "4" );
 109  0
         statusMap.put( "Resolved", "5" );
 110  0
         statusMap.put( "Closed", "6" );
 111  0
 
 112  0
         resolutionMap.put( "Unresolved", "-1" );
 113  0
         resolutionMap.put( "Fixed", "1" );
 114  0
         resolutionMap.put( "Won't Fix", "2" );
 115  0
         resolutionMap.put( "Duplicate", "3" );
 116  0
         resolutionMap.put( "Incomplete", "4" );
 117  0
         resolutionMap.put( "Cannot Reproduce", "5" );
 118  0
 
 119  0
         priorityMap.put( "Blocker", "1" );
 120  0
         priorityMap.put( "Critical", "2" );
 121  0
         priorityMap.put( "Major", "3" );
 122  0
         priorityMap.put( "Minor", "4" );
 123  0
         priorityMap.put( "Trivial", "5" );
 124  0
     }
 125  0
 
 126  
     /**
 127  
      * Creates a filter given the parameters and some defaults.
 128  
      *
 129  
      * @return request parameters to be added to URL used for downloading the JIRA issues
 130  
      */
 131  
     private String createFilter()
 132  0
     {
 133  0
         if ( ( this.filter != null ) && ( this.filter.length() > 0 ) )
 134  0
         {
 135  0
             if ( this.filter.charAt( 0 ) == '&' )
 136  0
             {
 137  0
                 return this.filter.substring( 1 );
 138  0
             }
 139  0
 
 140  0
             return this.filter;
 141  0
         }
 142  0
 
 143  0
         StringBuffer localFilter = new StringBuffer();
 144  0
 
 145  0
         // get the Status Ids
 146  0
         if ( statusIds != null )
 147  0
         {
 148  0
             String[] stats = statusIds.split( "," );
 149  0
 
 150  0
             for ( int i = 0; i < stats.length; i++ )
 151  0
             {
 152  0
                 String statusParam = (String) statusMap.get( stats[i] );
 153  0
 
 154  0
                 if ( statusParam != null )
 155  0
                 {
 156  0
                     localFilter.append( "&statusIds=" + statusParam );
 157  0
                 }
 158  
             }
 159  
         }
 160  
 
 161  0
         // get the Priority Ids
 162  0
         if ( priorityIds != null )
 163  0
         {
 164  0
             String[] prios = priorityIds.split( "," );
 165  0
 
 166  0
             for ( int i = 0; i < prios.length; i++ )
 167  0
             {
 168  0
                 String priorityParam = (String) priorityMap.get( prios[i] );
 169  0
 
 170  0
                 if ( priorityParam != null )
 171  0
                 {
 172  0
                     localFilter.append( "&priorityIds=" + priorityParam );
 173  0
                 }
 174  
             }
 175  
         }
 176  0
 
 177  0
         if ( resolutionIds != null )
 178  0
         {
 179  0
             // get the Resolution Ids
 180  0
             String[] resos = resolutionIds.split( "," );
 181  0
 
 182  0
             for ( int i = 0; i < resos.length; i++ )
 183  0
             {
 184  0
                 String resoParam = (String) resolutionMap.get( resos[i] );
 185  0
 
 186  0
                 if ( resoParam != null )
 187  0
                 {
 188  0
                     localFilter.append( "&resolutionIds=" + resoParam );
 189  0
                 }
 190  
             }
 191  
         }
 192  
 
 193  0
         // add all components
 194  0
         if ( component != null )
 195  0
         {
 196  0
             String[] components = component.split( "," );
 197  0
 
 198  0
             for ( int i = 0; i < components.length; i++ )
 199  0
             {
 200  0
                 if ( components[i].length() > 0 )
 201  0
                 {
 202  0
                     localFilter.append( "&component=" + components[i] );
 203  0
                 }
 204  
             }
 205  
         }
 206  
 
 207  0
         // add default sorting (by priority and then creation date)
 208  0
         String sort = "&sorter/field=created&sorter/order=DESC" + "&sorter/field=priority&sorter/order=DESC";
 209  0
 
 210  0
         return localFilter + sort;
 211  0
     }
 212  
 
 213  
     /**
 214  
      * Execute the query on the JIRA server.
 215  
      *
 216  
      * @throws Exception on error
 217  
      */
 218  
     public void doExecute()
 219  
         throws Exception
 220  
     {
 221  
         try
 222  0
         {
 223  0
             HttpClient cl = new HttpClient();
 224  0
 
 225  0
             HttpState state = new HttpState();
 226  0
 
 227  0
             HostConfiguration hc = new HostConfiguration();
 228  0
 
 229  0
             cl.setHostConfiguration( hc );
 230  0
 
 231  0
             cl.setState( state );
 232  0
 
 233  0
             determineProxy( cl );
 234  0
 
 235  0
             Map urlMap = getJiraUrlAndIssueId();
 236  0
 
 237  0
             String jiraUrl = (String) urlMap.get( "url" );
 238  0
 
 239  0
             String jiraId = (String) urlMap.get( "id" );
 240  0
 
 241  0
             doAuthentication( cl, jiraUrl );
 242  0
 
 243  0
             if ( jiraId == null || jiraId.length() == 0 )
 244  0
             {
 245  0
                 jiraId = JiraHelper.getPidFromJira( log, project.getIssueManagement().getUrl(), cl );
 246  0
             }
 247  0
 
 248  0
             // create the URL for getting the proper issues from JIRA
 249  0
             String fullURL = jiraUrl + "/secure/IssueNavigator.jspa?view=rss&pid=" + jiraId;
 250  0
 
 251  0
             fullURL += createFilter();
 252  0
 
 253  0
             fullURL += ( "&tempMax=" + nbEntriesMax + "&reset=true&decorator=none" );
 254  0
 
 255  0
             // execute the GET
 256  0
             download( cl, fullURL );
 257  0
         }
 258  0
         catch ( Exception e )
 259  0
         {
 260  0
             getLog().error( "Error accessing " + project.getIssueManagement().getUrl(), e );
 261  0
         }
 262  0
     }
 263  0
 
 264  
     private Map getJiraUrlAndIssueId()
 265  0
     {
 266  0
         HashMap urlMap = new HashMap();
 267  0
 
 268  0
         String url = project.getIssueManagement().getUrl();
 269  
 
 270  0
         // chop off the parameter part
 271  0
         int pos = url.indexOf( "?" );
 272  
 
 273  0
         // and get the id while we're at it
 274  0
         String id = "";
 275  0
 
 276  0
         if ( pos >= 0 )
 277  
         {
 278  0
             // url
 279  0
             id = url.substring( url.lastIndexOf( "=" ) + 1 );
 280  0
         }
 281  0
 
 282  0
         String jiraUrl = url.substring( 0, url.lastIndexOf( "/" ) );
 283  0
 
 284  0
         if ( jiraUrl.endsWith( "secure" ) || jiraUrl.endsWith( "browse" ) )
 285  0
         {
 286  0
             jiraUrl = jiraUrl.substring( 0, jiraUrl.lastIndexOf( "/" ) );
 287  0
         }
 288  0
         getLog().info( "JIRA lives at: " + jiraUrl );
 289  0
 
 290  0
         urlMap.put( "url", jiraUrl );
 291  0
 
 292  0
         urlMap.put( "id", id );
 293  0
 
 294  0
         return urlMap;
 295  0
     }
 296  0
 
 297  0
     /**
 298  
      * Authenticate against webserver and into JIRA if we have to.
 299  0
      *
 300  0
      * @param client    the HttpClient
 301  0
      * @param jiraUrl   the JIRA installation
 302  0
      */
 303  0
     private void doAuthentication( HttpClient client, final String jiraUrl )
 304  0
     {
 305  0
         // check and prepare for basic authentication
 306  0
         if ( ( webUser != null ) && ( webUser.length() > 0 ) )
 307  0
         {
 308  0
             client.getState().setAuthenticationPreemptive( true );
 309  0
 
 310  0
             Credentials defaultcreds = new UsernamePasswordCredentials( webUser, webPassword );
 311  0
 
 312  0
             getLog().info( "Using username: " + webUser + " for Basic Authentication against the webserver at "
 313  0
                 + jiraUrl );
 314  0
 
 315  0
             client.getState().setCredentials( null, null, defaultcreds );
 316  0
         }
 317  0
 
 318  0
         // log into JIRA if we have to
 319  0
         String loginUrl = null;
 320  0
 
 321  0
         if ( ( jiraUser != null ) && ( jiraUser.length() > 0 ) && ( jiraPassword != null ) )
 322  0
         {
 323  0
             StringBuffer loginLink = new StringBuffer( jiraUrl );
 324  0
 
 325  0
             loginLink.append( "/login.jsp?os_destination=/secure/" );
 326  0
 
 327  0
             loginLink.append( "&os_username=" ).append( jiraUser );
 328  0
 
 329  0
             getLog().info( "Login URL: " + loginLink + "&os_password=*******" );
 330  0
 
 331  0
             loginLink.append( "&os_password=" ).append( jiraPassword );
 332  0
 
 333  0
             loginUrl = loginLink.toString();
 334  
         }
 335  0
 
 336  0
         // execute the login
 337  0
         if ( loginUrl != null )
 338  0
         {
 339  0
             GetMethod loginGet = new GetMethod( loginUrl );
 340  0
 
 341  0
             try
 342  0
             {
 343  0
                 client.executeMethod( loginGet );
 344  0
 
 345  0
                 getLog().info( "Succesfully logged in into JIRA." );
 346  0
             }
 347  0
             catch ( Exception e )
 348  0
             {
 349  0
                 if ( getLog().isDebugEnabled() )
 350  0
                 {
 351  0
                     getLog().error( "Error trying to login into JIRA:", e );
 352  
                 }
 353  0
                 else
 354  0
                 {
 355  0
                     getLog().error( "Error trying to login into JIRA. Cause is: " + e.getLocalizedMessage() );
 356  0
                 }
 357  0
                 // continue any way, probably will fail later if authentication was necesaaray afterall
 358  0
             }
 359  0
         }
 360  0
     }
 361  0
 
 362  
     /**
 363  0
      * Setup proxy access if we have to.
 364  
      *
 365  0
      * @param client  the HttpClient
 366  
      */
 367  0
     private void determineProxy( HttpClient client )
 368  0
     {
 369  0
         // see whether there is any proxy defined in maven
 370  0
         Proxy proxy = null;
 371  0
 
 372  0
         String proxyHost = null;
 373  0
 
 374  0
         int proxyPort = 0;
 375  0
 
 376  0
         String proxyUser = null;
 377  0
 
 378  0
         String proxyPass = null;
 379  0
 
 380  0
         if ( project == null )
 381  0
         {
 382  0
             getLog().error( "No project set. No proxy info available." );
 383  0
 
 384  0
             return;
 385  0
         }
 386  0
 
 387  0
         if ( settings != null )
 388  0
         {
 389  0
             proxy = settings.getActiveProxy();
 390  0
         }
 391  0
 
 392  0
         if ( proxy != null )
 393  0
         {
 394  0
             proxyHost = settings.getActiveProxy().getHost();
 395  0
 
 396  0
             proxyPort = settings.getActiveProxy().getPort();
 397  0
 
 398  0
             proxyUser = settings.getActiveProxy().getUsername();
 399  0
 
 400  0
             proxyPass = settings.getActiveProxy().getPassword();
 401  0
 
 402  0
             getLog().info( proxyPass );
 403  0
         }
 404  0
 
 405  0
         if ( proxyHost != null )
 406  0
         {
 407  0
             client.getHostConfiguration().setProxy( proxyHost, proxyPort );
 408  0
 
 409  0
             getLog().info( "Using proxy: " + proxyHost + " at port " + proxyPort );
 410  0
 
 411  0
             if ( proxyUser != null )
 412  0
             {
 413  0
                 getLog().info( "Using proxy user: " + proxyUser );
 414  0
 
 415  0
                 client.getState().setProxyCredentials( null, null,
 416  0
                                                        new UsernamePasswordCredentials( proxyUser, proxyPass ) );
 417  0
             }
 418  0
         }
 419  0
     }
 420  0
 
 421  
     /**
 422  0
      * Downloads the given link using the configured HttpClient, possibly following redirects.
 423  
      *
 424  0
      * @param cl     the HttpClient
 425  0
      * @param link   the JiraUrl
 426  0
      * @return
 427  0
      */
 428  0
     private void download( final HttpClient cl, final String link )
 429  0
     {
 430  0
         try
 431  0
         {
 432  0
             GetMethod gm = new GetMethod( link );
 433  0
 
 434  0
             getLog().info( "Downloading " + link );
 435  0
 
 436  0
             gm.setFollowRedirects( true );
 437  0
 
 438  0
             cl.executeMethod( gm );
 439  0
 
 440  0
             final String strGetResponseBody = gm.getResponseBodyAsString();
 441  0
 
 442  0
             // write the reponse to file
 443  0
             PrintWriter pw = new PrintWriter( new FileWriter( output ) );
 444  0
 
 445  0
             pw.print( strGetResponseBody );
 446  0
 
 447  0
             pw.close();
 448  0
 
 449  0
             StatusLine sl = gm.getStatusLine();
 450  0
 
 451  0
             if ( sl == null )
 452  0
             {
 453  0
                 getLog().info( "Unknown error validating link : " + link );
 454  0
 
 455  0
                 return;
 456  0
             }
 457  0
 
 458  0
             // if we get a redirect, do so
 459  0
             if ( gm.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY )
 460  0
             {
 461  0
                 Header locationHeader = gm.getResponseHeader( "Location" );
 462  0
 
 463  0
                 if ( locationHeader == null )
 464  0
                 {
 465  0
                     getLog().info( "Site sent redirect, but did not set Location header" );
 466  0
                 }
 467  0
                 else
 468  0
                 {
 469  0
                     String newLink = locationHeader.getValue();
 470  0
 
 471  0
                     getLog().debug( "Following redirect to " + newLink );
 472  0
 
 473  0
                     download( cl, newLink );
 474  
                 }
 475  0
             }
 476  0
 
 477  0
             if ( gm.getStatusCode() != HttpStatus.SC_OK )
 478  0
             {
 479  0
                 getLog().warn( "Received: [" + gm.getStatusCode() + "]" );
 480  0
             }
 481  0
         }
 482  0
         catch ( HttpException e )
 483  0
         {
 484  0
             if ( getLog().isDebugEnabled() )
 485  0
             {
 486  0
                 getLog().error( "Error downloading issues from JIRA:", e );
 487  0
             }
 488  0
             else
 489  0
             {
 490  0
                 getLog().error( "Error downloading issues from JIRA url :  " + e.getLocalizedMessage() );
 491  0
 
 492  0
             }
 493  0
         }
 494  0
         catch ( IOException e )
 495  0
         {
 496  0
             if ( getLog().isDebugEnabled() )
 497  0
             {
 498  0
                 getLog().error( "Error downloading issues from JIRA :", e );
 499  0
             }
 500  0
             else
 501  0
             {
 502  0
                 getLog().error( "Error downloading issues from JIRA. Cause is " + e.getLocalizedMessage() );
 503  0
             }
 504  0
         }
 505  0
     }
 506  
 
 507  0
     /**
 508  0
      * Set the output file for the log.
 509  0
      *
 510  
      * @param thisOutput the output file
 511  0
      */
 512  0
     public void setOutput( File thisOutput )
 513  0
     {
 514  0
         this.output = thisOutput;
 515  0
     }
 516  
 
 517  0
     /**
 518  0
      * Sets the project.
 519  0
      *
 520  
      * @param thisProject  The project to set
 521  0
      */
 522  0
     public void setMavenProject( Object thisProject )
 523  0
     {
 524  0
         this.project = (MavenProject) thisProject;
 525  0
     }
 526  0
 
 527  0
     /**
 528  0
      * Sets the maximum number of Issues to show.
 529  
      *
 530  0
      * @param nbEntries  The maximum number of Issues
 531  
      */
 532  0
     public void setNbEntries( final int nbEntries )
 533  0
     {
 534  0
         nbEntriesMax = nbEntries;
 535  0
     }
 536  0
 
 537  0
     /**
 538  0
      * Sets the statusIds.
 539  
      *
 540  0
      * @param thisStatusIds   The id(s) of the status to show, as comma separated string
 541  
      */
 542  0
     public void setStatusIds( String thisStatusIds )
 543  0
     {
 544  0
         statusIds = thisStatusIds;
 545  0
     }
 546  0
 
 547  0
     /**
 548  0
      * Sets the priorityIds.
 549  0
      *
 550  0
      * @param thisPriorityIds  The id(s) of the priority to show, as comma separated string
 551  0
      */
 552  0
     public void setPriorityIds( String thisPriorityIds )
 553  0
     {
 554  0
         priorityIds = thisPriorityIds;
 555  0
     }
 556  
 
 557  0
     /**
 558  0
      * Sets the resolutionIds.
 559  0
      *
 560  0
      * @param thisResolutionIds  The id(s) of the resolution to show, as comma separated string
 561  0
      */
 562  0
     public void setResolutionIds( String thisResolutionIds )
 563  0
     {
 564  0
         resolutionIds = thisResolutionIds;
 565  0
     }
 566  
 
 567  0
     /**
 568  0
      * Sets the password for authentication against the webserver.
 569  0
      *
 570  0
      * @param thisWebPassword  The password of the webserver
 571  0
      */
 572  0
     public void setWebPassword( String thisWebPassword )
 573  0
     {
 574  0
         this.webPassword = thisWebPassword;
 575  0
     }
 576  
 
 577  0
     /**
 578  0
      * Sets the username for authentication against the webserver.
 579  0
      *
 580  0
      * @param thisWebUser   The username of the webserver
 581  0
      */
 582  0
     public void setWebUser( String thisWebUser )
 583  0
     {
 584  0
         this.webUser = thisWebUser;
 585  0
     }
 586  
 
 587  0
     /**
 588  0
      * Sets the password to log into a secured JIRA.
 589  0
      *
 590  0
      * @param thisJiraPassword  The password for JIRA
 591  0
      */
 592  0
     public void setJiraPassword( final String thisJiraPassword )
 593  0
     {
 594  0
         this.jiraPassword = thisJiraPassword;
 595  0
     }
 596  
 
 597  0
     /**
 598  0
      * Sets the username to log into a secured JIRA.
 599  0
      *
 600  0
      * @param thisJiraUser  The username for JIRA
 601  0
      */
 602  0
     public void setJiraUser( String thisJiraUser )
 603  0
     {
 604  0
         this.jiraUser = thisJiraUser;
 605  0
     }
 606  
 
 607  0
     /**
 608  0
      * Sets the filter to apply to query to JIRA.
 609  0
      *
 610  0
      * @param thisFilter  The filter to query JIRA
 611  0
      */
 612  0
     public void setFilter( String thisFilter )
 613  0
     {
 614  0
         this.filter = thisFilter;
 615  0
     }
 616  
 
 617  0
     /**
 618  0
      * Sets the component(s) to apply to query JIRA.
 619  0
      *
 620  0
      * @param theseComponents   The id(s) of components to show, as comma separated string
 621  0
      */
 622  0
     public void setComponent( String theseComponents )
 623  0
     {
 624  0
         this.component = theseComponents;
 625  0
     }
 626  
 
 627  0
     public void setLog( Log log )
 628  0
     {
 629  0
         this.log = log;
 630  0
     }
 631  0
 
 632  0
     private org.apache.maven.plugin.logging.Log getLog()
 633  0
     {
 634  0
         return log;
 635  
     }
 636  
 
 637  0
     public void setSettings( Settings settings )
 638  0
     {
 639  0
         this.settings = settings;
 640  0
     }
 641  0
 }