Coverage Report - org.apache.maven.plugin.jira.AbstractJiraDownloader
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractJiraDownloader
0%
0/266
0%
0/148
3,759
 
 1  
 package org.apache.maven.plugin.jira;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.commons.httpclient.Credentials;
 23  
 import org.apache.commons.httpclient.Header;
 24  
 import org.apache.commons.httpclient.HostConfiguration;
 25  
 import org.apache.commons.httpclient.HttpClient;
 26  
 import org.apache.commons.httpclient.HttpException;
 27  
 import org.apache.commons.httpclient.HttpState;
 28  
 import org.apache.commons.httpclient.HttpStatus;
 29  
 import org.apache.commons.httpclient.StatusLine;
 30  
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 31  
 import org.apache.commons.httpclient.params.HttpClientParams;
 32  
 import org.apache.commons.httpclient.auth.AuthScope;
 33  
 import org.apache.commons.httpclient.methods.GetMethod;
 34  
 import org.apache.maven.plugin.logging.Log;
 35  
 import org.apache.maven.project.MavenProject;
 36  
 import org.apache.maven.settings.Proxy;
 37  
 import org.apache.maven.settings.Settings;
 38  
 import org.codehaus.plexus.util.StringUtils;
 39  
 
 40  
 import java.io.File;
 41  
 import java.io.FileWriter;
 42  
 import java.io.IOException;
 43  
 import java.io.PrintWriter;
 44  
 import java.util.HashMap;
 45  
 import java.util.Locale;
 46  
 import java.util.Map;
 47  
 
 48  
 /**
 49  
  * Gets relevant issues in RSS from a given JIRA installation.
 50  
  * <p/>
 51  
  * Based on version 1.1.2 and patch by Dr. Spock (MPJIRA-8).
 52  
  *
 53  
  * @author mfranken@xebia.com
 54  
  * @author jruiz@exist.com
 55  
  * @version $Id: org.apache.maven.plugin.jira.AbstractJiraDownloader.html 816595 2012-05-08 12:43:00Z hboutemy $
 56  
  */
 57  0
 public abstract class AbstractJiraDownloader
 58  
 {
 59  
     /** Log for debug output. */
 60  
     private Log log;
 61  
     /** Output file for xml document. */
 62  
     private File output;
 63  
     /** The maximum number of entries to show. */
 64  
     private int nbEntriesMax;
 65  
     /** The filter to apply to query to JIRA. */
 66  
     private String filter;
 67  
     /** Ids of fix versions to show, as comma separated string. */
 68  
     private String fixVersionIds;
 69  
     /** Ids of status to show, as comma separated string. */
 70  
     private String statusIds;
 71  
     /** Ids of resolution to show, as comma separated string. */
 72  
     private String resolutionIds;
 73  
     /** Ids of priority to show, as comma separated string. */
 74  
     private String priorityIds;
 75  
     /** The component to show. */
 76  
     private String component;
 77  
     /** Ids of types to show, as comma separated string. */
 78  
     private String typeIds;
 79  
     /** Column names to sort by, as comma separated string. */
 80  
     private String sortColumnNames;
 81  
     /** The username to log into JIRA. */
 82  
     private String jiraUser;
 83  
     /** The password to log into JIRA. */
 84  
     private String jiraPassword;
 85  
     /** The username to log into webserver. */
 86  
     private String webUser;
 87  
     /** The password to log into webserver. */
 88  
     private String webPassword;
 89  
     /** The maven project. */
 90  
     private MavenProject project;
 91  
     /** The maven settings. */
 92  
     private Settings settings;
 93  
     /** Mapping containing all allowed JIRA status values. */
 94  0
     protected Map statusMap = new HashMap();
 95  
     /** Mapping containing all allowed JIRA resolution values. */
 96  0
     protected Map resolutionMap = new HashMap();
 97  
     /** Mapping containing all allowed JIRA priority values. */
 98  0
     protected Map priorityMap = new HashMap();
 99  
     /** Mapping containing all allowed JIRA type values. */
 100  0
     protected Map typeMap = new HashMap();
 101  
 
 102  
     /**
 103  
      * Creates a filter given the parameters and some defaults.
 104  
      *
 105  
      * @return request parameters to be added to URL used for downloading the JIRA issues
 106  
      */
 107  
     private String createFilter()
 108  
     {
 109  
         // If the user has defined a filter - use that
 110  0
         if ( ( this.filter != null ) && ( this.filter.length() > 0 ) )
 111  
         {
 112  0
             return this.filter;
 113  
         }
 114  
 
 115  0
         StringBuffer localFilter = new StringBuffer();
 116  
 
 117  
         // add fix versions
 118  0
         if ( fixVersionIds != null )
 119  
         {
 120  0
             String[] fixVersions = fixVersionIds.split( "," );
 121  
 
 122  0
             for ( int i = 0; i < fixVersions.length; i++ )
 123  
             {
 124  0
                 if ( fixVersions[i].length() > 0 )
 125  
                 {
 126  0
                     localFilter.append( "&fixfor=" + fixVersions[i].trim() );
 127  
                 }
 128  
             }
 129  
         }
 130  
 
 131  
         // get the Status Ids
 132  0
         if ( statusIds != null )
 133  
         {
 134  0
             String[] stats = statusIds.split( "," );
 135  
 
 136  0
             for ( int i = 0; i < stats.length; i++ )
 137  
             {
 138  0
                 String statusParam = (String) statusMap.get( stats[i] );
 139  
 
 140  0
                 if ( statusParam != null )
 141  
                 {
 142  0
                     localFilter.append( "&statusIds=" + statusParam );
 143  
                 }
 144  
             }
 145  
         }
 146  
 
 147  
         // get the Priority Ids
 148  0
         if ( priorityIds != null )
 149  
         {
 150  0
             String[] prios = priorityIds.split( "," );
 151  
 
 152  0
             for ( int i = 0; i < prios.length; i++ )
 153  
             {
 154  0
                 String priorityParam = (String) priorityMap.get( prios[i] );
 155  
 
 156  0
                 if ( priorityParam != null )
 157  
                 {
 158  0
                     localFilter.append( "&priorityIds=" + priorityParam );
 159  
                 }
 160  
             }
 161  
         }
 162  
 
 163  
         // get the Resolution Ids
 164  0
         if ( resolutionIds != null )
 165  
         {
 166  0
             String[] resos = resolutionIds.split( "," );
 167  
 
 168  0
             for ( int i = 0; i < resos.length; i++ )
 169  
             {
 170  0
                 String resoParam = (String) resolutionMap.get( resos[i] );
 171  
 
 172  0
                 if ( resoParam != null )
 173  
                 {
 174  0
                     localFilter.append( "&resolutionIds=" + resoParam );
 175  
                 }
 176  
             }
 177  
         }
 178  
 
 179  
         // add components
 180  0
         if ( component != null )
 181  
         {
 182  0
             String[] components = component.split( "," );
 183  
 
 184  0
             for ( int i = 0; i < components.length; i++ )
 185  
             {
 186  0
                 if ( components[i].length() > 0 )
 187  
                 {
 188  0
                     localFilter.append( "&component=" + components[i] );
 189  
                 }
 190  
             }
 191  
         }
 192  
 
 193  
         // get the Type Ids
 194  0
         if ( typeIds != null )
 195  
         {
 196  0
             String[] types = typeIds.split( "," );
 197  
 
 198  0
             for ( int i = 0; i < types.length; i++ )
 199  
             {
 200  0
                 String typeParam = (String) typeMap.get( types[i].trim() );
 201  
 
 202  0
                 if ( typeParam != null )
 203  
                 {
 204  0
                     localFilter.append( "&type=" + typeParam );
 205  
                 }
 206  
             }
 207  
         }
 208  
 
 209  
         // get the Sort order
 210  0
         int validSortColumnNames = 0;
 211  0
         if ( sortColumnNames != null )
 212  
         {
 213  0
             String[] sortColumnNamesArray = sortColumnNames.split( "," );
 214  
             // N.B. Add in reverse order (it's the way JIRA likes it!!)
 215  0
             for ( int i = sortColumnNamesArray.length - 1; i >= 0; i-- )
 216  
             {
 217  0
                 String lowerColumnName = sortColumnNamesArray[i].trim().toLowerCase( Locale.ENGLISH );
 218  0
                 boolean descending = false;
 219  0
                 String fieldName = null;
 220  0
                 if ( lowerColumnName.endsWith( "desc" ) )
 221  
                 {
 222  0
                     descending = true;
 223  0
                     lowerColumnName = lowerColumnName.substring( 0, lowerColumnName.length() - 4 ).trim();
 224  
                 }
 225  0
                 else if ( lowerColumnName.endsWith( "asc" ) )
 226  
                 {
 227  0
                     descending = false;
 228  0
                     lowerColumnName = lowerColumnName.substring( 0, lowerColumnName.length() - 3 ).trim();
 229  
                 }
 230  
 
 231  0
                 if ( "key".equals( lowerColumnName ) )
 232  
                 {
 233  0
                     fieldName = "issuekey";
 234  
                 }
 235  0
                 else if ( "summary".equals( lowerColumnName ) )
 236  
                 {
 237  0
                     fieldName = lowerColumnName;
 238  
                 }
 239  0
                 else if ( "status".equals( lowerColumnName ) )
 240  
                 {
 241  0
                     fieldName = lowerColumnName;
 242  
                 }
 243  0
                 else if ( "resolution".equals( lowerColumnName ) )
 244  
                 {
 245  0
                     fieldName = lowerColumnName;
 246  
                 }
 247  0
                 else if ( "assignee".equals( lowerColumnName ) )
 248  
                 {
 249  0
                     fieldName = lowerColumnName;
 250  
                 }
 251  0
                 else if ( "reporter".equals( lowerColumnName ) )
 252  
                 {
 253  0
                     fieldName = lowerColumnName;
 254  
                 }
 255  0
                 else if ( "type".equals( lowerColumnName ) )
 256  
                 {
 257  0
                     fieldName = "issuetype";
 258  
                 }
 259  0
                 else if ( "priority".equals( lowerColumnName ) )
 260  
                 {
 261  0
                     fieldName = lowerColumnName;
 262  
                 }
 263  0
                 else if ( "version".equals( lowerColumnName ) )
 264  
                 {
 265  0
                     fieldName = "versions";
 266  
                 }
 267  0
                 else if ( "fix version".equals( lowerColumnName ) )
 268  
                 {
 269  0
                     fieldName = "fixVersions";
 270  
                 }
 271  0
                 else if ( "component".equals( lowerColumnName ) )
 272  
                 {
 273  0
                     fieldName = "components";
 274  
                 }
 275  0
                 else if ( "created".equals( lowerColumnName ) )
 276  
                 {
 277  0
                     fieldName = lowerColumnName;
 278  
                 }
 279  0
                 else if ( "updated".equals( lowerColumnName ) )
 280  
                 {
 281  0
                     fieldName = lowerColumnName;
 282  
                 }
 283  0
                 if ( fieldName != null )
 284  
                 {
 285  0
                     localFilter.append( "&sorter/field=" );
 286  0
                     localFilter.append( fieldName );
 287  0
                     localFilter.append( "&sorter/order=" );
 288  0
                     localFilter.append( descending ? "DESC" : "ASC" );
 289  0
                     validSortColumnNames++;
 290  
                 }
 291  
                 else
 292  
                 {
 293  
                     // Error in the configuration
 294  0
                     getLog().error(
 295  
                         "maven-changes-plugin: The configured value '" + lowerColumnName
 296  
                             + "' for sortColumnNames is not correct." );
 297  
                 }
 298  
             }
 299  
         }
 300  0
         if ( validSortColumnNames == 0 )
 301  
         {
 302  
             // Error in the configuration
 303  0
             getLog().error(
 304  
                 "maven-changes-plugin: None of the configured sortColumnNames '" + sortColumnNames + "' are correct." );
 305  
         }
 306  
 
 307  
 
 308  0
         return localFilter.toString();
 309  
     }
 310  
 
 311  
     /**
 312  
      * Execute the query on the JIRA server.
 313  
      *
 314  
      * @throws Exception on error
 315  
      */
 316  
     public void doExecute()
 317  
         throws Exception
 318  
     {
 319  
         try
 320  
         {
 321  0
             HttpClient client = new HttpClient();
 322  
 
 323  
             // MCHANGES-89 Allow circular redirects
 324  0
             HttpClientParams clientParams = client.getParams();
 325  0
             clientParams.setBooleanParameter( HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true );
 326  
 
 327  0
             HttpState state = new HttpState();
 328  
 
 329  0
             HostConfiguration hc = new HostConfiguration();
 330  
 
 331  0
             client.setHostConfiguration( hc );
 332  
 
 333  0
             client.setState( state );
 334  
 
 335  0
             determineProxy( client );
 336  
 
 337  0
             Map urlMap = getJiraUrlAndIssueId();
 338  
 
 339  0
             String jiraUrl = (String) urlMap.get( "url" );
 340  
 
 341  0
             String jiraId = (String) urlMap.get( "id" );
 342  
 
 343  0
             prepareBasicAuthentication( client );
 344  
 
 345  0
             boolean jiraAuthenticationSuccessful = false;
 346  0
             if ( isJiraAuthenticationConfigured() )
 347  
             {
 348  0
                 jiraAuthenticationSuccessful = doJiraAuthentication( client, jiraUrl );
 349  
             }
 350  
 
 351  0
             if ( ( isJiraAuthenticationConfigured() && jiraAuthenticationSuccessful )
 352  
                 || !isJiraAuthenticationConfigured() )
 353  
             {
 354  0
                 if ( jiraId == null || jiraId.length() == 0 )
 355  
                 {
 356  0
                     log.debug( "The JIRA URL " + project.getIssueManagement().getUrl()
 357  
                         + " doesn't include a pid, trying to extract it from JIRA." );
 358  0
                     jiraId = JiraHelper.getPidFromJira( log, project.getIssueManagement().getUrl(), client );
 359  
                 }
 360  
 
 361  0
                 if ( jiraId == null )
 362  
                 {
 363  0
                     getLog().error( "The issue management URL in the POM does not include a pid,"
 364  
                         + " and it was not possible to extract it from the page at that URL." );
 365  
                 }
 366  
                 else
 367  
                 {
 368  
                     // create the URL for getting the proper issues from JIRA
 369  0
                     String fullURL = jiraUrl + "/secure/IssueNavigator.jspa?view=rss&pid=" + jiraId;
 370  
 
 371  0
                     if ( getFixFor() != null )
 372  
                     {
 373  0
                         fullURL += "&fixfor=" + getFixFor();
 374  
                     }
 375  
 
 376  0
                     String createdFilter = createFilter();
 377  0
                     if ( createdFilter.charAt( 0 ) != '&' )
 378  
                     {
 379  0
                         fullURL += "&";
 380  
                     }
 381  0
                     fullURL += createdFilter;
 382  
 
 383  0
                     fullURL += ( "&tempMax=" + nbEntriesMax + "&reset=true&decorator=none" );
 384  
 
 385  0
                     if ( log.isDebugEnabled() )
 386  
                     {
 387  0
                         log.debug( "download jira issues from url " + fullURL );
 388  
                     }
 389  
 
 390  
                     // execute the GET
 391  0
                     download( client, fullURL );
 392  
                 }
 393  
             }
 394  
         }
 395  0
         catch ( Exception e )
 396  
         {
 397  0
             getLog().error( "Error accessing " + project.getIssueManagement().getUrl(), e );
 398  0
         }
 399  0
     }
 400  
 
 401  
     /**
 402  
      * Override this method if you need to get issues for a specific Fix For.
 403  
      *
 404  
      * @return A Fix For id or <code>null</code> if you don't have that need
 405  
      */
 406  
     protected String getFixFor()
 407  
     {
 408  0
         return null;
 409  
     }
 410  
 
 411  
     /**
 412  
      * Parse out the base URL for JIRA and the JIRA project id from the issue
 413  
      * management section of the POM.
 414  
      *
 415  
      * @return A <code>Map</code> containing the URL and project id
 416  
      */
 417  
     private Map getJiraUrlAndIssueId()
 418  
     {
 419  0
         HashMap urlMap = new HashMap();
 420  
 
 421  0
         String url = project.getIssueManagement().getUrl();
 422  
 
 423  
         // chop off the parameter part
 424  0
         int pos = url.indexOf( "?" );
 425  
 
 426  
         // and get the id while we're at it
 427  0
         String id = "";
 428  
 
 429  0
         if ( pos >= 0 )
 430  
         {
 431  
             // project id
 432  0
             id = url.substring( url.lastIndexOf( "=" ) + 1 );
 433  
         }
 434  
 
 435  0
         String jiraUrl = url.substring( 0, url.lastIndexOf( "/" ) );
 436  
 
 437  0
         if ( jiraUrl.endsWith( "secure" ) || jiraUrl.endsWith( "browse" ) )
 438  
         {
 439  0
             jiraUrl = jiraUrl.substring( 0, jiraUrl.lastIndexOf( "/" ) );
 440  
         }
 441  0
         getLog().debug( "JIRA lives at: " + jiraUrl );
 442  
 
 443  0
         urlMap.put( "url", jiraUrl );
 444  
 
 445  0
         urlMap.put( "id", id );
 446  
 
 447  0
         return urlMap;
 448  
     }
 449  
 
 450  
     /**
 451  
      * Check and prepare for basic authentication.
 452  
      *
 453  
      * @param client The client to prepare
 454  
      */
 455  
     private void prepareBasicAuthentication( HttpClient client )
 456  
     {
 457  0
         if ( ( webUser != null ) && ( webUser.length() > 0 ) )
 458  
         {
 459  0
             client.getParams().setAuthenticationPreemptive( true );
 460  
 
 461  0
             Credentials defaultcreds = new UsernamePasswordCredentials( webUser, webPassword );
 462  
 
 463  0
             getLog().debug( "Using username: " + webUser + " for Basic Authentication." );
 464  
 
 465  0
             client.getState().setCredentials( new AuthScope( null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME ),
 466  
                                               defaultcreds );
 467  
         }
 468  0
     }
 469  
 
 470  
     /**
 471  
      * Authenticate against JIRA. This method relies on jiraUser and
 472  
      * jiraPassword being set. You can check this by calling
 473  
      * isJiraAuthenticationConfigured().
 474  
      *
 475  
      * @param client    the HttpClient
 476  
      * @param jiraUrl   the JIRA installation
 477  
      * @return <code>true</code> if the authentication was successful, otherwise <code>false</code>
 478  
      */
 479  
     private boolean doJiraAuthentication( HttpClient client, final String jiraUrl )
 480  
     {
 481  
         // log into JIRA if we have to
 482  0
         String loginUrl = null;
 483  
 
 484  0
         StringBuffer loginLink = new StringBuffer( jiraUrl );
 485  
 
 486  0
         loginLink.append( "/login.jsp?os_destination=/secure/" );
 487  
 
 488  0
         loginLink.append( "&os_username=" ).append( jiraUser );
 489  
 
 490  0
         String password = null;
 491  0
         if ( jiraPassword != null )
 492  
         {
 493  0
             password = StringUtils.repeat( "*", jiraPassword.length() );
 494  
         }
 495  0
         getLog().debug( "Login URL: " + loginLink + "&os_password=" + password );
 496  
 
 497  0
         loginLink.append( "&os_password=" ).append( jiraPassword );
 498  
 
 499  0
         loginUrl = loginLink.toString();
 500  
 
 501  
         // execute the login
 502  0
         GetMethod loginGet = new GetMethod( loginUrl );
 503  
 
 504  
         try
 505  
         {
 506  0
             client.executeMethod( loginGet );
 507  
 
 508  0
             if ( loginSucceeded( loginGet ) )
 509  
             {
 510  0
                 getLog().debug( "Successfully logged in into JIRA." );
 511  0
                 return true;
 512  
             }
 513  
             else
 514  
             {
 515  0
                 getLog().warn( "Was unable to login into JIRA: wrong username and/or password." );
 516  
             }
 517  
         }
 518  0
         catch ( Exception e )
 519  
         {
 520  0
             if ( getLog().isDebugEnabled() )
 521  
             {
 522  0
                 getLog().error( "Error trying to login into JIRA.", e );
 523  
             }
 524  
             else
 525  
             {
 526  0
                 getLog().error( "Error trying to login into JIRA. Cause is: " + e.getLocalizedMessage() );
 527  
             }
 528  0
         }
 529  0
         return false;
 530  
     }
 531  
 
 532  
     /**
 533  
      * Check to see if we think that JIRA authentication is needed.
 534  
      *
 535  
      * @return <code>true</code> if jiraUser and jiraPassword are set, otherwise <code>false</code>
 536  
      */
 537  
     private boolean isJiraAuthenticationConfigured()
 538  
     {
 539  0
         return ( jiraUser != null ) && ( jiraUser.length() > 0 ) && ( jiraPassword != null );
 540  
     }
 541  
 
 542  
     /**
 543  
      * Evaluate if the login attempt to JIRA was successful or not. We can't
 544  
      * use the status code because JIRA returns 200 even if the login fails.
 545  
      *
 546  
      * @param loginGet The method that was executed
 547  
      * @return <code>false</code> if we find an error message in the response body, otherwise <code>true</code>
 548  
      * @todo There must be a nicer way to know whether we were able to login or not
 549  
      */
 550  
     private boolean loginSucceeded( GetMethod loginGet )
 551  
         throws IOException
 552  
     {
 553  0
         final String loginFailureResponse = "your username and password are incorrect";
 554  
 
 555  0
         return loginGet.getResponseBodyAsString().indexOf( loginFailureResponse ) == -1;
 556  
     }
 557  
 
 558  
     /**
 559  
      * Setup proxy access if we have to.
 560  
      *
 561  
      * @param client  the HttpClient
 562  
      */
 563  
     private void determineProxy( HttpClient client )
 564  
     {
 565  
         // see whether there is any proxy defined in maven
 566  0
         Proxy proxy = null;
 567  
 
 568  0
         String proxyHost = null;
 569  
 
 570  0
         int proxyPort = 0;
 571  
 
 572  0
         String proxyUser = null;
 573  
 
 574  0
         String proxyPass = null;
 575  
 
 576  0
         if ( project == null )
 577  
         {
 578  0
             getLog().error( "No project set. No proxy info available." );
 579  
 
 580  0
             return;
 581  
         }
 582  
 
 583  0
         if ( settings != null )
 584  
         {
 585  0
             proxy = settings.getActiveProxy();
 586  
         }
 587  
 
 588  0
         if ( proxy != null )
 589  
         {
 590  0
             proxyHost = settings.getActiveProxy().getHost();
 591  
 
 592  0
             proxyPort = settings.getActiveProxy().getPort();
 593  
 
 594  0
             proxyUser = settings.getActiveProxy().getUsername();
 595  
 
 596  0
             proxyPass = settings.getActiveProxy().getPassword();
 597  
 
 598  0
             getLog().debug( proxyPass );
 599  
         }
 600  
 
 601  0
         if ( proxyHost != null )
 602  
         {
 603  0
             client.getHostConfiguration().setProxy( proxyHost, proxyPort );
 604  
 
 605  0
             getLog().debug( "Using proxy: " + proxyHost + " at port " + proxyPort );
 606  
 
 607  0
             if ( proxyUser != null )
 608  
             {
 609  0
                 getLog().debug( "Using proxy user: " + proxyUser );
 610  
 
 611  0
                 client.getState().setProxyCredentials(
 612  
                                                        new AuthScope( null, AuthScope.ANY_PORT, null,
 613  
                                                                       AuthScope.ANY_SCHEME ),
 614  
                                                        new UsernamePasswordCredentials( proxyUser, proxyPass ) );
 615  
             }
 616  
         }
 617  0
     }
 618  
 
 619  
     /**
 620  
      * Downloads the given link using the configured HttpClient, possibly following redirects.
 621  
      *
 622  
      * @param cl     the HttpClient
 623  
      * @param link   the URL to JIRA
 624  
      */
 625  
     private void download( final HttpClient cl, final String link )
 626  
     {
 627  
         try
 628  
         {
 629  0
             GetMethod gm = new GetMethod( link );
 630  
 
 631  0
             getLog().info( "Downloading from JIRA at: " + link );
 632  
 
 633  0
             gm.setFollowRedirects( true );
 634  
 
 635  0
             cl.executeMethod( gm );
 636  
 
 637  0
             StatusLine sl = gm.getStatusLine();
 638  
 
 639  0
             if ( sl == null )
 640  
             {
 641  0
                 getLog().error( "Unknown error validating link: " + link );
 642  
 
 643  0
                 return;
 644  
             }
 645  
 
 646  
             // if we get a redirect, do so
 647  0
             if ( gm.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY )
 648  
             {
 649  0
                 Header locationHeader = gm.getResponseHeader( "Location" );
 650  
 
 651  0
                 if ( locationHeader == null )
 652  
                 {
 653  0
                     getLog().warn( "Site sent redirect, but did not set Location header" );
 654  
                 }
 655  
                 else
 656  
                 {
 657  0
                     String newLink = locationHeader.getValue();
 658  
 
 659  0
                     getLog().debug( "Following redirect to " + newLink );
 660  
 
 661  0
                     download( cl, newLink );
 662  
                 }
 663  
             }
 664  
 
 665  0
             if ( gm.getStatusCode() == HttpStatus.SC_OK )
 666  
             {
 667  0
                 final String strGetResponseBody = gm.getResponseBodyAsString();
 668  
 
 669  0
                 if ( !output.getParentFile().exists() )
 670  
                 {
 671  0
                     output.getParentFile().mkdirs();
 672  
                 }
 673  
 
 674  
                 // write the reponse to file
 675  0
                 PrintWriter pw = new PrintWriter( new FileWriter( output ) );
 676  
 
 677  0
                 pw.print( strGetResponseBody );
 678  
 
 679  0
                 pw.close();
 680  
 
 681  0
                 getLog().debug( "Downloading from JIRA was successful" );
 682  0
             }
 683  
             else
 684  
             {
 685  0
                 getLog().warn( "Downloading from JIRA failed. Received: [" + gm.getStatusCode() + "]" );
 686  
             }
 687  
         }
 688  0
         catch ( HttpException e )
 689  
         {
 690  0
             if ( getLog().isDebugEnabled() )
 691  
             {
 692  0
                 getLog().error( "Error downloading issues from JIRA:", e );
 693  
             }
 694  
             else
 695  
             {
 696  0
                 getLog().error( "Error downloading issues from JIRA url: " + e.getLocalizedMessage() );
 697  
 
 698  
             }
 699  
         }
 700  0
         catch ( IOException e )
 701  
         {
 702  0
             if ( getLog().isDebugEnabled() )
 703  
             {
 704  0
                 getLog().error( "Error downloading issues from JIRA:", e );
 705  
             }
 706  
             else
 707  
             {
 708  0
                 getLog().error( "Error downloading issues from JIRA. Cause is " + e.getLocalizedMessage() );
 709  
             }
 710  0
         }
 711  0
     }
 712  
 
 713  
     /**
 714  
      * Set the output file for the log.
 715  
      *
 716  
      * @param thisOutput the output file
 717  
      */
 718  
     public void setOutput( File thisOutput )
 719  
     {
 720  0
         this.output = thisOutput;
 721  0
     }
 722  
 
 723  
     public File getOutput()
 724  
     {
 725  0
         return this.output;
 726  
     }
 727  
 
 728  
     /**
 729  
      * Sets the project.
 730  
      *
 731  
      * @param thisProject  The project to set
 732  
      */
 733  
     public void setMavenProject( Object thisProject )
 734  
     {
 735  0
         this.project = (MavenProject) thisProject;
 736  0
     }
 737  
 
 738  
     /**
 739  
      * Sets the maximum number of Issues to show.
 740  
      *
 741  
      * @param nbEntries  The maximum number of Issues
 742  
      */
 743  
     public void setNbEntries( final int nbEntries )
 744  
     {
 745  0
         nbEntriesMax = nbEntries;
 746  0
     }
 747  
 
 748  
     /**
 749  
      * Sets the statusIds.
 750  
      *
 751  
      * @param thisStatusIds   The id(s) of the status to show, as comma separated string
 752  
      */
 753  
     public void setStatusIds( String thisStatusIds )
 754  
     {
 755  0
         statusIds = thisStatusIds;
 756  0
     }
 757  
 
 758  
     /**
 759  
      * Sets the priorityIds.
 760  
      *
 761  
      * @param thisPriorityIds  The id(s) of the priority to show, as comma separated string
 762  
      */
 763  
     public void setPriorityIds( String thisPriorityIds )
 764  
     {
 765  0
         priorityIds = thisPriorityIds;
 766  0
     }
 767  
 
 768  
     /**
 769  
      * Sets the resolutionIds.
 770  
      *
 771  
      * @param thisResolutionIds  The id(s) of the resolution to show, as comma separated string
 772  
      */
 773  
     public void setResolutionIds( String thisResolutionIds )
 774  
     {
 775  0
         resolutionIds = thisResolutionIds;
 776  0
     }
 777  
 
 778  
     /**
 779  
      * Sets the sort column names.
 780  
      *
 781  
      * @param thisSortColumnNames The column names to sort by
 782  
      */
 783  
     public void setSortColumnNames( String thisSortColumnNames )
 784  
     {
 785  0
         sortColumnNames = thisSortColumnNames;
 786  0
     }
 787  
 
 788  
     /**
 789  
      * Sets the password for authentication against the webserver.
 790  
      *
 791  
      * @param thisWebPassword  The password of the webserver
 792  
      */
 793  
     public void setWebPassword( String thisWebPassword )
 794  
     {
 795  0
         this.webPassword = thisWebPassword;
 796  0
     }
 797  
 
 798  
     /**
 799  
      * Sets the username for authentication against the webserver.
 800  
      *
 801  
      * @param thisWebUser   The username of the webserver
 802  
      */
 803  
     public void setWebUser( String thisWebUser )
 804  
     {
 805  0
         this.webUser = thisWebUser;
 806  0
     }
 807  
 
 808  
     /**
 809  
      * Sets the password to log into a secured JIRA.
 810  
      *
 811  
      * @param thisJiraPassword  The password for JIRA
 812  
      */
 813  
     public void setJiraPassword( final String thisJiraPassword )
 814  
     {
 815  0
         this.jiraPassword = thisJiraPassword;
 816  0
     }
 817  
 
 818  
     /**
 819  
      * Sets the username to log into a secured JIRA.
 820  
      *
 821  
      * @param thisJiraUser  The username for JIRA
 822  
      */
 823  
     public void setJiraUser( String thisJiraUser )
 824  
     {
 825  0
         this.jiraUser = thisJiraUser;
 826  0
     }
 827  
 
 828  
     /**
 829  
      * Sets the filter to apply to query to JIRA.
 830  
      *
 831  
      * @param thisFilter  The filter to query JIRA
 832  
      */
 833  
     public void setFilter( String thisFilter )
 834  
     {
 835  0
         this.filter = thisFilter;
 836  0
     }
 837  
 
 838  
     /**
 839  
      * Sets the component(s) to apply to query JIRA.
 840  
      *
 841  
      * @param theseComponents   The id(s) of components to show, as comma separated string
 842  
      */
 843  
     public void setComponent( String theseComponents )
 844  
     {
 845  0
         this.component = theseComponents;
 846  0
     }
 847  
 
 848  
     /**
 849  
      * Sets the fix version id(s) to apply to query JIRA.
 850  
      *
 851  
      * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
 852  
      */
 853  
     public void setFixVersionIds( String theseFixVersionIds )
 854  
     {
 855  0
         this.fixVersionIds = theseFixVersionIds;
 856  0
     }
 857  
 
 858  
     /**
 859  
      * Sets the typeIds.
 860  
      *
 861  
      * @param theseTypeIds  The id(s) of the types to show, as comma separated string
 862  
      */
 863  
     public void setTypeIds( String theseTypeIds )
 864  
     {
 865  0
         typeIds = theseTypeIds;
 866  0
     }
 867  
 
 868  
     public void setLog( Log log )
 869  
     {
 870  0
         this.log = log;
 871  0
     }
 872  
 
 873  
     private Log getLog()
 874  
     {
 875  0
         return log;
 876  
     }
 877  
 
 878  
     public void setSettings( Settings settings )
 879  
     {
 880  0
         this.settings = settings;
 881  0
     }
 882  
 }