Coverage Report - org.apache.maven.plugin.jira.AbstractJiraDownloader
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractJiraDownloader
0%
0/263
0%
0/146
3,414
 
 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 816584 2012-05-08 12:33:35Z 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  
                     // execute the GET
 386  0
                     download( client, fullURL );
 387  
                 }
 388  
             }
 389  
         }
 390  0
         catch ( Exception e )
 391  
         {
 392  0
             getLog().error( "Error accessing " + project.getIssueManagement().getUrl(), e );
 393  0
         }
 394  0
     }
 395  
 
 396  
     /**
 397  
      * Override this method if you need to get issues for a specific Fix For.
 398  
      *
 399  
      * @return A Fix For id or <code>null</code> if you don't have that need
 400  
      */
 401  
     protected String getFixFor()
 402  
     {
 403  0
         return null;
 404  
     }
 405  
 
 406  
     /**
 407  
      * Parse out the base URL for JIRA and the JIRA project id from the issue
 408  
      * management section of the POM.
 409  
      *
 410  
      * @return A <code>Map</code> containing the URL and project id
 411  
      */
 412  
     private Map getJiraUrlAndIssueId()
 413  
     {
 414  0
         HashMap urlMap = new HashMap();
 415  
 
 416  0
         String url = project.getIssueManagement().getUrl();
 417  
 
 418  
         // chop off the parameter part
 419  0
         int pos = url.indexOf( "?" );
 420  
 
 421  
         // and get the id while we're at it
 422  0
         String id = "";
 423  
 
 424  0
         if ( pos >= 0 )
 425  
         {
 426  
             // project id
 427  0
             id = url.substring( url.lastIndexOf( "=" ) + 1 );
 428  
         }
 429  
 
 430  0
         String jiraUrl = url.substring( 0, url.lastIndexOf( "/" ) );
 431  
 
 432  0
         if ( jiraUrl.endsWith( "secure" ) || jiraUrl.endsWith( "browse" ) )
 433  
         {
 434  0
             jiraUrl = jiraUrl.substring( 0, jiraUrl.lastIndexOf( "/" ) );
 435  
         }
 436  0
         getLog().debug( "JIRA lives at: " + jiraUrl );
 437  
 
 438  0
         urlMap.put( "url", jiraUrl );
 439  
 
 440  0
         urlMap.put( "id", id );
 441  
 
 442  0
         return urlMap;
 443  
     }
 444  
 
 445  
     /**
 446  
      * Check and prepare for basic authentication.
 447  
      *
 448  
      * @param client The client to prepare
 449  
      */
 450  
     private void prepareBasicAuthentication( HttpClient client )
 451  
     {
 452  0
         if ( ( webUser != null ) && ( webUser.length() > 0 ) )
 453  
         {
 454  0
             client.getParams().setAuthenticationPreemptive( true );
 455  
 
 456  0
             Credentials defaultcreds = new UsernamePasswordCredentials( webUser, webPassword );
 457  
 
 458  0
             getLog().debug( "Using username: " + webUser + " for Basic Authentication." );
 459  
 
 460  0
             client.getState().setCredentials( new AuthScope( null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME ),
 461  
                                               defaultcreds );
 462  
         }
 463  0
     }
 464  
 
 465  
     /**
 466  
      * Authenticate against JIRA. This method relies on jiraUser and
 467  
      * jiraPassword being set. You can check this by calling
 468  
      * isJiraAuthenticationConfigured().
 469  
      *
 470  
      * @param client    the HttpClient
 471  
      * @param jiraUrl   the JIRA installation
 472  
      * @return <code>true</code> if the authentication was successful, otherwise <code>false</code>
 473  
      */
 474  
     private boolean doJiraAuthentication( HttpClient client, final String jiraUrl )
 475  
     {
 476  
         // log into JIRA if we have to
 477  0
         String loginUrl = null;
 478  
 
 479  0
         StringBuffer loginLink = new StringBuffer( jiraUrl );
 480  
 
 481  0
         loginLink.append( "/login.jsp?os_destination=/secure/" );
 482  
 
 483  0
         loginLink.append( "&os_username=" ).append( jiraUser );
 484  
 
 485  0
         String password = null;
 486  0
         if ( jiraPassword != null )
 487  
         {
 488  0
             password = StringUtils.repeat( "*", jiraPassword.length() );
 489  
         }
 490  0
         getLog().debug( "Login URL: " + loginLink + "&os_password=" + password );
 491  
 
 492  0
         loginLink.append( "&os_password=" ).append( jiraPassword );
 493  
 
 494  0
         loginUrl = loginLink.toString();
 495  
 
 496  
         // execute the login
 497  0
         GetMethod loginGet = new GetMethod( loginUrl );
 498  
 
 499  
         try
 500  
         {
 501  0
             client.executeMethod( loginGet );
 502  
 
 503  0
             if ( loginSucceeded( loginGet ) )
 504  
             {
 505  0
                 getLog().debug( "Successfully logged in into JIRA." );
 506  0
                 return true;
 507  
             }
 508  
             else
 509  
             {
 510  0
                 getLog().warn( "Was unable to login into JIRA: wrong username and/or password." );
 511  
             }
 512  
         }
 513  0
         catch ( Exception e )
 514  
         {
 515  0
             if ( getLog().isDebugEnabled() )
 516  
             {
 517  0
                 getLog().error( "Error trying to login into JIRA.", e );
 518  
             }
 519  
             else
 520  
             {
 521  0
                 getLog().error( "Error trying to login into JIRA. Cause is: " + e.getLocalizedMessage() );
 522  
             }
 523  0
         }
 524  0
         return false;
 525  
     }
 526  
 
 527  
     /**
 528  
      * Check to see if we think that JIRA authentication is needed.
 529  
      *
 530  
      * @return <code>true</code> if jiraUser and jiraPassword are set, otherwise <code>false</code>
 531  
      */
 532  
     private boolean isJiraAuthenticationConfigured()
 533  
     {
 534  0
         return ( jiraUser != null ) && ( jiraUser.length() > 0 ) && ( jiraPassword != null );
 535  
     }
 536  
 
 537  
     /**
 538  
      * Evaluate if the login attempt to JIRA was successful or not. We can't
 539  
      * use the status code because JIRA returns 200 even if the login fails.
 540  
      *
 541  
      * @param loginGet The method that was executed
 542  
      * @return <code>false</code> if we find an error message in the response body, otherwise <code>true</code>
 543  
      * @todo There must be a nicer way to know whether we were able to login or not
 544  
      */
 545  
     private boolean loginSucceeded( GetMethod loginGet )
 546  
         throws IOException
 547  
     {
 548  0
         final String loginFailureResponse = "your username and password are incorrect";
 549  
 
 550  0
         return loginGet.getResponseBodyAsString().indexOf( loginFailureResponse ) == -1;
 551  
     }
 552  
 
 553  
     /**
 554  
      * Setup proxy access if we have to.
 555  
      *
 556  
      * @param client  the HttpClient
 557  
      */
 558  
     private void determineProxy( HttpClient client )
 559  
     {
 560  
         // see whether there is any proxy defined in maven
 561  0
         Proxy proxy = null;
 562  
 
 563  0
         String proxyHost = null;
 564  
 
 565  0
         int proxyPort = 0;
 566  
 
 567  0
         String proxyUser = null;
 568  
 
 569  0
         String proxyPass = null;
 570  
 
 571  0
         if ( project == null )
 572  
         {
 573  0
             getLog().error( "No project set. No proxy info available." );
 574  
 
 575  0
             return;
 576  
         }
 577  
 
 578  0
         if ( settings != null )
 579  
         {
 580  0
             proxy = settings.getActiveProxy();
 581  
         }
 582  
 
 583  0
         if ( proxy != null )
 584  
         {
 585  0
             proxyHost = settings.getActiveProxy().getHost();
 586  
 
 587  0
             proxyPort = settings.getActiveProxy().getPort();
 588  
 
 589  0
             proxyUser = settings.getActiveProxy().getUsername();
 590  
 
 591  0
             proxyPass = settings.getActiveProxy().getPassword();
 592  
 
 593  0
             getLog().debug( proxyPass );
 594  
         }
 595  
 
 596  0
         if ( proxyHost != null )
 597  
         {
 598  0
             client.getHostConfiguration().setProxy( proxyHost, proxyPort );
 599  
 
 600  0
             getLog().debug( "Using proxy: " + proxyHost + " at port " + proxyPort );
 601  
 
 602  0
             if ( proxyUser != null )
 603  
             {
 604  0
                 getLog().debug( "Using proxy user: " + proxyUser );
 605  
 
 606  0
                 client.getState().setProxyCredentials(
 607  
                                                        new AuthScope( null, AuthScope.ANY_PORT, null,
 608  
                                                                       AuthScope.ANY_SCHEME ),
 609  
                                                        new UsernamePasswordCredentials( proxyUser, proxyPass ) );
 610  
             }
 611  
         }
 612  0
     }
 613  
 
 614  
     /**
 615  
      * Downloads the given link using the configured HttpClient, possibly following redirects.
 616  
      *
 617  
      * @param cl     the HttpClient
 618  
      * @param link   the URL to JIRA
 619  
      */
 620  
     private void download( final HttpClient cl, final String link )
 621  
     {
 622  
         try
 623  
         {
 624  0
             GetMethod gm = new GetMethod( link );
 625  
 
 626  0
             getLog().info( "Downloading from JIRA at: " + link );
 627  
 
 628  0
             gm.setFollowRedirects( true );
 629  
 
 630  0
             cl.executeMethod( gm );
 631  
 
 632  0
             StatusLine sl = gm.getStatusLine();
 633  
 
 634  0
             if ( sl == null )
 635  
             {
 636  0
                 getLog().error( "Unknown error validating link: " + link );
 637  
 
 638  0
                 return;
 639  
             }
 640  
 
 641  
             // if we get a redirect, do so
 642  0
             if ( gm.getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY )
 643  
             {
 644  0
                 Header locationHeader = gm.getResponseHeader( "Location" );
 645  
 
 646  0
                 if ( locationHeader == null )
 647  
                 {
 648  0
                     getLog().warn( "Site sent redirect, but did not set Location header" );
 649  
                 }
 650  
                 else
 651  
                 {
 652  0
                     String newLink = locationHeader.getValue();
 653  
 
 654  0
                     getLog().debug( "Following redirect to " + newLink );
 655  
 
 656  0
                     download( cl, newLink );
 657  
                 }
 658  
             }
 659  
 
 660  0
             if ( gm.getStatusCode() == HttpStatus.SC_OK )
 661  
             {
 662  0
                 final String strGetResponseBody = gm.getResponseBodyAsString();
 663  
 
 664  0
                 if ( !output.getParentFile().exists() )
 665  
                 {
 666  0
                     output.getParentFile().mkdirs();
 667  
                 }
 668  
 
 669  
                 // write the reponse to file
 670  0
                 PrintWriter pw = new PrintWriter( new FileWriter( output ) );
 671  
 
 672  0
                 pw.print( strGetResponseBody );
 673  
 
 674  0
                 pw.close();
 675  
 
 676  0
                 getLog().debug( "Downloading from JIRA was successful" );
 677  
             }
 678  
             else
 679  
             {
 680  0
                 getLog().warn( "Downloading from JIRA failed. Received: [" + gm.getStatusCode() + "]" );
 681  
             }
 682  
         }
 683  0
         catch ( HttpException e )
 684  
         {
 685  0
             if ( getLog().isDebugEnabled() )
 686  
             {
 687  0
                 getLog().error( "Error downloading issues from JIRA:", e );
 688  
             }
 689  
             else
 690  
             {
 691  0
                 getLog().error( "Error downloading issues from JIRA url: " + e.getLocalizedMessage() );
 692  
 
 693  
             }
 694  
         }
 695  0
         catch ( IOException e )
 696  
         {
 697  0
             if ( getLog().isDebugEnabled() )
 698  
             {
 699  0
                 getLog().error( "Error downloading issues from JIRA:", e );
 700  
             }
 701  
             else
 702  
             {
 703  0
                 getLog().error( "Error downloading issues from JIRA. Cause is " + e.getLocalizedMessage() );
 704  
             }
 705  0
         }
 706  0
     }
 707  
 
 708  
     /**
 709  
      * Set the output file for the log.
 710  
      *
 711  
      * @param thisOutput the output file
 712  
      */
 713  
     public void setOutput( File thisOutput )
 714  
     {
 715  0
         this.output = thisOutput;
 716  0
     }
 717  
 
 718  
     public File getOutput()
 719  
     {
 720  0
         return this.output;
 721  
     }
 722  
 
 723  
     /**
 724  
      * Sets the project.
 725  
      *
 726  
      * @param thisProject  The project to set
 727  
      */
 728  
     public void setMavenProject( Object thisProject )
 729  
     {
 730  0
         this.project = (MavenProject) thisProject;
 731  0
     }
 732  
 
 733  
     /**
 734  
      * Sets the maximum number of Issues to show.
 735  
      *
 736  
      * @param nbEntries  The maximum number of Issues
 737  
      */
 738  
     public void setNbEntries( final int nbEntries )
 739  
     {
 740  0
         nbEntriesMax = nbEntries;
 741  0
     }
 742  
 
 743  
     /**
 744  
      * Sets the statusIds.
 745  
      *
 746  
      * @param thisStatusIds   The id(s) of the status to show, as comma separated string
 747  
      */
 748  
     public void setStatusIds( String thisStatusIds )
 749  
     {
 750  0
         statusIds = thisStatusIds;
 751  0
     }
 752  
 
 753  
     /**
 754  
      * Sets the priorityIds.
 755  
      *
 756  
      * @param thisPriorityIds  The id(s) of the priority to show, as comma separated string
 757  
      */
 758  
     public void setPriorityIds( String thisPriorityIds )
 759  
     {
 760  0
         priorityIds = thisPriorityIds;
 761  0
     }
 762  
 
 763  
     /**
 764  
      * Sets the resolutionIds.
 765  
      *
 766  
      * @param thisResolutionIds  The id(s) of the resolution to show, as comma separated string
 767  
      */
 768  
     public void setResolutionIds( String thisResolutionIds )
 769  
     {
 770  0
         resolutionIds = thisResolutionIds;
 771  0
     }
 772  
 
 773  
     /**
 774  
      * Sets the sort column names.
 775  
      *
 776  
      * @param thisSortColumnNames The column names to sort by
 777  
      */
 778  
     public void setSortColumnNames( String thisSortColumnNames )
 779  
     {
 780  0
         sortColumnNames = thisSortColumnNames;
 781  0
     }
 782  
 
 783  
     /**
 784  
      * Sets the password for authentication against the webserver.
 785  
      *
 786  
      * @param thisWebPassword  The password of the webserver
 787  
      */
 788  
     public void setWebPassword( String thisWebPassword )
 789  
     {
 790  0
         this.webPassword = thisWebPassword;
 791  0
     }
 792  
 
 793  
     /**
 794  
      * Sets the username for authentication against the webserver.
 795  
      *
 796  
      * @param thisWebUser   The username of the webserver
 797  
      */
 798  
     public void setWebUser( String thisWebUser )
 799  
     {
 800  0
         this.webUser = thisWebUser;
 801  0
     }
 802  
 
 803  
     /**
 804  
      * Sets the password to log into a secured JIRA.
 805  
      *
 806  
      * @param thisJiraPassword  The password for JIRA
 807  
      */
 808  
     public void setJiraPassword( final String thisJiraPassword )
 809  
     {
 810  0
         this.jiraPassword = thisJiraPassword;
 811  0
     }
 812  
 
 813  
     /**
 814  
      * Sets the username to log into a secured JIRA.
 815  
      *
 816  
      * @param thisJiraUser  The username for JIRA
 817  
      */
 818  
     public void setJiraUser( String thisJiraUser )
 819  
     {
 820  0
         this.jiraUser = thisJiraUser;
 821  0
     }
 822  
 
 823  
     /**
 824  
      * Sets the filter to apply to query to JIRA.
 825  
      *
 826  
      * @param thisFilter  The filter to query JIRA
 827  
      */
 828  
     public void setFilter( String thisFilter )
 829  
     {
 830  0
         this.filter = thisFilter;
 831  0
     }
 832  
 
 833  
     /**
 834  
      * Sets the component(s) to apply to query JIRA.
 835  
      *
 836  
      * @param theseComponents   The id(s) of components to show, as comma separated string
 837  
      */
 838  
     public void setComponent( String theseComponents )
 839  
     {
 840  0
         this.component = theseComponents;
 841  0
     }
 842  
 
 843  
     /**
 844  
      * Sets the fix version id(s) to apply to query JIRA.
 845  
      *
 846  
      * @param theseFixVersionIds The id(s) of fix versions to show, as comma separated string
 847  
      */
 848  
     public void setFixVersionIds( String theseFixVersionIds )
 849  
     {
 850  0
         this.fixVersionIds = theseFixVersionIds;
 851  0
     }
 852  
 
 853  
     /**
 854  
      * Sets the typeIds.
 855  
      *
 856  
      * @param theseTypeIds  The id(s) of the types to show, as comma separated string
 857  
      */
 858  
     public void setTypeIds( String theseTypeIds )
 859  
     {
 860  0
         typeIds = theseTypeIds;
 861  0
     }
 862  
 
 863  
     public void setLog( Log log )
 864  
     {
 865  0
         this.log = log;
 866  0
     }
 867  
 
 868  
     private Log getLog()
 869  
     {
 870  0
         return log;
 871  
     }
 872  
 
 873  
     public void setSettings( Settings settings )
 874  
     {
 875  0
         this.settings = settings;
 876  0
     }
 877  
 }