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 }