Coverage Report - org.apache.maven.plugin.doap.DoapUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
DoapUtil
0 %
0/198
0 %
0/104
0
DoapUtil$1
0 %
0/3
N/A
0
DoapUtil$2
0 %
0/5
N/A
0
DoapUtil$Organization
0 %
0/14
N/A
0
DoapUtil$ReflectionValueExtractor
0 %
0/46
0 %
0/20
0
 
 1  
 package org.apache.maven.plugin.doap;
 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 java.io.File;
 23  
 import java.io.FileNotFoundException;
 24  
 import java.io.IOException;
 25  
 import java.io.InputStream;
 26  
 import java.lang.reflect.Method;
 27  
 import java.net.MalformedURLException;
 28  
 import java.net.SocketTimeoutException;
 29  
 import java.net.URL;
 30  
 import java.text.DateFormat;
 31  
 import java.util.ArrayList;
 32  
 import java.util.Collection;
 33  
 import java.util.Date;
 34  
 import java.util.HashMap;
 35  
 import java.util.LinkedList;
 36  
 import java.util.List;
 37  
 import java.util.Locale;
 38  
 import java.util.Map;
 39  
 import java.util.StringTokenizer;
 40  
 import java.util.WeakHashMap;
 41  
 import java.util.Map.Entry;
 42  
 import java.util.regex.Matcher;
 43  
 import java.util.regex.Pattern;
 44  
 import java.util.Set;
 45  
 import java.util.Properties;
 46  
 
 47  
 import org.apache.commons.httpclient.Credentials;
 48  
 import org.apache.commons.httpclient.HttpClient;
 49  
 import org.apache.commons.httpclient.HttpStatus;
 50  
 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 51  
 import org.apache.commons.httpclient.UsernamePasswordCredentials;
 52  
 import org.apache.commons.httpclient.auth.AuthScope;
 53  
 import org.apache.commons.httpclient.methods.GetMethod;
 54  
 import org.apache.commons.httpclient.params.HttpClientParams;
 55  
 import org.apache.commons.httpclient.params.HttpMethodParams;
 56  
 import org.apache.maven.model.Contributor;
 57  
 import org.apache.maven.project.MavenProject;
 58  
 import org.apache.maven.settings.Proxy;
 59  
 import org.apache.maven.settings.Settings;
 60  
 import org.apache.maven.wagon.proxy.ProxyInfo;
 61  
 import org.apache.maven.wagon.proxy.ProxyUtils;
 62  
 import org.codehaus.plexus.i18n.I18N;
 63  
 import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
 64  
 import org.codehaus.plexus.interpolation.InterpolationException;
 65  
 import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
 66  
 import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
 67  
 import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
 68  
 import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
 69  
 import org.codehaus.plexus.util.IOUtil;
 70  
 import org.codehaus.plexus.util.StringUtils;
 71  
 import org.codehaus.plexus.util.introspection.ClassMap;
 72  
 import org.codehaus.plexus.util.xml.XMLWriter;
 73  
 import org.codehaus.plexus.util.xml.XmlWriterUtil;
 74  
 
 75  
 import com.hp.hpl.jena.rdf.model.Model;
 76  
 import com.hp.hpl.jena.rdf.model.ModelFactory;
 77  
 import com.hp.hpl.jena.rdf.model.RDFReader;
 78  
 import com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler;
 79  
 
 80  
 /**
 81  
  * Utility class for {@link DoapMojo} class.
 82  
  *
 83  
  * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 84  
  * @version $Id: org.apache.maven.plugin.doap.DoapUtil.html 815337 2012-05-01 21:52:10Z hboutemy $
 85  
  * @since 1.0
 86  
  */
 87  0
 public class DoapUtil
 88  
 {
 89  
     /** Email regex */
 90  
     private static final String EMAIL_REGEX =
 91  
         "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
 92  
 
 93  
     /** Email pattern */
 94  0
     private static final Pattern EMAIL_PATTERN = Pattern.compile( EMAIL_REGEX );
 95  
 
 96  
     /** Magic number to repeat '=' */
 97  
     private static final int REPEAT_EQUALS = 21;
 98  
 
 99  
     /** The default timeout used when fetching url, i.e. 2000. */
 100  
     public static final int DEFAULT_TIMEOUT = 2000;
 101  
 
 102  
     /** RDF resource attribute */
 103  
     protected static final String RDF_RESOURCE = "rdf:resource";
 104  
 
 105  
     /** RDF nodeID attribute */
 106  
     protected static final String RDF_NODE_ID = "rdf:nodeID";
 107  
 
 108  
     /** DoaP Organizations stored by name */
 109  0
     private static Map<String, DoapUtil.Organization> organizations = new HashMap<String, DoapUtil.Organization>();
 110  
 
 111  
     /**
 112  
      * Write comments in the DOAP file header
 113  
      *
 114  
      * @param writer not null
 115  
      */
 116  
     public static void writeHeader( XMLWriter writer )
 117  
     {
 118  0
         XmlWriterUtil.writeLineBreak( writer );
 119  
 
 120  0
         XmlWriterUtil.writeCommentLineBreak( writer );
 121  0
         XmlWriterUtil.writeComment( writer, StringUtils.repeat( "=", REPEAT_EQUALS ) + " - DO NOT EDIT THIS FILE! - "
 122  
             + StringUtils.repeat( "=", REPEAT_EQUALS ) );
 123  0
         XmlWriterUtil.writeCommentLineBreak( writer );
 124  0
         XmlWriterUtil.writeComment( writer, " " );
 125  0
         XmlWriterUtil.writeComment( writer, "Any modifications will be overwritten." );
 126  0
         XmlWriterUtil.writeComment( writer, " " );
 127  0
         DateFormat dateFormat = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, Locale.US );
 128  0
         XmlWriterUtil.writeComment( writer, "Generated by Maven Doap Plugin " + getPluginVersion() + " on "
 129  
             + dateFormat.format( new Date( System.currentTimeMillis() ) ) );
 130  0
         XmlWriterUtil.writeComment( writer, "See: http://maven.apache.org/plugins/maven-doap-plugin/" );
 131  0
         XmlWriterUtil.writeComment( writer, " " );
 132  0
         XmlWriterUtil.writeCommentLineBreak( writer );
 133  
 
 134  0
         XmlWriterUtil.writeLineBreak( writer );
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Write comment.
 139  
      *
 140  
      * @param writer not null
 141  
      * @param comment not null
 142  
      * @throws IllegalArgumentException if comment is null or empty
 143  
      * @since 1.1
 144  
      */
 145  
     public static void writeComment( XMLWriter writer, String comment )
 146  
         throws IllegalArgumentException
 147  
     {
 148  0
         if ( StringUtils.isEmpty( comment ) )
 149  
         {
 150  0
             throw new IllegalArgumentException( "comment should be defined" );
 151  
         }
 152  
 
 153  0
         XmlWriterUtil.writeLineBreak( writer );
 154  0
         XmlWriterUtil.writeCommentText( writer, comment, 2 );
 155  0
     }
 156  
 
 157  
     /**
 158  
      * @param writer not null
 159  
      * @param xmlnsPrefix could be null
 160  
      * @param name not null
 161  
      * @param value could be null. In this case, the element is not written.
 162  
      * @throws IllegalArgumentException if name is null or empty
 163  
      */
 164  
     public static void writeElement( XMLWriter writer, String xmlnsPrefix, String name, String value )
 165  
         throws IllegalArgumentException
 166  
     {
 167  0
         if ( StringUtils.isEmpty( name ) )
 168  
         {
 169  0
             throw new IllegalArgumentException( "name should be defined" );
 170  
         }
 171  
 
 172  0
         if ( value != null )
 173  
         {
 174  0
             writeStartElement( writer, xmlnsPrefix, name );
 175  0
             writer.writeText( value );
 176  0
             writer.endElement();
 177  
         }
 178  0
     }
 179  
 
 180  
     /**
 181  
      * @param writer not null
 182  
      * @param xmlnsPrefix could be null
 183  
      * @param name not null
 184  
      * @param lang not null
 185  
      * @param value could be null. In this case, the element is not written.
 186  
      * @throws IllegalArgumentException if name is null or empty
 187  
      */
 188  
     public static void writeElement( XMLWriter writer, String xmlnsPrefix, String name, String value, String lang )
 189  
         throws IllegalArgumentException
 190  
     {
 191  0
         if ( StringUtils.isEmpty( lang ) )
 192  
         {
 193  0
             writeElement( writer, xmlnsPrefix, name, value );
 194  0
             return;
 195  
         }
 196  
 
 197  0
         if ( StringUtils.isEmpty( name ) )
 198  
         {
 199  0
             throw new IllegalArgumentException( "name should be defined" );
 200  
         }
 201  
 
 202  0
         if ( value != null )
 203  
         {
 204  0
             writeStartElement( writer, xmlnsPrefix, name );
 205  0
             writer.addAttribute( "xml:lang", lang );
 206  0
             writer.writeText( value );
 207  0
             writer.endElement();
 208  
         }
 209  0
     }
 210  
 
 211  
     /**
 212  
      * @param writer not null
 213  
      * @param xmlnsPrefix could be null
 214  
      * @param name not null
 215  
      * @throws IllegalArgumentException if name is null or empty
 216  
      * @since 1.1
 217  
      */
 218  
     public static void writeStartElement( XMLWriter writer, String xmlnsPrefix, String name )
 219  
         throws IllegalArgumentException
 220  
     {
 221  0
         if ( StringUtils.isEmpty( name ) )
 222  
         {
 223  0
             throw new IllegalArgumentException( "name should be defined" );
 224  
         }
 225  
 
 226  0
         if ( StringUtils.isNotEmpty( xmlnsPrefix ) )
 227  
         {
 228  0
             writer.startElement( xmlnsPrefix + ":" + name );
 229  
         }
 230  
         else
 231  
         {
 232  0
             writer.startElement( name );
 233  
         }
 234  0
     }
 235  
 
 236  
     /**
 237  
      * @param writer not null
 238  
      * @param xmlnsPrefix could be null
 239  
      * @param name not null
 240  
      * @param value could be null. In this case, the element is not written.
 241  
      * @throws IllegalArgumentException if name is null or empty
 242  
      */
 243  
     public static void writeRdfResourceElement( XMLWriter writer, String xmlnsPrefix, String name, String value )
 244  
         throws IllegalArgumentException
 245  
     {
 246  0
         if ( StringUtils.isEmpty( name ) )
 247  
         {
 248  0
             throw new IllegalArgumentException( "name should be defined" );
 249  
         }
 250  
 
 251  0
         if ( value != null )
 252  
         {
 253  0
             writeStartElement( writer, xmlnsPrefix, name );
 254  0
             writer.addAttribute( RDF_RESOURCE, value );
 255  0
             writer.endElement();
 256  
         }
 257  0
     }
 258  
 
 259  
     /**
 260  
      * @param writer not null
 261  
      * @param name not null
 262  
      * @param value could be null. In this case, the element is not written.
 263  
      * @throws IllegalArgumentException if name is null or empty
 264  
      */
 265  
     public static void writeRdfNodeIdElement( XMLWriter writer, String xmlnsPrefix, String name, String value )
 266  
         throws IllegalArgumentException
 267  
     {
 268  0
         if ( StringUtils.isEmpty( name ) )
 269  
         {
 270  0
             throw new IllegalArgumentException( "name should be defined" );
 271  
         }
 272  
 
 273  0
         if ( value != null )
 274  
         {
 275  0
             writeStartElement( writer, xmlnsPrefix, name );
 276  0
             writer.addAttribute( RDF_NODE_ID, value );
 277  0
             writer.endElement();
 278  
         }
 279  0
     }
 280  
 
 281  
     /**
 282  
      * @param i18n the internationalization component
 283  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 284  
      * @return a none null list of <code>{@link Contributor}</code> which have a <code>developer</code> DOAP role.
 285  
      */
 286  
     public static List<Contributor> getContributorsWithDeveloperRole( I18N i18n,
 287  
                                                                       List<Contributor> developersOrContributors )
 288  
     {
 289  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "developers" );
 290  
     }
 291  
 
 292  
     /**
 293  
      * @param i18n the internationalization component
 294  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 295  
      * @return a none null list of <code>{@link Contributor}</code> which have a <code>documenter</code> DOAP role.
 296  
      */
 297  
     public static List<Contributor> getContributorsWithDocumenterRole( I18N i18n,
 298  
                                                                        List<Contributor> developersOrContributors )
 299  
     {
 300  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "documenters" );
 301  
     }
 302  
 
 303  
     /**
 304  
      * @param i18n the internationalization component
 305  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 306  
      * @return a none null list of <code>{@link Contributor}</code> which have an <code>helper</code> DOAP role.
 307  
      */
 308  
     public static List<Contributor> getContributorsWithHelperRole( I18N i18n, List<Contributor> developersOrContributors )
 309  
     {
 310  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "helpers" );
 311  
     }
 312  
 
 313  
     /**
 314  
      * @param i18n the internationalization component
 315  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 316  
      * @return a none null list of <code>{@link Contributor}</code> which have a <code>maintainer</code> DOAP role.
 317  
      */
 318  
     public static List<Contributor> getContributorsWithMaintainerRole( I18N i18n,
 319  
                                                                        List<Contributor> developersOrContributors )
 320  
     {
 321  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "maintainers" );
 322  
     }
 323  
 
 324  
     /**
 325  
      * @param i18n the internationalization component
 326  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 327  
      * @return a none null list of <code>{@link Contributor}</code> which have a <code>tester</code> DOAP role.
 328  
      */
 329  
     public static List<Contributor> getContributorsWithTesterRole( I18N i18n, List<Contributor> developersOrContributors )
 330  
     {
 331  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "testers" );
 332  
     }
 333  
 
 334  
     /**
 335  
      * @param i18n the internationalization component
 336  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 337  
      * @return a none null list of <code>{@link Contributor}</code> which have a <code>translator</code> DOAP role.
 338  
      */
 339  
     public static List<Contributor> getContributorsWithTranslatorRole( I18N i18n,
 340  
                                                                        List<Contributor> developersOrContributors )
 341  
     {
 342  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "translators" );
 343  
     }
 344  
 
 345  
     /**
 346  
      * @param i18n the internationalization component
 347  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 348  
      * @return a none null list of <code>{@link Contributor}</code> which have an <code>unknown</code> DOAP role.
 349  
      */
 350  
     public static List<Contributor> getContributorsWithUnknownRole( I18N i18n,
 351  
                                                                     List<Contributor> developersOrContributors )
 352  
     {
 353  0
         return filterContributorsByDoapRoles( i18n, developersOrContributors ).get( "unknowns" );
 354  
     }
 355  
 
 356  
     /**
 357  
      * Utility class for keeping track of DOAP organizations in the DoaP mojo.
 358  
      *
 359  
      * @author <a href="mailto:t.fliss@gmail.com">Tim Fliss</a>
 360  
      * @version $Id: org.apache.maven.plugin.doap.DoapUtil.html 815337 2012-05-01 21:52:10Z hboutemy $
 361  
      * @since 1.1
 362  
      */
 363  
     public static class Organization
 364  
     {
 365  
         private String name;
 366  
 
 367  
         private String url;
 368  
 
 369  0
         private List<String> members = new LinkedList<String>();
 370  
 
 371  
         public Organization( String name, String url )
 372  0
         {
 373  0
             this.name = name;
 374  0
             this.url = url;
 375  0
         }
 376  
 
 377  
         public void setName( String name )
 378  
         {
 379  0
             this.name = name;
 380  0
         }
 381  
 
 382  
         public String getName()
 383  
         {
 384  0
             return name;
 385  
         }
 386  
 
 387  
         public void setUrl( String url )
 388  
         {
 389  0
             this.url = url;
 390  0
         }
 391  
 
 392  
         public String getUrl()
 393  
         {
 394  0
             return url;
 395  
         }
 396  
 
 397  
         public void addMember( String nodeId )
 398  
         {
 399  0
             members.add( nodeId );
 400  0
         }
 401  
 
 402  
         public List<String> getMembers()
 403  
         {
 404  0
             return members;
 405  
         }
 406  
     }
 407  
 
 408  
     /**
 409  
      * put an organization from the pom file in the organization list.
 410  
      *
 411  
      * @param name from the pom file (e.g. Yoyodyne)
 412  
      * @param url from the pom file (e.g. http://yoyodyne.example.org/about)
 413  
      * @return the existing organization if a duplicate, or a new one.
 414  
      */
 415  
     public static DoapUtil.Organization addOrganization( String name, String url )
 416  
     {
 417  0
         Organization organization = organizations.get( name );
 418  
 
 419  0
         if ( organization == null )
 420  
         {
 421  0
             organization = new DoapUtil.Organization( name, url );
 422  
         }
 423  
 
 424  0
         organizations.put( name, organization );
 425  
 
 426  0
         return organization;
 427  
     }
 428  
 
 429  
     // unique RDF blank node index scoped internal to the DOAP file
 430  0
     private static int nodeNumber = 1;
 431  
 
 432  
     /**
 433  
      * get a unique (within the DoaP file) RDF blank node ID
 434  
      *
 435  
      * @return the nodeID
 436  
      * @see <a href="http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-blank-nodes">
 437  
      *      http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-blank-nodes</a>
 438  
      */
 439  
     public static String getNodeId()
 440  
     {
 441  0
         return "b" + nodeNumber++;
 442  
     }
 443  
 
 444  
     /**
 445  
      * get the set of Organizations that people are members of
 446  
      *
 447  
      * @return Map.EntrySet of DoapUtil.Organization
 448  
      */
 449  
     public static Set<Entry<String, DoapUtil.Organization>> getOrganizations()
 450  
     {
 451  0
         return organizations.entrySet();
 452  
     }
 453  
 
 454  
     /**
 455  
      * Validate the given DOAP file.
 456  
      *
 457  
      * @param doapFile not null and should exists.
 458  
      * @return an empty list if the DOAP file is valid, otherwise a list of errors.
 459  
      * @since 1.1
 460  
      */
 461  
     public static List<String> validate( File doapFile )
 462  
     {
 463  0
         if ( doapFile == null || !doapFile.isFile() )
 464  
         {
 465  0
             throw new IllegalArgumentException( "The DOAP file should exist" );
 466  
         }
 467  
 
 468  0
         Model model = ModelFactory.createDefaultModel();
 469  0
         RDFReader r = model.getReader( "RDF/XML" );
 470  0
         r.setProperty( "error-mode", "strict-error" );
 471  0
         final List<String> errors = new ArrayList<String>();
 472  0
         r.setErrorHandler( new RDFDefaultErrorHandler()
 473  0
         {
 474  
             @Override
 475  
             public void error( Exception e )
 476  
             {
 477  0
                 errors.add( e.getMessage() );
 478  0
             }
 479  
         } );
 480  
 
 481  
         try
 482  
         {
 483  0
             r.read( model, doapFile.toURI().toURL().toString() );
 484  
         }
 485  0
         catch ( MalformedURLException e )
 486  
         {
 487  
             // ignored
 488  0
         }
 489  
 
 490  0
         return errors;
 491  
     }
 492  
 
 493  
     /**
 494  
      * @param str not null
 495  
      * @return <code>true</code> if the str parameter is a valid email, <code>false</code> otherwise.
 496  
      * @since 1.1
 497  
      */
 498  
     public static boolean isValidEmail( String str )
 499  
     {
 500  0
         if ( StringUtils.isEmpty( str ) )
 501  
         {
 502  0
             return false;
 503  
         }
 504  
 
 505  0
         Matcher matcher = EMAIL_PATTERN.matcher( str );
 506  0
         return matcher.matches();
 507  
     }
 508  
 
 509  
     /**
 510  
      * Fetch an URL
 511  
      *
 512  
      * @param settings the user settings used to fetch the url with an active proxy, if defined.
 513  
      * @param url the url to fetch
 514  
      * @throws IOException if any
 515  
      * @see #DEFAULT_TIMEOUT
 516  
      * @since 1.1
 517  
      */
 518  
     public static void fetchURL( Settings settings, URL url )
 519  
         throws IOException
 520  
     {
 521  0
         if ( url == null )
 522  
         {
 523  0
             throw new IllegalArgumentException( "The url is null" );
 524  
         }
 525  
 
 526  0
         if ( "file".equals( url.getProtocol() ) )
 527  
         {
 528  0
             InputStream in = null;
 529  
             try
 530  
             {
 531  0
                 in = url.openStream();
 532  
             }
 533  
             finally
 534  
             {
 535  0
                 IOUtil.close( in );
 536  0
             }
 537  
 
 538  0
             return;
 539  
         }
 540  
 
 541  
         // http, https...
 542  0
         HttpClient httpClient = new HttpClient( new MultiThreadedHttpConnectionManager() );
 543  0
         httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( DEFAULT_TIMEOUT );
 544  0
         httpClient.getHttpConnectionManager().getParams().setSoTimeout( DEFAULT_TIMEOUT );
 545  0
         httpClient.getParams().setBooleanParameter( HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true );
 546  
 
 547  
         // Some web servers don't allow the default user-agent sent by httpClient
 548  0
         httpClient.getParams().setParameter( HttpMethodParams.USER_AGENT,
 549  
                                              "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" );
 550  
 
 551  0
         if ( settings != null && settings.getActiveProxy() != null )
 552  
         {
 553  0
             Proxy activeProxy = settings.getActiveProxy();
 554  
 
 555  0
             ProxyInfo proxyInfo = new ProxyInfo();
 556  0
             proxyInfo.setNonProxyHosts( activeProxy.getNonProxyHosts() );
 557  
 
 558  0
             if ( StringUtils.isNotEmpty( activeProxy.getHost() )
 559  
                 && !ProxyUtils.validateNonProxyHosts( proxyInfo, url.getHost() ) )
 560  
             {
 561  0
                 httpClient.getHostConfiguration().setProxy( activeProxy.getHost(), activeProxy.getPort() );
 562  
 
 563  0
                 if ( StringUtils.isNotEmpty( activeProxy.getUsername() ) && activeProxy.getPassword() != null )
 564  
                 {
 565  0
                     Credentials credentials =
 566  
                         new UsernamePasswordCredentials( activeProxy.getUsername(), activeProxy.getPassword() );
 567  
 
 568  0
                     httpClient.getState().setProxyCredentials( AuthScope.ANY, credentials );
 569  
                 }
 570  
             }
 571  
         }
 572  
 
 573  0
         GetMethod getMethod = new GetMethod( url.toString() );
 574  
         try
 575  
         {
 576  
             int status;
 577  
             try
 578  
             {
 579  0
                 status = httpClient.executeMethod( getMethod );
 580  
             }
 581  0
             catch ( SocketTimeoutException e )
 582  
             {
 583  
                 // could be a sporadic failure, one more retry before we give up
 584  0
                 status = httpClient.executeMethod( getMethod );
 585  0
             }
 586  
 
 587  0
             if ( status != HttpStatus.SC_OK )
 588  
             {
 589  0
                 throw new FileNotFoundException( url.toString() );
 590  
             }
 591  
         }
 592  
         finally
 593  
         {
 594  0
             getMethod.releaseConnection();
 595  0
         }
 596  0
     }
 597  
 
 598  
     /**
 599  
      * Interpolate a string with project and settings.
 600  
      *
 601  
      * @param value could be null
 602  
      * @param project not null
 603  
      * @param settings could be null
 604  
      * @return the value trimmed and interpolated or null if the interpolation doesn't work.
 605  
      * @since 1.1
 606  
      */
 607  
     public static String interpolate( String value, final MavenProject project, Settings settings )
 608  
     {
 609  0
         if ( project == null )
 610  
         {
 611  0
             throw new IllegalArgumentException( "project is required" );
 612  
         }
 613  
 
 614  0
         if ( value == null )
 615  
         {
 616  0
             return value;
 617  
         }
 618  
 
 619  0
         if ( !value.contains( "${" ) )
 620  
         {
 621  0
             return value.trim();
 622  
         }
 623  
 
 624  0
         RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
 625  
         try
 626  
         {
 627  0
             interpolator.addValueSource( new EnvarBasedValueSource() );
 628  
         }
 629  0
         catch ( IOException e )
 630  
         {
 631  0
         }
 632  0
         interpolator.addValueSource( new PropertiesBasedValueSource( System.getProperties() ) );
 633  0
         interpolator.addValueSource( new PropertiesBasedValueSource( project.getProperties() ) );
 634  0
         interpolator.addValueSource( new PrefixedObjectValueSource( "project", project ) );
 635  0
         interpolator.addValueSource( new PrefixedObjectValueSource( "pom", project ) );
 636  0
         interpolator.addValueSource( new ObjectBasedValueSource( project )
 637  0
         {
 638  
             @Override
 639  
             public Object getValue( String expression )
 640  
             {
 641  
                 try
 642  
                 {
 643  0
                     return ReflectionValueExtractor.evaluate( expression, project, true );
 644  
                 }
 645  0
                 catch ( Exception e )
 646  
                 {
 647  0
                     addFeedback( "Failed to extract \'" + expression + "\' from: " + project, e );
 648  
                 }
 649  
 
 650  0
                 return null;
 651  
             }
 652  
         } );
 653  
 
 654  0
         if ( settings != null )
 655  
         {
 656  0
             interpolator.addValueSource( new PrefixedObjectValueSource( "settings", settings ) );
 657  
         }
 658  
 
 659  0
         String interpolatedValue = value;
 660  
         try
 661  
         {
 662  0
             interpolatedValue = interpolator.interpolate( value ).trim();
 663  
         }
 664  0
         catch ( InterpolationException e )
 665  
         {
 666  0
         }
 667  
 
 668  0
         if ( interpolatedValue.startsWith( "${" ) )
 669  
         {
 670  0
             return null;
 671  
         }
 672  
 
 673  0
         return interpolatedValue;
 674  
     }
 675  
 
 676  
     // ----------------------------------------------------------------------
 677  
     // Private methods
 678  
     // ----------------------------------------------------------------------
 679  
 
 680  
     /**
 681  
      * Filter the developers/contributors roles by the keys from {@link I18N#getBundle()}. <br/>
 682  
      * I18N roles supported in DOAP, i.e. <code>maintainer</code>, <code>developer</code>, <code>documenter</code>,
 683  
      * <code>translator</code>, <code>tester</code>, <code>helper</code>. <br/>
 684  
      * <b>Note:</b> Actually, only English keys are used.
 685  
      *
 686  
      * @param i18n i18n component
 687  
      * @param developersOrContributors list of <code>{@link Contributor}</code>
 688  
      * @return a none null map with <code>maintainers</code>, <code>developers</code>, <code>documenters</code>,
 689  
      *         <code>translators</code>, <code>testers</code>, <code>helpers</code>, <code>unknowns</code> as keys and
 690  
      *         list of <code>{@link Contributor}</code> as value.
 691  
      */
 692  
     private static Map<String, List<Contributor>> filterContributorsByDoapRoles( I18N i18n,
 693  
                                                                                  List<Contributor> developersOrContributors )
 694  
     {
 695  0
         Map<String, List<Contributor>> returnMap = new HashMap<String, List<Contributor>>( 7 );
 696  0
         returnMap.put( "maintainers", new ArrayList<Contributor>() );
 697  0
         returnMap.put( "developers", new ArrayList<Contributor>() );
 698  0
         returnMap.put( "documenters", new ArrayList<Contributor>() );
 699  0
         returnMap.put( "translators", new ArrayList<Contributor>() );
 700  0
         returnMap.put( "testers", new ArrayList<Contributor>() );
 701  0
         returnMap.put( "helpers", new ArrayList<Contributor>() );
 702  0
         returnMap.put( "unknowns", new ArrayList<Contributor>() );
 703  
 
 704  0
         if ( developersOrContributors == null || developersOrContributors.isEmpty() )
 705  
         {
 706  0
             return returnMap;
 707  
         }
 708  
 
 709  0
         for ( Contributor contributor : developersOrContributors )
 710  
         {
 711  0
             List<String> roles = contributor.getRoles();
 712  
 
 713  0
             if ( roles != null && roles.size() != 0 )
 714  
             {
 715  0
                 for ( String role : roles )
 716  
                 {
 717  0
                     role = role.toLowerCase( Locale.ENGLISH );
 718  0
                     if ( role.contains( getLowerCaseString( i18n, "doap.maintainer" ) ) )
 719  
                     {
 720  0
                         if ( !returnMap.get( "maintainers" ).contains( contributor ) )
 721  
                         {
 722  0
                             returnMap.get( "maintainers" ).add( contributor );
 723  
                         }
 724  
                     }
 725  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.developer" ) ) )
 726  
                     {
 727  0
                         if ( !returnMap.get( "developers" ).contains( contributor ) )
 728  
                         {
 729  0
                             returnMap.get( "developers" ).add( contributor );
 730  
                         }
 731  
                     }
 732  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.documenter" ) ) )
 733  
                     {
 734  0
                         if ( !returnMap.get( "documenters" ).contains( contributor ) )
 735  
                         {
 736  0
                             returnMap.get( "documenters" ).add( contributor );
 737  
                         }
 738  
                     }
 739  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.translator" ) ) )
 740  
                     {
 741  0
                         if ( !returnMap.get( "translators" ).contains( contributor ) )
 742  
                         {
 743  0
                             returnMap.get( "translators" ).add( contributor );
 744  
                         }
 745  
                     }
 746  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.tester" ) ) )
 747  
                     {
 748  0
                         if ( !returnMap.get( "testers" ).contains( contributor ) )
 749  
                         {
 750  0
                             returnMap.get( "testers" ).add( contributor );
 751  
                         }
 752  
                     }
 753  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.helper" ) ) )
 754  
                     {
 755  0
                         if ( !returnMap.get( "helpers" ).contains( contributor ) )
 756  
                         {
 757  0
                             returnMap.get( "helpers" ).add( contributor );
 758  
                         }
 759  
                     }
 760  0
                     else if ( role.contains( getLowerCaseString( i18n, "doap.emeritus" ) ) )
 761  
                     {
 762  
                         // Don't add as developer nor as contributor as the person is no longer involved
 763  
                     }
 764  
                     else
 765  
                     {
 766  0
                         if ( !returnMap.get( "unknowns" ).contains( contributor ) )
 767  
                         {
 768  0
                             returnMap.get( "unknowns" ).add( contributor );
 769  
                         }
 770  
                     }
 771  
                 }
 772  
             }
 773  
             else
 774  
             {
 775  0
                 if ( !returnMap.get( "unknowns" ).contains( contributor ) )
 776  
                 {
 777  0
                     returnMap.get( "unknowns" ).add( contributor );
 778  
                 }
 779  
             }
 780  0
         }
 781  
 
 782  0
         return returnMap;
 783  
     }
 784  
 
 785  
     /**
 786  
      * @param i18n not null
 787  
      * @param key not null
 788  
      * @return lower case value for the key in the i18n bundle.
 789  
      */
 790  
     private static String getLowerCaseString( I18N i18n, String key )
 791  
     {
 792  0
         return i18n.getString( "doap-person", Locale.ENGLISH, key ).toLowerCase( Locale.ENGLISH );
 793  
     }
 794  
 
 795  
     /**
 796  
      * @return the Maven artefact version.
 797  
      */
 798  
     private static String getPluginVersion()
 799  
     {
 800  0
         Properties pomProperties = new Properties();
 801  0
         InputStream is = null;
 802  
         try
 803  
         {
 804  0
             is =
 805  
                 DoapUtil.class.getResourceAsStream( "/META-INF/maven/org.apache.maven.plugins/maven-doap-plugin/pom.properties" );
 806  0
             if ( is == null )
 807  
             {
 808  0
                 return "<unknown>";
 809  
             }
 810  
 
 811  0
             pomProperties.load( is );
 812  
 
 813  0
             return pomProperties.getProperty( "version", "<unknown>" );
 814  
         }
 815  0
         catch ( IOException e )
 816  
         {
 817  0
             return "<unknown>";
 818  
         }
 819  
         finally
 820  
         {
 821  0
             IOUtil.close( is );
 822  
         }
 823  
     }
 824  
 
 825  
     /**
 826  
      * Fork of {@link org.codehaus.plexus.interpolation.reflection.ReflectionValueExtractor} to care of list or arrays.
 827  
      */
 828  0
     static class ReflectionValueExtractor
 829  
     {
 830  
         @SuppressWarnings( "rawtypes" )
 831  0
         private static final Class[] CLASS_ARGS = new Class[0];
 832  
 
 833  0
         private static final Object[] OBJECT_ARGS = new Object[0];
 834  
 
 835  
         /**
 836  
          * Use a WeakHashMap here, so the keys (Class objects) can be garbage collected. This approach prevents permgen
 837  
          * space overflows due to retention of discarded classloaders.
 838  
          */
 839  
         @SuppressWarnings( "rawtypes" )
 840  0
         private static final Map<Class,ClassMap> classMaps = new WeakHashMap<Class,ClassMap>();
 841  
 
 842  
         private ReflectionValueExtractor()
 843  0
         {
 844  0
         }
 845  
 
 846  
         public static Object evaluate( String expression, Object root )
 847  
             throws Exception
 848  
         {
 849  0
             return evaluate( expression, root, true );
 850  
         }
 851  
 
 852  
         // TODO: don't throw Exception
 853  
         public static Object evaluate( String expression, Object root, boolean trimRootToken )
 854  
             throws Exception
 855  
         {
 856  
             // if the root token refers to the supplied root object parameter, remove it.
 857  0
             if ( trimRootToken )
 858  
             {
 859  0
                 expression = expression.substring( expression.indexOf( '.' ) + 1 );
 860  
             }
 861  
 
 862  0
             Object value = root;
 863  
 
 864  
             // ----------------------------------------------------------------------
 865  
             // Walk the dots and retrieve the ultimate value desired from the
 866  
             // MavenProject instance.
 867  
             // ----------------------------------------------------------------------
 868  
 
 869  0
             StringTokenizer parser = new StringTokenizer( expression, "." );
 870  
 
 871  0
             while ( parser.hasMoreTokens() )
 872  
             {
 873  0
                 String token = parser.nextToken();
 874  0
                 if ( value == null )
 875  
                 {
 876  0
                     return null;
 877  
                 }
 878  
 
 879  0
                 StringTokenizer parser2 = new StringTokenizer( token, "[]" );
 880  0
                 int index = -1;
 881  0
                 if ( parser2.countTokens() > 1 )
 882  
                 {
 883  0
                     token = parser2.nextToken();
 884  
                     try
 885  
                     {
 886  0
                         index = Integer.valueOf( parser2.nextToken() ).intValue();
 887  
                     }
 888  0
                     catch ( NumberFormatException e )
 889  
                     {
 890  0
                     }
 891  
                 }
 892  
 
 893  0
                 final ClassMap classMap = getClassMap( value.getClass() );
 894  
 
 895  0
                 final String methodBase = StringUtils.capitalizeFirstLetter( token );
 896  
 
 897  0
                 String methodName = "get" + methodBase;
 898  
 
 899  0
                 Method method = classMap.findMethod( methodName, CLASS_ARGS );
 900  
 
 901  0
                 if ( method == null )
 902  
                 {
 903  
                     // perhaps this is a boolean property??
 904  0
                     methodName = "is" + methodBase;
 905  
 
 906  0
                     method = classMap.findMethod( methodName, CLASS_ARGS );
 907  
                 }
 908  
 
 909  0
                 if ( method == null )
 910  
                 {
 911  0
                     return null;
 912  
                 }
 913  
 
 914  0
                 value = method.invoke( value, OBJECT_ARGS );
 915  0
                 if ( value == null )
 916  
                 {
 917  0
                     return null;
 918  
                 }
 919  0
                 if ( Collection.class.isAssignableFrom( value.getClass() ) )
 920  
                 {
 921  0
                     ClassMap classMap2 = getClassMap( value.getClass() );
 922  
 
 923  0
                     Method method2 = classMap2.findMethod( "toArray", CLASS_ARGS );
 924  
 
 925  0
                     value = method2.invoke( value, OBJECT_ARGS );
 926  
                 }
 927  0
                 if ( value.getClass().isArray() )
 928  
                 {
 929  0
                     value = ( (Object[]) value )[index];
 930  
                 }
 931  0
             }
 932  
 
 933  0
             return value;
 934  
         }
 935  
 
 936  
         private static ClassMap getClassMap( Class<? extends Object> clazz )
 937  
         {
 938  0
             ClassMap classMap = classMaps.get( clazz );
 939  
 
 940  0
             if ( classMap == null )
 941  
             {
 942  0
                 classMap = new ClassMap( clazz );
 943  
 
 944  0
                 classMaps.put( clazz, classMap );
 945  
             }
 946  
 
 947  0
             return classMap;
 948  
         }
 949  
     }
 950  
 }