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;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.nio.file.Files;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.zip.ZipEntry;
28  import java.util.zip.ZipFile;
29  
30  import org.apache.lucene.document.Document;
31  import org.apache.lucene.document.Field;
32  import org.apache.lucene.document.StoredField;
33  import org.apache.maven.index.artifact.Gav;
34  import org.apache.maven.index.context.IndexCreator;
35  import org.apache.maven.index.context.IndexingContext;
36  import org.apache.maven.model.Model;
37  import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  /**
43   * An artifact context used to provide information about artifact during scanning. It is passed to the
44   * {@link IndexCreator}, which can populate {@link ArtifactInfo} for the given artifact.
45   *
46   * @see IndexCreator#populateArtifactInfo(ArtifactContext)
47   * @author Jason van Zyl
48   * @author Tamas Cservenak
49   */
50  public class ArtifactContext {
51  
52      private static final Logger LOGGER = LoggerFactory.getLogger(ArtifactContext.class);
53  
54      private final File pom;
55  
56      private final File artifact;
57  
58      private final File metadata;
59  
60      private final ArtifactInfo artifactInfo;
61  
62      private final Gav gav;
63  
64      private final List<Exception> errors = new ArrayList<>();
65  
66      public ArtifactContext(File pom, File artifact, File metadata, ArtifactInfo artifactInfo, Gav gav)
67              throws IllegalArgumentException {
68          if (artifactInfo == null) {
69              throw new IllegalArgumentException("Parameter artifactInfo must not be null.");
70          }
71  
72          this.pom = pom;
73          this.artifact = artifact;
74          this.metadata = metadata;
75          this.artifactInfo = artifactInfo;
76          this.gav = gav == null ? artifactInfo.calculateGav() : gav;
77      }
78  
79      public File getPom() {
80          return pom;
81      }
82  
83      public Model getPomModel() {
84          // First check for local pom file
85          File pom = getPom();
86          if (pom != null && pom.isFile()) {
87              try (InputStream inputStream = Files.newInputStream(pom.toPath())) {
88                  return new MavenXpp3Reader().read(inputStream, false);
89              } catch (IOException | XmlPullParserException e) {
90                  LOGGER.warn("skip error reading pom: " + pom, e);
91              }
92          }
93          // Otherwise, check for pom contained in maven generated artifact
94          else if (getArtifact() != null && getArtifact().isFile()) {
95              try (ZipFile zipFile = new ZipFile(artifact)) {
96                  final String embeddedPomPath =
97                          "META-INF/maven/" + getGav().getGroupId() + "/" + getGav().getArtifactId() + "/pom.xml";
98  
99                  ZipEntry zipEntry = zipFile.getEntry(embeddedPomPath);
100 
101                 if (zipEntry != null) {
102                     try (InputStream inputStream = zipFile.getInputStream(zipEntry)) {
103                         return new MavenXpp3Reader().read(inputStream, false);
104                     }
105                 }
106             } catch (IOException | XmlPullParserException e) {
107                 LOGGER.warn("skip error reading pom withing artifact:" + artifact, e);
108             }
109         }
110 
111         return null;
112     }
113 
114     public File getArtifact() {
115         return artifact;
116     }
117 
118     public File getMetadata() {
119         return metadata;
120     }
121 
122     public ArtifactInfo getArtifactInfo() {
123         return artifactInfo;
124     }
125 
126     public Gav getGav() {
127         return gav;
128     }
129 
130     public List<Exception> getErrors() {
131         return errors;
132     }
133 
134     public void addError(Exception e) {
135         errors.add(e);
136     }
137 
138     /**
139      * Creates Lucene Document using {@link IndexCreator}s from the given {@link IndexingContext}.
140      */
141     public Document createDocument(IndexingContext context) {
142         Document doc = new Document();
143 
144         // unique key
145         doc.add(new Field(ArtifactInfo.UINFO, getArtifactInfo().getUinfo(), IndexerField.KEYWORD_STORED));
146 
147         doc.add(new StoredField(
148                 ArtifactInfo.LAST_MODIFIED, //
149                 Long.toString(System.currentTimeMillis())));
150 
151         for (IndexCreator indexCreator : context.getIndexCreators()) {
152             try {
153                 indexCreator.populateArtifactInfo(this);
154             } catch (IOException ex) {
155                 addError(ex);
156             }
157         }
158 
159         // need a second pass in case index creators updated document attributes
160         for (IndexCreator indexCreator : context.getIndexCreators()) {
161             indexCreator.updateDocument(getArtifactInfo(), doc);
162         }
163 
164         return doc;
165     }
166 }