View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.index.creator;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
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 extends AbstractIndexCreator {
46      public static final String ID = "maven-archetype";
47  
48      private static final String MAVEN_ARCHETYPE_PACKAGING = "maven-archetype";
49  
50      private static final String[] ARCHETYPE_XML_LOCATIONS = {
51          "META-INF/maven/archetype.xml", "META-INF/archetype.xml", "META-INF/maven/archetype-metadata.xml"
52      };
53  
54      public MavenArchetypeArtifactInfoIndexCreator() {
55          super(ID, Arrays.asList(MinimalArtifactInfoIndexCreator.ID));
56      }
57  
58      public void populateArtifactInfo(ArtifactContext ac) {
59          File artifact = ac.getArtifact();
60  
61          ArtifactInfo ai = ac.getArtifactInfo();
62  
63          // we need the file to perform these checks, and those may be only JARs
64          if (artifact != null
65                  && artifact.isFile()
66                  && !MAVEN_ARCHETYPE_PACKAGING.equals(ai.getPackaging())
67                  && artifact.getName().endsWith(".jar")) {
68              // TODO: recheck, is the following true? "Maven plugins and Maven Archetypes can be only JARs?"
69  
70              // check for maven archetype, since Archetypes seems to not have consistent packaging,
71              // and depending on the contents of the JAR, this call will override the packaging to "maven-archetype"!
72              checkMavenArchetype(ai, artifact);
73          }
74      }
75  
76      /**
77       * Archetypes that are added will have their packaging types set correctly (to maven-archetype)
78       *
79       * @param ai
80       * @param artifact
81       */
82      private void checkMavenArchetype(ArtifactInfo ai, File artifact) {
83          try (ZipFile zipFile = new ZipFile(artifact)) {
84              for (String path : ARCHETYPE_XML_LOCATIONS) {
85                  if (zipFile.getEntry(path) != null) {
86                      ai.setPackaging(MAVEN_ARCHETYPE_PACKAGING);
87  
88                      return;
89                  }
90              }
91          } catch (Exception e) {
92              if (getLogger().isDebugEnabled()) {
93                  getLogger()
94                          .info("Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to exception:", e);
95              } else {
96                  getLogger()
97                          .info("Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to "
98                                  + e.getMessage());
99              }
100         }
101     }
102 
103     public void updateDocument(ArtifactInfo ai, Document doc) {
104         // nothing to update, minimal will maintain it.
105     }
106 
107     public boolean updateArtifactInfo(Document doc, ArtifactInfo ai) {
108         // nothing to update, minimal will maintain it.
109 
110         return false;
111     }
112 
113     // ==
114 
115     @Override
116     public String toString() {
117         return ID;
118     }
119 
120     public Collection<IndexerField> getIndexerFields() {
121         // it does not "add" any new field, it actually updates those already maintained by minimal creator.
122         return Collections.emptyList();
123     }
124 }