Coverage Report - org.apache.maven.index.creator.MinimalArtifactInfoIndexCreator
 
Classes in this File Line Coverage Branch Coverage Complexity
MinimalArtifactInfoIndexCreator
94 %
129/137
84 %
61/72
6
 
 1  
 package org.apache.maven.index.creator;
 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.IOException;
 24  
 import java.util.Arrays;
 25  
 import java.util.Collection;
 26  
 
 27  
 import org.apache.lucene.document.Document;
 28  
 import org.apache.lucene.document.Field;
 29  
 import org.apache.lucene.document.Field.Index;
 30  
 import org.apache.lucene.document.Field.Store;
 31  
 import org.apache.maven.index.ArtifactAvailablility;
 32  
 import org.apache.maven.index.ArtifactContext;
 33  
 import org.apache.maven.index.ArtifactInfo;
 34  
 import org.apache.maven.index.IndexerField;
 35  
 import org.apache.maven.index.IndexerFieldVersion;
 36  
 import org.apache.maven.index.MAVEN;
 37  
 import org.apache.maven.index.NEXUS;
 38  
 import org.apache.maven.index.artifact.Gav;
 39  
 import org.apache.maven.index.context.IndexCreator;
 40  
 import org.apache.maven.index.locator.JavadocLocator;
 41  
 import org.apache.maven.index.locator.Locator;
 42  
 import org.apache.maven.index.locator.Sha1Locator;
 43  
 import org.apache.maven.index.locator.SignatureLocator;
 44  
 import org.apache.maven.index.locator.SourcesLocator;
 45  
 import org.apache.maven.model.Model;
 46  
 import org.codehaus.plexus.component.annotations.Component;
 47  
 import org.codehaus.plexus.util.FileUtils;
 48  
 import org.codehaus.plexus.util.StringUtils;
 49  
 
 50  
 /**
 51  
  * A minimal index creator used to provide basic information about Maven artifact. This creator will create the index
 52  
  * fast, will not open any file to be fastest as possible but it has some drawbacks: The information gathered by this
 53  
  * creator are sometimes based on "best-effort" only, and does not reflect the reality (ie. maven archetype packaging @see
 54  
  * {@link MavenArchetypeArtifactInfoIndexCreator}).
 55  
  * 
 56  
  * @author cstamas
 57  
  */
 58  
 @Component( role = IndexCreator.class, hint = MinimalArtifactInfoIndexCreator.ID )
 59  
 public class MinimalArtifactInfoIndexCreator
 60  
     extends AbstractIndexCreator
 61  
     implements LegacyDocumentUpdater
 62  
 {
 63  
     public static final String ID = "min";
 64  
 
 65  
     /**
 66  
      * Info: packaging, lastModified, size, sourcesExists, javadocExists, signatureExists. Stored, not indexed.
 67  
      */
 68  1
     public static final IndexerField FLD_INFO = new IndexerField( NEXUS.INFO, IndexerFieldVersion.V1, "i",
 69  
         "Artifact INFO (not indexed, stored)", Store.YES, Index.NO );
 70  
 
 71  1
     public static final IndexerField FLD_GROUP_ID_KW = new IndexerField( MAVEN.GROUP_ID, IndexerFieldVersion.V1, "g",
 72  
         "Artifact GroupID (as keyword)", Store.NO, Index.NOT_ANALYZED );
 73  
 
 74  1
     public static final IndexerField FLD_GROUP_ID = new IndexerField( MAVEN.GROUP_ID, IndexerFieldVersion.V3,
 75  
         "groupId", "Artifact GroupID (tokenized)", Store.NO, Index.ANALYZED );
 76  
 
 77  1
     public static final IndexerField FLD_ARTIFACT_ID_KW = new IndexerField( MAVEN.ARTIFACT_ID, IndexerFieldVersion.V1,
 78  
         "a", "Artifact ArtifactID (as keyword)", Store.NO, Index.NOT_ANALYZED );
 79  
 
 80  1
     public static final IndexerField FLD_ARTIFACT_ID = new IndexerField( MAVEN.ARTIFACT_ID, IndexerFieldVersion.V3,
 81  
         "artifactId", "Artifact ArtifactID (tokenized)", Store.NO, Index.ANALYZED );
 82  
 
 83  1
     public static final IndexerField FLD_VERSION_KW = new IndexerField( MAVEN.VERSION, IndexerFieldVersion.V1, "v",
 84  
         "Artifact Version (as keyword)", Store.NO, Index.NOT_ANALYZED );
 85  
 
 86  1
     public static final IndexerField FLD_VERSION = new IndexerField( MAVEN.VERSION, IndexerFieldVersion.V3, "version",
 87  
         "Artifact Version (tokenized)", Store.NO, Index.ANALYZED );
 88  
 
 89  1
     public static final IndexerField FLD_PACKAGING = new IndexerField( MAVEN.PACKAGING, IndexerFieldVersion.V1, "p",
 90  
         "Artifact Packaging (as keyword)", Store.NO, Index.NOT_ANALYZED );
 91  
 
 92  1
     public static final IndexerField FLD_CLASSIFIER = new IndexerField( MAVEN.CLASSIFIER, IndexerFieldVersion.V1, "l",
 93  
         "Artifact classifier (as keyword)", Store.NO, Index.NOT_ANALYZED );
 94  
 
 95  1
     public static final IndexerField FLD_NAME = new IndexerField( MAVEN.NAME, IndexerFieldVersion.V1, "n",
 96  
         "Artifact name (tokenized, stored)", Store.YES, Index.ANALYZED );
 97  
 
 98  1
     public static final IndexerField FLD_DESCRIPTION = new IndexerField( MAVEN.DESCRIPTION, IndexerFieldVersion.V1,
 99  
         "d", "Artifact description (tokenized, stored)", Store.YES, Index.ANALYZED );
 100  
 
 101  1
     public static final IndexerField FLD_LAST_MODIFIED = new IndexerField( MAVEN.LAST_MODIFIED, IndexerFieldVersion.V1,
 102  
         "m", "Artifact last modified (not indexed, stored)", Store.YES, Index.NO );
 103  
 
 104  1
     public static final IndexerField FLD_SHA1 = new IndexerField( MAVEN.SHA1, IndexerFieldVersion.V1, "1",
 105  
         "Artifact SHA1 checksum (as keyword, stored)", Store.YES, Index.NOT_ANALYZED );
 106  
 
 107  213
     private Locator jl = new JavadocLocator();
 108  
 
 109  213
     private Locator sl = new SourcesLocator();
 110  
 
 111  213
     private Locator sigl = new SignatureLocator();
 112  
 
 113  213
     private Locator sha1l = new Sha1Locator();
 114  
 
 115  
     public MinimalArtifactInfoIndexCreator()
 116  
     {
 117  213
         super( ID );
 118  213
     }
 119  
 
 120  
     public void populateArtifactInfo( ArtifactContext ac )
 121  
     {
 122  11575
         File artifact = ac.getArtifact();
 123  
 
 124  11575
         File pom = ac.getPom();
 125  
 
 126  11575
         ArtifactInfo ai = ac.getArtifactInfo();
 127  
 
 128  11575
         if ( pom != null )
 129  
         {
 130  6019
             ai.lastModified = pom.lastModified();
 131  
 
 132  6019
             ai.fextension = "pom";
 133  
         }
 134  
 
 135  
         // TODO handle artifacts without poms
 136  11575
         if ( pom != null )
 137  
         {
 138  6019
             if ( ai.classifier != null )
 139  
             {
 140  2523
                 ai.sourcesExists = ArtifactAvailablility.NOT_AVAILABLE;
 141  
 
 142  2523
                 ai.javadocExists = ArtifactAvailablility.NOT_AVAILABLE;
 143  
             }
 144  
             else
 145  
             {
 146  3496
                 File sources = sl.locate( pom );
 147  3496
                 if ( !sources.exists() )
 148  
                 {
 149  2309
                     ai.sourcesExists = ArtifactAvailablility.NOT_PRESENT;
 150  
                 }
 151  
                 else
 152  
                 {
 153  1187
                     ai.sourcesExists = ArtifactAvailablility.PRESENT;
 154  
                 }
 155  
 
 156  3496
                 File javadoc = jl.locate( pom );
 157  3496
                 if ( !javadoc.exists() )
 158  
                 {
 159  2668
                     ai.javadocExists = ArtifactAvailablility.NOT_PRESENT;
 160  
                 }
 161  
                 else
 162  
                 {
 163  828
                     ai.javadocExists = ArtifactAvailablility.PRESENT;
 164  
                 }
 165  
             }
 166  
         }
 167  
 
 168  11575
         Model model = ac.getPomModel();
 169  
 
 170  11575
         if ( model != null )
 171  
         {
 172  5643
             ai.name = model.getName();
 173  
 
 174  5643
             ai.description = model.getDescription();
 175  
 
 176  
             // for main artifacts (without classifier) only:
 177  5643
             if ( ai.classifier == null )
 178  
             {
 179  
                 // only when this is not a classified artifact
 180  3120
                 if ( model.getPackaging() != null )
 181  
                 {
 182  
                     // set the read value that is coming from POM
 183  878
                     ai.packaging = model.getPackaging();
 184  
                 }
 185  
                 else
 186  
                 {
 187  
                     // default it, since POM is present, is read, but does not contain explicit packaging
 188  
                     // TODO: this change breaks junit tests, but not sure why is "null" expected value?
 189  
                     // ai.packaging = "jar";
 190  
                 }
 191  
             }
 192  
         }
 193  
 
 194  11575
         if ( "pom".equals( ai.packaging ) )
 195  
         {
 196  
             // special case, the POM _is_ the artifact
 197  270
             artifact = pom;
 198  
         }
 199  
 
 200  11575
         if ( artifact != null )
 201  
         {
 202  6011
             File signature = sigl.locate( artifact );
 203  
 
 204  6011
             ai.signatureExists = signature.exists() ? ArtifactAvailablility.PRESENT : ArtifactAvailablility.NOT_PRESENT;
 205  
 
 206  6011
             File sha1 = sha1l.locate( artifact );
 207  
 
 208  6011
             if ( sha1.exists() )
 209  
             {
 210  
                 try
 211  
                 {
 212  4987
                     ai.sha1 = StringUtils.chomp( FileUtils.fileRead( sha1 ) ).trim().split( " " )[0];
 213  
                 }
 214  0
                 catch ( IOException e )
 215  
                 {
 216  0
                     ac.addError( e );
 217  4987
                 }
 218  
             }
 219  
 
 220  6011
             ai.lastModified = artifact.lastModified();
 221  
 
 222  6011
             ai.size = artifact.length();
 223  
 
 224  6011
             ai.fextension = getExtension( artifact, ac.getGav() );
 225  
 
 226  6011
             if ( ai.packaging == null )
 227  
             {
 228  2611
                 ai.packaging = ai.fextension;
 229  
             }
 230  
         }
 231  11575
     }
 232  
 
 233  
     private String getExtension( File artifact, Gav gav )
 234  
     {
 235  6011
         if ( gav != null && StringUtils.isNotBlank( gav.getExtension() ) )
 236  
         {
 237  6011
             return gav.getExtension();
 238  
         }
 239  
 
 240  
         // last resort, the extension of the file
 241  0
         String artifactFileName = artifact.getName().toLowerCase();
 242  
 
 243  
         // tar.gz? and other "special" combinations
 244  0
         if ( artifactFileName.endsWith( "tar.gz" ) )
 245  
         {
 246  0
             return "tar.gz";
 247  
         }
 248  0
         else if ( artifactFileName.equals( "tar.bz2" ) )
 249  
         {
 250  0
             return "tar.bz2";
 251  
         }
 252  
 
 253  
         // get the part after the last dot
 254  0
         return FileUtils.getExtension( artifactFileName );
 255  
     }
 256  
 
 257  
     public void updateDocument( ArtifactInfo ai, Document doc )
 258  
     {
 259  29162
         String info =
 260  
             new StringBuilder().append( ai.packaging ).append( ArtifactInfo.FS ).append(
 261  
                 Long.toString( ai.lastModified ) ).append( ArtifactInfo.FS ).append( Long.toString( ai.size ) ).append(
 262  
                 ArtifactInfo.FS ).append( ai.sourcesExists.toString() ).append( ArtifactInfo.FS ).append(
 263  
                 ai.javadocExists.toString() ).append( ArtifactInfo.FS ).append( ai.signatureExists.toString() ).append(
 264  
                 ArtifactInfo.FS ).append( ai.fextension ).toString();
 265  
 
 266  29162
         doc.add( FLD_INFO.toField( info ) );
 267  
 
 268  29162
         doc.add( FLD_GROUP_ID_KW.toField( ai.groupId ) );
 269  29162
         doc.add( FLD_ARTIFACT_ID_KW.toField( ai.artifactId ) );
 270  29162
         doc.add( FLD_VERSION_KW.toField( ai.version ) );
 271  
 
 272  
         // V3
 273  29162
         doc.add( FLD_GROUP_ID.toField( ai.groupId ) );
 274  29162
         doc.add( FLD_ARTIFACT_ID.toField( ai.artifactId ) );
 275  29162
         doc.add( FLD_VERSION.toField( ai.version ) );
 276  
 
 277  29162
         if ( ai.name != null )
 278  
         {
 279  17377
             doc.add( FLD_NAME.toField( ai.name ) );
 280  
         }
 281  
 
 282  29162
         if ( ai.description != null )
 283  
         {
 284  15075
             doc.add( FLD_DESCRIPTION.toField( ai.description ) );
 285  
         }
 286  
 
 287  29162
         if ( ai.packaging != null )
 288  
         {
 289  21809
             doc.add( FLD_PACKAGING.toField( ai.packaging ) );
 290  
         }
 291  
 
 292  29162
         if ( ai.classifier != null )
 293  
         {
 294  9168
             doc.add( FLD_CLASSIFIER.toField( ai.classifier ) );
 295  
         }
 296  
 
 297  29162
         if ( ai.sha1 != null )
 298  
         {
 299  17885
             doc.add( FLD_SHA1.toField( ai.sha1 ) );
 300  
         }
 301  29162
     }
 302  
 
 303  
     public void updateLegacyDocument( ArtifactInfo ai, Document doc )
 304  
     {
 305  16384
         updateDocument( ai, doc );
 306  
 
 307  
         // legacy!
 308  16384
         if ( ai.prefix != null )
 309  
         {
 310  624
             doc.add( new Field( ArtifactInfo.PLUGIN_PREFIX, ai.prefix, Field.Store.YES, Field.Index.NOT_ANALYZED ) );
 311  
         }
 312  
 
 313  16384
         if ( ai.goals != null )
 314  
         {
 315  624
             doc.add( new Field( ArtifactInfo.PLUGIN_GOALS, ArtifactInfo.lst2str( ai.goals ), Field.Store.YES,
 316  
                 Field.Index.NO ) );
 317  
         }
 318  
 
 319  16384
         doc.removeField( ArtifactInfo.GROUP_ID );
 320  16384
         doc.add( new Field( ArtifactInfo.GROUP_ID, ai.groupId, Field.Store.NO, Field.Index.NOT_ANALYZED ) );
 321  16384
     }
 322  
 
 323  
     public boolean updateArtifactInfo( Document doc, ArtifactInfo ai )
 324  
     {
 325  225287
         boolean res = false;
 326  
 
 327  225287
         String uinfo = doc.get( ArtifactInfo.UINFO );
 328  
 
 329  225287
         if ( uinfo != null )
 330  
         {
 331  225287
             String[] r = ArtifactInfo.FS_PATTERN.split( uinfo );
 332  
 
 333  225287
             ai.groupId = r[0];
 334  
 
 335  225287
             ai.artifactId = r[1];
 336  
 
 337  225287
             ai.version = r[2];
 338  
 
 339  225287
             if ( r.length > 3 )
 340  
             {
 341  225287
                 ai.classifier = ArtifactInfo.renvl( r[3] );
 342  
             }
 343  
 
 344  225287
             res = true;
 345  
         }
 346  
 
 347  225287
         String info = doc.get( ArtifactInfo.INFO );
 348  
 
 349  225287
         if ( info != null )
 350  
         {
 351  225287
             String[] r = ArtifactInfo.FS_PATTERN.split( info );
 352  
 
 353  225287
             ai.packaging = r[0];
 354  
 
 355  225287
             ai.lastModified = Long.parseLong( r[1] );
 356  
 
 357  225287
             ai.size = Long.parseLong( r[2] );
 358  
 
 359  225287
             ai.sourcesExists = ArtifactAvailablility.fromString( r[3] );
 360  
 
 361  225287
             ai.javadocExists = ArtifactAvailablility.fromString( r[4] );
 362  
 
 363  225287
             ai.signatureExists = ArtifactAvailablility.fromString( r[5] );
 364  
 
 365  225287
             if ( r.length > 6 )
 366  
             {
 367  224979
                 ai.fextension = r[6];
 368  
             }
 369  
             else
 370  
             {
 371  308
                 if ( ai.classifier != null //
 372  
                     || "pom".equals( ai.packaging ) //
 373  
                     || "war".equals( ai.packaging ) //
 374  
                     || "ear".equals( ai.packaging ) )
 375  
                 {
 376  66
                     ai.fextension = ai.packaging;
 377  
                 }
 378  
                 else
 379  
                 {
 380  242
                     ai.fextension = "jar"; // best guess
 381  
                 }
 382  
             }
 383  
 
 384  225287
             res = true;
 385  
         }
 386  
 
 387  225287
         String name = doc.get( ArtifactInfo.NAME );
 388  
 
 389  225287
         if ( name != null )
 390  
         {
 391  14114
             ai.name = name;
 392  
 
 393  14114
             res = true;
 394  
         }
 395  
 
 396  225287
         String description = doc.get( ArtifactInfo.DESCRIPTION );
 397  
 
 398  225287
         if ( description != null )
 399  
         {
 400  12246
             ai.description = description;
 401  
 
 402  12246
             res = true;
 403  
         }
 404  
 
 405  
         // sometimes there's a pom without packaging(default to jar), but no artifact, then the value will be a "null"
 406  
         // String
 407  225287
         if ( "null".equals( ai.packaging ) )
 408  
         {
 409  207654
             ai.packaging = null;
 410  
         }
 411  
 
 412  225287
         String sha1 = doc.get( ArtifactInfo.SHA1 );
 413  
 
 414  225287
         if ( sha1 != null )
 415  
         {
 416  14374
             ai.sha1 = sha1;
 417  
         }
 418  
 
 419  225287
         return res;
 420  
 
 421  
         // artifactInfo.fname = ???
 422  
     }
 423  
 
 424  
     // ==
 425  
 
 426  
     @Override
 427  
     public String toString()
 428  
     {
 429  7
         return ID;
 430  
     }
 431  
 
 432  
     public Collection<IndexerField> getIndexerFields()
 433  
     {
 434  475
         return Arrays.asList( FLD_INFO, FLD_GROUP_ID_KW, FLD_GROUP_ID, FLD_ARTIFACT_ID_KW, FLD_ARTIFACT_ID,
 435  
             FLD_VERSION_KW, FLD_VERSION, FLD_PACKAGING, FLD_CLASSIFIER, FLD_NAME, FLD_DESCRIPTION, FLD_LAST_MODIFIED,
 436  
             FLD_SHA1 );
 437  
     }
 438  
 }