View Javadoc

1   package org.apache.maven.index;
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.FileInputStream;
24  import java.io.FileNotFoundException;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.InputStreamReader;
28  import java.io.Reader;
29  import java.util.ArrayList;
30  import java.util.List;
31  
32  import org.apache.lucene.document.Document;
33  import org.apache.lucene.document.Field;
34  import org.apache.lucene.document.Field.Index;
35  import org.apache.lucene.document.Field.Store;
36  import org.apache.maven.index.artifact.Gav;
37  import org.apache.maven.index.context.IndexCreator;
38  import org.apache.maven.index.context.IndexingContext;
39  import org.apache.maven.index.util.zip.ZipFacade;
40  import org.apache.maven.index.util.zip.ZipHandle;
41  import org.apache.maven.model.Model;
42  import org.codehaus.plexus.util.xml.Xpp3Dom;
43  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
44  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
45  
46  /**
47   * An artifact context used to provide information about artifact during scanning. It is passed to the
48   * {@link IndexCreator}, which can populate {@link ArtifactInfo} for the given artifact.
49   * 
50   * @see IndexCreator#populateArtifactInfo(ArtifactContext)
51   * @see Indexer#scan(IndexingContext)
52   * @author Jason van Zyl
53   * @author Tamas Cservenak
54   */
55  public class ArtifactContext
56  {
57      private final File pom;
58  
59      private final File artifact;
60  
61      private final File metadata;
62  
63      private final ArtifactInfo artifactInfo;
64  
65      private final Gav gav;
66  
67      private final List<Exception> errors = new ArrayList<Exception>();
68  
69      public ArtifactContext( File pom, File artifact, File metadata, ArtifactInfo artifactInfo, Gav gav )
70          throws IllegalArgumentException
71      {
72          if ( artifactInfo == null )
73          {
74              throw new IllegalArgumentException( "Parameter artifactInfo must not be null." );
75          }
76  
77          this.pom = pom;
78          this.artifact = artifact;
79          this.metadata = metadata;
80          this.artifactInfo = artifactInfo;
81          this.gav = gav == null ? artifactInfo.calculateGav() : gav;
82      }
83  
84      public File getPom()
85      {
86          return pom;
87      }
88  
89      public Model getPomModel()
90      {
91          // First check for local pom file
92          if ( getPom() != null && getPom().exists() )
93          {
94              try
95              {
96                  return new ModelReader().readModel( new FileInputStream( getPom() ) );
97              }
98              catch ( FileNotFoundException e )
99              {
100             }
101         }
102         // Otherwise, check for pom contained in maven generated artifact
103         else if ( getArtifact() != null )
104         {
105             ZipHandle handle = null;
106 
107             try
108             {
109                 handle = ZipFacade.getZipHandle( getArtifact() );
110 
111                 final String embeddedPomPath =
112                     "META-INF/maven/" + getGav().getGroupId() + "/" + getGav().getArtifactId() + "/pom.xml";
113 
114                 if ( handle.hasEntry( embeddedPomPath ) )
115                 {
116                     return new ModelReader().readModel( handle.getEntryContent( embeddedPomPath ) );
117                 }
118             }
119             catch ( IOException e )
120             {
121             }
122             finally
123             {
124                 try
125                 {
126                     ZipFacade.close( handle );
127                 }
128                 catch ( Exception e )
129                 {
130                 }
131             }
132         }
133 
134         return null;
135     }
136 
137     public File getArtifact()
138     {
139         return artifact;
140     }
141 
142     public File getMetadata()
143     {
144         return metadata;
145     }
146 
147     public ArtifactInfo getArtifactInfo()
148     {
149         return artifactInfo;
150     }
151 
152     public Gav getGav()
153     {
154         return gav;
155     }
156 
157     public List<Exception> getErrors()
158     {
159         return errors;
160     }
161 
162     public void addError( Exception e )
163     {
164         errors.add( e );
165     }
166 
167     /**
168      * Creates Lucene Document using {@link IndexCreator}s from the given {@link IndexingContext}.
169      */
170     public Document createDocument( IndexingContext context )
171     {
172         Document doc = new Document();
173 
174         // unique key
175         doc.add( new Field( ArtifactInfo.UINFO, getArtifactInfo().getUinfo(), Store.YES, Index.NOT_ANALYZED ) );
176 
177         doc.add( new Field( ArtifactInfo.LAST_MODIFIED, //
178             Long.toString( System.currentTimeMillis() ), Store.YES, Index.NO ) );
179 
180         for ( IndexCreator indexCreator : context.getIndexCreators() )
181         {
182             try
183             {
184                 indexCreator.populateArtifactInfo( this );
185             }
186             catch ( IOException ex )
187             {
188                 addError( ex );
189             }
190         }
191 
192         // need a second pass in case index creators updated document attributes
193         for ( IndexCreator indexCreator : context.getIndexCreators() )
194         {
195             indexCreator.updateDocument( getArtifactInfo(), doc );
196         }
197 
198         return doc;
199     }
200 
201     public static class ModelReader
202     {
203         public Model readModel( InputStream pom )
204         {
205             if ( pom == null )
206             {
207                 return null;
208             }
209 
210             Model model = new Model();
211 
212             Xpp3Dom dom = readPomInputStream( pom );
213 
214             if ( dom == null )
215             {
216                 return null;
217             }
218 
219             if ( dom.getChild( "packaging" ) != null )
220             {
221                 model.setPackaging( dom.getChild( "packaging" ).getValue() );
222             }
223             // Special case, packaging should be null instead of default .jar if not set in pom
224             else
225             {
226                 model.setPackaging( null );
227             }
228 
229             if ( dom.getChild( "name" ) != null )
230             {
231                 model.setName( dom.getChild( "name" ).getValue() );
232             }
233 
234             if ( dom.getChild( "description" ) != null )
235             {
236                 model.setDescription( dom.getChild( "description" ).getValue() );
237             }
238 
239             return model;
240         }
241 
242         private Xpp3Dom readPomInputStream( InputStream is )
243         {
244             Reader r = new InputStreamReader( is );
245             try
246             {
247                 return Xpp3DomBuilder.build( r );
248             }
249             catch ( XmlPullParserException e )
250             {
251             }
252             catch ( IOException e )
253             {
254             }
255             finally
256             {
257                 try
258                 {
259                     r.close();
260                 }
261                 catch ( IOException e )
262                 {
263                 }
264             }
265 
266             return null;
267         }
268     }
269 }