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