View Javadoc
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 javax.inject.Named;
23  import javax.inject.Singleton;
24  import java.io.File;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.zip.ZipFile;
29  
30  import org.apache.lucene.document.Document;
31  import org.apache.maven.index.ArtifactContext;
32  import org.apache.maven.index.ArtifactInfo;
33  import org.apache.maven.index.IndexerField;
34  
35  /**
36   * A Maven Archetype index creator used to detect and correct the artifact packaging to "maven-archetype" if the
37   * inspected JAR is an Archetype. Since packaging is already handled by Minimal creator, this Creator only alters the
38   * supplied ArtifactInfo packaging field during processing, but does not interferes with Lucene document fill-up or the
39   * ArtifactInfo fill-up (the update* methods are empty).
40   * 
41   * @author cstamas
42   */
43  @Singleton
44  @Named( MavenArchetypeArtifactInfoIndexCreator.ID )
45  public class MavenArchetypeArtifactInfoIndexCreator
46      extends AbstractIndexCreator
47  {
48      public static final String ID = "maven-archetype";
49  
50      private static final String MAVEN_ARCHETYPE_PACKAGING = "maven-archetype";
51  
52      private static final String[] ARCHETYPE_XML_LOCATIONS =
53          { "META-INF/maven/archetype.xml", "META-INF/archetype.xml", "META-INF/maven/archetype-metadata.xml" };
54  
55      public MavenArchetypeArtifactInfoIndexCreator()
56      {
57          super( ID, Arrays.asList( MinimalArtifactInfoIndexCreator.ID ) );
58      }
59  
60      public void populateArtifactInfo( ArtifactContext ac )
61      {
62          File artifact = ac.getArtifact();
63  
64          ArtifactInfo ai = ac.getArtifactInfo();
65  
66          // we need the file to perform these checks, and those may be only JARs
67          if ( artifact != null && artifact.isFile() && !MAVEN_ARCHETYPE_PACKAGING.equals( ai.getPackaging() )
68              && artifact.getName().endsWith( ".jar" ) )
69          {
70              // TODO: recheck, is the following true? "Maven plugins and Maven Archetypes can be only JARs?"
71  
72              // check for maven archetype, since Archetypes seems to not have consistent packaging,
73              // and depending on the contents of the JAR, this call will override the packaging to "maven-archetype"!
74              checkMavenArchetype( ai, artifact );
75          }
76      }
77  
78      /**
79       * Archetypes that are added will have their packaging types set correctly (to maven-archetype)
80       * 
81       * @param ai
82       * @param artifact
83       */
84      private void checkMavenArchetype( ArtifactInfo ai, File artifact )
85      {
86          try ( ZipFile zipFile = new ZipFile( artifact ) )
87          {
88              for ( String path : ARCHETYPE_XML_LOCATIONS )
89              {
90                  if ( zipFile.getEntry( path ) != null )
91                  {
92                      ai.setPackaging( MAVEN_ARCHETYPE_PACKAGING );
93  
94                      return;
95                  }
96              }
97          }
98          catch ( Exception e )
99          {
100             if ( getLogger().isDebugEnabled() )
101             {
102                 getLogger().info(
103                     "Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to exception:", e );
104             }
105             else
106             {
107                 getLogger().info(
108                     "Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to " + e.getMessage() );
109             }
110         }
111     }
112 
113     public void updateDocument( ArtifactInfo ai, Document doc )
114     {
115         // nothing to update, minimal will maintain it.
116     }
117 
118     public boolean updateArtifactInfo( Document doc, ArtifactInfo ai )
119     {
120         // nothing to update, minimal will maintain it.
121 
122         return false;
123     }
124 
125     // ==
126 
127     @Override
128     public String toString()
129     {
130         return ID;
131     }
132 
133     public Collection<IndexerField> getIndexerFields()
134     {
135         // it does not "add" any new field, it actually updates those already maintained by minimal creator.
136         return Collections.emptyList();
137     }
138 }