Coverage Report - org.apache.maven.index.ArtifactInfo
 
Classes in this File Line Coverage Branch Coverage Complexity
ArtifactInfo
90 %
111/123
76 %
46/60
4,381
ArtifactInfo$ContextVersionComparator
88 %
8/9
50 %
4/8
4,381
ArtifactInfo$RepositoryVersionComparator
11 %
1/9
0 %
0/8
4,381
ArtifactInfo$VersionComparator
96 %
24/25
80 %
16/20
4,381
 
 1  
 package org.apache.maven.index;
 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.util.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.Collection;
 25  
 import java.util.Comparator;
 26  
 import java.util.HashMap;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 
 30  
 import org.apache.maven.index.artifact.Gav;
 31  
 import org.apache.maven.index.creator.JarFileContentsIndexCreator;
 32  
 import org.apache.maven.index.creator.MavenPluginArtifactInfoIndexCreator;
 33  
 import org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator;
 34  
 import org.apache.maven.index.creator.OsgiArtifactIndexCreator;
 35  
 import org.codehaus.plexus.util.StringUtils;
 36  
 import org.sonatype.aether.util.version.GenericVersionScheme;
 37  
 import org.sonatype.aether.version.InvalidVersionSpecificationException;
 38  
 import org.sonatype.aether.version.Version;
 39  
 import org.sonatype.aether.version.VersionScheme;
 40  
 
 41  
 /**
 42  
  * ArtifactInfo holds the values known about an repository artifact. This is a simple Value Object kind of stuff.
 43  
  * Phasing out.
 44  
  * 
 45  
  * @author Jason van Zyl
 46  
  * @author Eugene Kuleshov
 47  
  */
 48  
 public class ArtifactInfo
 49  
     extends ArtifactInfoRecord
 50  
 {
 51  
     private static final long serialVersionUID = 6028843453477511104L;
 52  
 
 53  
     // --
 54  
 
 55  
     public static final String ROOT_GROUPS = "rootGroups";
 56  
 
 57  
     public static final String ROOT_GROUPS_VALUE = "rootGroups";
 58  
 
 59  
     public static final String ROOT_GROUPS_LIST = "rootGroupsList";
 60  
 
 61  
     public static final String ALL_GROUPS = "allGroups";
 62  
 
 63  
     public static final String ALL_GROUPS_VALUE = "allGroups";
 64  
 
 65  
     public static final String ALL_GROUPS_LIST = "allGroupsList";
 66  
 
 67  
     // ----------
 68  
 
 69  
     /**
 70  
      * Unique groupId, artifactId, version, classifier, extension (or packaging). Stored, indexed untokenized
 71  
      */
 72  1
     public static final String UINFO = FLD_UINFO.getKey();
 73  
 
 74  
     /**
 75  
      * Field that contains {@link #UINFO} value for deleted artifact
 76  
      */
 77  1
     public static final String DELETED = FLD_DELETED.getKey();
 78  
 
 79  
     /**
 80  
      * GroupId. Not stored, indexed untokenized
 81  
      */
 82  1
     public static final String GROUP_ID = MinimalArtifactInfoIndexCreator.FLD_GROUP_ID_KW.getKey();
 83  
 
 84  
     /**
 85  
      * ArtifactId. Not stored, indexed tokenized
 86  
      */
 87  1
     public static final String ARTIFACT_ID = MinimalArtifactInfoIndexCreator.FLD_ARTIFACT_ID_KW.getKey();
 88  
 
 89  
     /**
 90  
      * Version. Not stored, indexed tokenized
 91  
      */
 92  1
     public static final String VERSION = MinimalArtifactInfoIndexCreator.FLD_VERSION_KW.getKey();
 93  
 
 94  
     /**
 95  
      * Packaging. Not stored, indexed untokenized
 96  
      */
 97  1
     public static final String PACKAGING = MinimalArtifactInfoIndexCreator.FLD_PACKAGING.getKey();
 98  
 
 99  
     /**
 100  
      * Classifier. Not stored, indexed untokenized
 101  
      */
 102  1
     public static final String CLASSIFIER = MinimalArtifactInfoIndexCreator.FLD_CLASSIFIER.getKey();
 103  
 
 104  
     /**
 105  
      * Info: packaging, lastModified, size, sourcesExists, javadocExists, signatureExists. Stored, not indexed.
 106  
      */
 107  1
     public static final String INFO = MinimalArtifactInfoIndexCreator.FLD_INFO.getKey();
 108  
 
 109  
     /**
 110  
      * Name. Stored, not indexed
 111  
      */
 112  1
     public static final String NAME = MinimalArtifactInfoIndexCreator.FLD_NAME.getKey();
 113  
 
 114  
     /**
 115  
      * Description. Stored, not indexed
 116  
      */
 117  1
     public static final String DESCRIPTION = MinimalArtifactInfoIndexCreator.FLD_DESCRIPTION.getKey();
 118  
 
 119  
     /**
 120  
      * Last modified. Stored, not indexed
 121  
      */
 122  1
     public static final String LAST_MODIFIED = MinimalArtifactInfoIndexCreator.FLD_LAST_MODIFIED.getKey();
 123  
 
 124  
     /**
 125  
      * SHA1. Stored, indexed untokenized
 126  
      */
 127  1
     public static final String SHA1 = MinimalArtifactInfoIndexCreator.FLD_SHA1.getKey();
 128  
 
 129  
     /**
 130  
      * Class names Stored compressed, indexed tokeninzed
 131  
      */
 132  1
     public static final String NAMES = JarFileContentsIndexCreator.FLD_CLASSNAMES_KW.getKey();
 133  
 
 134  
     /**
 135  
      * Plugin prefix. Stored, not indexed
 136  
      */
 137  1
     public static final String PLUGIN_PREFIX = MavenPluginArtifactInfoIndexCreator.FLD_PLUGIN_PREFIX.getKey();
 138  
 
 139  
     /**
 140  
      * Plugin goals. Stored, not indexed
 141  
      */
 142  1
     public static final String PLUGIN_GOALS = MavenPluginArtifactInfoIndexCreator.FLD_PLUGIN_GOALS.getKey();
 143  
 
 144  
 
 145  
     /**
 146  
      * @since 1.4.2
 147  
      */
 148  1
     public static final String BUNDLE_SYMBOLIC_NAME = OsgiArtifactIndexCreator.FLD_BUNDLE_SYMBOLIC_NAME.getKey();
 149  
 
 150  
     /**
 151  
      * @since 1.4.2
 152  
      */
 153  1
     public static final String BUNDLE_VERSION = OsgiArtifactIndexCreator.FLD_BUNDLE_VERSION.getKey();
 154  
 
 155  
     /**
 156  
      * @since 1.4.2
 157  
      */
 158  1
     public static final String BUNDLE_EXPORT_PACKAGE = OsgiArtifactIndexCreator.FLD_BUNDLE_EXPORT_PACKAGE.getKey();
 159  
 
 160  1
     public static final Comparator<ArtifactInfo> VERSION_COMPARATOR = new VersionComparator();
 161  
 
 162  1
     public static final Comparator<ArtifactInfo> REPOSITORY_VERSION_COMPARATOR = new RepositoryVersionComparator();
 163  
 
 164  1
     public static final Comparator<ArtifactInfo> CONTEXT_VERSION_COMPARATOR = new ContextVersionComparator();
 165  
 
 166  
     public String fname;
 167  
 
 168  
     public String fextension;
 169  
 
 170  
     public String groupId;
 171  
 
 172  
     public String artifactId;
 173  
 
 174  
     public String version;
 175  
 
 176  
     private transient Version artifactVersion;
 177  
 
 178  
     private transient float luceneScore;
 179  
 
 180  
     public String classifier;
 181  
 
 182  
     /**
 183  
      * Artifact packaging for the main artifact and extension for secondary artifact (no classifier)
 184  
      */
 185  
     public String packaging;
 186  
 
 187  
     public String name;
 188  
 
 189  
     public String description;
 190  
 
 191  239986
     public long lastModified = -1;
 192  
 
 193  239986
     public long size = -1;
 194  
 
 195  
     public String md5;
 196  
 
 197  
     public String sha1;
 198  
 
 199  239986
     public ArtifactAvailablility sourcesExists = ArtifactAvailablility.NOT_PRESENT;
 200  
 
 201  239986
     public ArtifactAvailablility javadocExists = ArtifactAvailablility.NOT_PRESENT;
 202  
 
 203  239986
     public ArtifactAvailablility signatureExists = ArtifactAvailablility.NOT_PRESENT;
 204  
 
 205  
     public String classNames;
 206  
 
 207  
     public String repository;
 208  
 
 209  
     public String path;
 210  
 
 211  
     public String remoteUrl;
 212  
 
 213  
     public String context;
 214  
 
 215  
     /**
 216  
      * Plugin goal prefix (only if packaging is "maven-plugin")
 217  
      */
 218  
     public String prefix;
 219  
 
 220  
     /**
 221  
      * Plugin goals (only if packaging is "maven-plugin")
 222  
      */
 223  
     public List<String> goals;
 224  
 
 225  
     /**
 226  
      * contains osgi metadata Bundle-Version if available
 227  
      * @since 4.1.2
 228  
      */
 229  
     public String bundleVersion;
 230  
 
 231  
     /**
 232  
      * contains osgi metadata Bundle-SymbolicName if available
 233  
      * @since 4.1.2
 234  
      */
 235  
     public String bundleSymbolicName;
 236  
 
 237  
     /**
 238  
      * contains osgi metadata Export-Package if available
 239  
      * @since 4.1.2
 240  
      */
 241  
     public String bundleExportPackage;
 242  
 
 243  
     /**
 244  
      * contains osgi metadata Export-Service if available
 245  
      * @since 4.1.2
 246  
      */
 247  
     public String bundleExportService;
 248  
 
 249  
     /**
 250  
      * contains osgi metadata Bundle-Description if available
 251  
      * @since 4.1.2
 252  
      */
 253  
     public String bundleDescription;
 254  
 
 255  
     /**
 256  
      * contains osgi metadata Bundle-Name if available
 257  
      * @since 4.1.2
 258  
      */
 259  
     public String bundleName;
 260  
 
 261  
     /**
 262  
      * contains osgi metadata Bundle-License if available
 263  
      * @since 4.1.2
 264  
      */
 265  
     public String bundleLicense;
 266  
 
 267  
     /**
 268  
      * contains osgi metadata Bundle-DocURL if available
 269  
      * @since 4.1.2
 270  
      */
 271  
     public String bundleDocUrl;
 272  
 
 273  
     /**
 274  
      * contains osgi metadata Import-Package if available
 275  
      * @since 4.1.2
 276  
      */
 277  
     public String bundleImportPackage;
 278  
 
 279  
     /**
 280  
      * contains osgi metadata Require-Bundle if available
 281  
      * @since 4.1.2
 282  
      */
 283  
     public String bundleRequireBundle;
 284  
 
 285  239986
     private String uinfo = null;
 286  
 
 287  239986
     private final Map<String, String> attributes = new HashMap<String, String>();
 288  
 
 289  239986
     private final List<MatchHighlight> matchHighlights = new ArrayList<MatchHighlight>();
 290  
 
 291  
     private final transient VersionScheme versionScheme;
 292  
 
 293  
     public ArtifactInfo()
 294  239986
     {
 295  239986
         versionScheme = new GenericVersionScheme();
 296  239986
     }
 297  
 
 298  
     public ArtifactInfo( String repository, String groupId, String artifactId, String version, String classifier )
 299  
     {
 300  14693
         this();
 301  14693
         this.repository = repository;
 302  14693
         this.groupId = groupId;
 303  14693
         this.artifactId = artifactId;
 304  14693
         this.version = version;
 305  14693
         this.classifier = classifier;
 306  14693
     }
 307  
 
 308  
     public Version getArtifactVersion()
 309  
     {
 310  3765202
         if ( artifactVersion == null )
 311  
         {
 312  
             try
 313  
             {
 314  206940
                 artifactVersion = versionScheme.parseVersion( version );
 315  
             }
 316  0
             catch ( InvalidVersionSpecificationException e )
 317  
             {
 318  
                 // will not happen, only with version ranges but we should not have those
 319  
                 // we handle POM versions here, not dependency versions
 320  206940
             }
 321  
         }
 322  
 
 323  3765202
         return artifactVersion;
 324  
     }
 325  
 
 326  
     public float getLuceneScore()
 327  
     {
 328  4
         return luceneScore;
 329  
     }
 330  
 
 331  
     public void setLuceneScore( float score )
 332  
     {
 333  376
         this.luceneScore = score;
 334  376
     }
 335  
 
 336  
     public String getUinfo()
 337  
     {
 338  49530
         if ( uinfo == null )
 339  
         {
 340  32370
             uinfo = new StringBuilder() //
 341  
             .append( groupId ).append( FS ) //
 342  
             .append( artifactId ).append( FS ) //
 343  
             .append( version ).append( FS ) //
 344  
             .append( nvl( classifier ) ) //
 345  
             .append( StringUtils.isEmpty( classifier ) || StringUtils.isEmpty( packaging ) ? "" : FS + packaging ) //
 346  
             .toString(); // extension is stored in the packaging field when classifier is not used
 347  
         }
 348  
 
 349  49530
         return uinfo;
 350  
     }
 351  
 
 352  
     public String getRootGroup()
 353  
     {
 354  11614
         int n = groupId.indexOf( '.' );
 355  11614
         if ( n > -1 )
 356  
         {
 357  8623
             return groupId.substring( 0, n );
 358  
         }
 359  2991
         return groupId;
 360  
     }
 361  
 
 362  
     public Gav calculateGav()
 363  
     {
 364  5567
         return new Gav( groupId, artifactId, version, classifier, fextension, null, // snapshotBuildNumber
 365  
             null, // snapshotTimeStamp
 366  
             fname, // name
 367  
             false, // hash
 368  
             null, // hashType
 369  
             false, // signature
 370  
             null ); // signatureType
 371  
     }
 372  
 
 373  
     public Map<String, String> getAttributes()
 374  
     {
 375  4
         return attributes;
 376  
     }
 377  
 
 378  
     public List<MatchHighlight> getMatchHighlights()
 379  
     {
 380  25
         return matchHighlights;
 381  
     }
 382  
 
 383  
     @Override
 384  
     public String toString()
 385  
     {
 386  1667
         return new StringBuilder( groupId ).append( ':' ).append( artifactId ) //
 387  
         .append( ':' ).append( version ) //
 388  
         .append( ':' ).append( classifier ) //
 389  
         .append( ':' ).append( packaging ).toString();
 390  
     }
 391  
 
 392  1
     private static final List<Field> DEFAULT_FIELDS = new ArrayList<Field>();
 393  
     static
 394  
     {
 395  1
         DEFAULT_FIELDS.add( MAVEN.GROUP_ID );
 396  1
         DEFAULT_FIELDS.add( MAVEN.ARTIFACT_ID );
 397  1
         DEFAULT_FIELDS.add( MAVEN.VERSION );
 398  1
         DEFAULT_FIELDS.add( MAVEN.PACKAGING );
 399  1
         DEFAULT_FIELDS.add( MAVEN.CLASSIFIER );
 400  1
         DEFAULT_FIELDS.add( MAVEN.SHA1 );
 401  1
         DEFAULT_FIELDS.add( MAVEN.NAME );
 402  1
         DEFAULT_FIELDS.add( MAVEN.DESCRIPTION );
 403  1
         DEFAULT_FIELDS.add( MAVEN.CLASSNAMES );
 404  1
         DEFAULT_FIELDS.add( MAVEN.REPOSITORY_ID );
 405  1
     }
 406  
 
 407  
     private List<Field> fields;
 408  
 
 409  
     public Collection<Field> getFields()
 410  
     {
 411  5
         if ( fields == null )
 412  
         {
 413  5
             fields = new ArrayList<Field>( DEFAULT_FIELDS.size() );
 414  
 
 415  5
             fields.addAll( DEFAULT_FIELDS );
 416  
         }
 417  
 
 418  5
         return fields;
 419  
     }
 420  
 
 421  
     /**
 422  
      * This method will disappear, once we drop ArtifactInfo.
 423  
      * 
 424  
      * @param field
 425  
      * @return
 426  
      */
 427  
     public String getFieldValue( Field field )
 428  
     {
 429  110
         if ( MAVEN.GROUP_ID.equals( field ) )
 430  
         {
 431  60
             return groupId;
 432  
         }
 433  50
         else if ( MAVEN.ARTIFACT_ID.equals( field ) )
 434  
         {
 435  45
             return artifactId;
 436  
         }
 437  5
         else if ( MAVEN.VERSION.equals( field ) )
 438  
         {
 439  0
             return version;
 440  
         }
 441  5
         else if ( MAVEN.PACKAGING.equals( field ) )
 442  
         {
 443  0
             return packaging;
 444  
         }
 445  5
         else if ( MAVEN.CLASSIFIER.equals( field ) )
 446  
         {
 447  0
             return classifier;
 448  
         }
 449  5
         else if ( MAVEN.SHA1.equals( field ) )
 450  
         {
 451  0
             return sha1;
 452  
         }
 453  5
         else if ( MAVEN.NAME.equals( field ) )
 454  
         {
 455  0
             return name;
 456  
         }
 457  5
         else if ( MAVEN.DESCRIPTION.equals( field ) )
 458  
         {
 459  0
             return description;
 460  
         }
 461  5
         else if ( MAVEN.CLASSNAMES.equals( field ) )
 462  
         {
 463  5
             return classNames;
 464  
         }
 465  0
         else if ( MAVEN.REPOSITORY_ID.equals( field ) )
 466  
         {
 467  0
             return repository;
 468  
         }
 469  
 
 470  
         // no match
 471  0
         return null;
 472  
     }
 473  
 
 474  
     public ArtifactInfo setFieldValue( Field field, String value )
 475  
     {
 476  40
         if ( MAVEN.GROUP_ID.equals( field ) )
 477  
         {
 478  0
             groupId = value;
 479  
         }
 480  40
         else if ( MAVEN.ARTIFACT_ID.equals( field ) )
 481  
         {
 482  0
             artifactId = value;
 483  
         }
 484  40
         else if ( MAVEN.VERSION.equals( field ) )
 485  
         {
 486  5
             version = value;
 487  
         }
 488  35
         else if ( MAVEN.PACKAGING.equals( field ) )
 489  
         {
 490  5
             packaging = value;
 491  
         }
 492  30
         else if ( MAVEN.CLASSIFIER.equals( field ) )
 493  
         {
 494  5
             classifier = value;
 495  
         }
 496  25
         else if ( MAVEN.SHA1.equals( field ) )
 497  
         {
 498  5
             sha1 = value;
 499  
         }
 500  20
         else if ( MAVEN.NAME.equals( field ) )
 501  
         {
 502  5
             name = value;
 503  
         }
 504  15
         else if ( MAVEN.DESCRIPTION.equals( field ) )
 505  
         {
 506  5
             description = value;
 507  
         }
 508  10
         else if ( MAVEN.CLASSNAMES.equals( field ) )
 509  
         {
 510  5
             classNames = value;
 511  
         }
 512  5
         else if ( MAVEN.REPOSITORY_ID.equals( field ) )
 513  
         {
 514  5
             repository = value;
 515  
         }
 516  
 
 517  
         // no match
 518  40
         return this;
 519  
     }
 520  
 
 521  
     // ----------------------------------------------------------------------------
 522  
     // Utils
 523  
     // ----------------------------------------------------------------------------
 524  
 
 525  
     public static String nvl( String v )
 526  
     {
 527  32370
         return v == null ? NA : v;
 528  
     }
 529  
 
 530  
     public static String renvl( String v )
 531  
     {
 532  225296
         return NA.equals( v ) ? null : v;
 533  
     }
 534  
 
 535  
     public static String lst2str( Collection<String> list )
 536  
     {
 537  1972
         StringBuilder sb = new StringBuilder();
 538  1972
         for ( String s : list )
 539  
         {
 540  15353
             sb.append( s ).append( ArtifactInfo.FS );
 541  
         }
 542  1972
         return sb.length() == 0 ? sb.toString() : sb.substring( 0, sb.length() - 1 );
 543  
     }
 544  
 
 545  
     public static List<String> str2lst( String str )
 546  
     {
 547  1439
         return Arrays.asList( ArtifactInfo.FS_PATTERN.split( str ) );
 548  
     }
 549  
 
 550  
     /**
 551  
      * A version comparator
 552  
      */
 553  1883777
     static class VersionComparator
 554  
         implements Comparator<ArtifactInfo>
 555  
     {
 556  
         public int compare( final ArtifactInfo f1, final ArtifactInfo f2 )
 557  
         {
 558  1883879
             int n = f1.groupId.compareTo( f2.groupId );
 559  1883879
             if ( n != 0 )
 560  
             {
 561  796
                 return n;
 562  
             }
 563  
 
 564  1883083
             n = f1.artifactId.compareTo( f2.artifactId );
 565  1883083
             if ( n != 0 )
 566  
             {
 567  482
                 return n;
 568  
             }
 569  
 
 570  1882601
             n = -f1.getArtifactVersion().compareTo( f2.getArtifactVersion() );
 571  1882601
             if ( n != 0 )
 572  
             {
 573  1881808
                 return n;
 574  
             }
 575  
 
 576  
             {
 577  793
                 final String c1 = f1.classifier;
 578  793
                 final String c2 = f2.classifier;
 579  793
                 if ( c1 == null )
 580  
                 {
 581  52
                     if ( c2 != null )
 582  
                     {
 583  32
                         return -1;
 584  
                     }
 585  
                 }
 586  
                 else
 587  
                 {
 588  741
                     if ( c2 == null )
 589  
                     {
 590  528
                         return 1;
 591  
                     }
 592  
 
 593  213
                     n = c1.compareTo( c2 );
 594  213
                     if ( n != 0 )
 595  
                     {
 596  150
                         return n;
 597  
                     }
 598  
                 }
 599  
             }
 600  
 
 601  
             {
 602  83
                 final String p1 = f1.packaging;
 603  83
                 final String p2 = f2.packaging;
 604  83
                 if ( p1 == null )
 605  
                 {
 606  0
                     return p2 == null ? 0 : -1;
 607  
                 }
 608  
                 else
 609  
                 {
 610  83
                     return p2 == null ? 1 : p1.compareTo( p2 );
 611  
                 }
 612  
             }
 613  
         }
 614  
     }
 615  
 
 616  
     /**
 617  
      * A repository and version comparator
 618  
      */
 619  1
     static class RepositoryVersionComparator
 620  
         extends VersionComparator
 621  
     {
 622  
         @Override
 623  
         public int compare( final ArtifactInfo f1, final ArtifactInfo f2 )
 624  
         {
 625  0
             final int n = super.compare( f1, f2 );
 626  0
             if ( n != 0 )
 627  
             {
 628  0
                 return n;
 629  
             }
 630  
 
 631  0
             final String r1 = f1.repository;
 632  0
             final String r2 = f2.repository;
 633  0
             if ( r1 == null )
 634  
             {
 635  0
                 return r2 == null ? 0 : -1;
 636  
             }
 637  
             else
 638  
             {
 639  0
                 return r2 == null ? 1 : r1.compareTo( r2 );
 640  
             }
 641  
         }
 642  
     }
 643  
     
 644  
     /**
 645  
      * A context and version comparator
 646  
      */
 647  106
     static class ContextVersionComparator
 648  
         extends VersionComparator
 649  
     {
 650  
         @Override
 651  
         public int compare( final ArtifactInfo f1, final ArtifactInfo f2 )
 652  
         {
 653  105
             final int n = super.compare( f1, f2 );
 654  105
             if ( n != 0 )
 655  
             {
 656  75
                 return n;
 657  
             }
 658  
 
 659  30
             final String r1 = f1.context;
 660  30
             final String r2 = f2.context;
 661  30
             if ( r1 == null )
 662  
             {
 663  0
                 return r2 == null ? 0 : -1;
 664  
             }
 665  
             else
 666  
             {
 667  30
                 return r2 == null ? 1 : r1.compareTo( r2 );
 668  
             }
 669  
         }
 670  
     }
 671  
 
 672  
 }