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.BufferedInputStream;
25  import java.io.File;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.io.InputStreamReader;
29  import java.util.ArrayList;
30  import java.util.Arrays;
31  import java.util.Collection;
32  
33  import org.apache.lucene.document.Document;
34  import org.apache.lucene.document.Field.Index;
35  import org.apache.lucene.document.Field.Store;
36  import org.apache.maven.index.ArtifactContext;
37  import org.apache.maven.index.ArtifactInfo;
38  import org.apache.maven.index.IndexerField;
39  import org.apache.maven.index.IndexerFieldVersion;
40  import org.apache.maven.index.MAVEN;
41  import org.apache.maven.index.util.zip.ZipFacade;
42  import org.apache.maven.index.util.zip.ZipHandle;
43  import org.codehaus.plexus.configuration.PlexusConfiguration;
44  import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
45  import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
46  
47  /**
48   * A Maven Plugin index creator used to provide information about Maven Plugins. It will collect the plugin prefix and
49   * the goals the plugin provides. Also, the Lucene document and the returned ArtifactInfo will be correctly filled with
50   * these information.
51   * 
52   * @author cstamas
53   */
54  @Singleton
55  @Named( MavenPluginArtifactInfoIndexCreator.ID )
56  public class MavenPluginArtifactInfoIndexCreator
57      extends AbstractIndexCreator
58  {
59      public static final String ID = "maven-plugin";
60  
61      private static final String MAVEN_PLUGIN_PACKAGING = "maven-plugin";
62  
63      public static final IndexerField FLD_PLUGIN_PREFIX = new IndexerField( MAVEN.PLUGIN_PREFIX, IndexerFieldVersion.V1,
64          "px", "MavenPlugin prefix (as keyword, stored)", Store.YES, Index.NOT_ANALYZED );
65  
66      public static final IndexerField FLD_PLUGIN_GOALS = new IndexerField( MAVEN.PLUGIN_GOALS, IndexerFieldVersion.V1,
67          "gx", "MavenPlugin goals (as keyword, stored)", Store.YES, Index.ANALYZED );
68  
69      public MavenPluginArtifactInfoIndexCreator()
70      {
71          super( ID, Arrays.asList( MinimalArtifactInfoIndexCreator.ID ) );
72      }
73  
74      public void populateArtifactInfo( ArtifactContext ac )
75      {
76          File artifact = ac.getArtifact();
77  
78          ArtifactInfo ai = ac.getArtifactInfo();
79  
80          // we need the file to perform these checks, and those may be only JARs
81          if ( artifact != null && MAVEN_PLUGIN_PACKAGING.equals( ai.getPackaging() )
82              && artifact.getName().endsWith( ".jar" ) )
83          {
84              // TODO: recheck, is the following true? "Maven plugins and Maven Archetypes can be only JARs?"
85  
86              // 1st, check for maven plugin
87              checkMavenPlugin( ai, artifact );
88          }
89      }
90  
91      private void checkMavenPlugin( ArtifactInfo ai, File artifact )
92      {
93          ZipHandle handle = null;
94  
95          try
96          {
97              handle = ZipFacade.getZipHandle( artifact );
98  
99              final String pluginDescriptorPath = "META-INF/maven/plugin.xml";
100 
101             if ( handle.hasEntry( pluginDescriptorPath ) )
102             {
103                 InputStream is = new BufferedInputStream( handle.getEntryContent( pluginDescriptorPath ) );
104 
105                 try
106                 {
107                     // here the reader is closed
108                     PlexusConfiguration plexusConfig =
109                         new XmlPlexusConfiguration( Xpp3DomBuilder.build( new InputStreamReader( is ) ) );
110 
111                     ai.setPrefix( plexusConfig.getChild( "goalPrefix" ).getValue() );
112 
113                     ai.setGoals( new ArrayList<String>() );
114 
115                     PlexusConfiguration[] mojoConfigs = plexusConfig.getChild( "mojos" ).getChildren( "mojo" );
116 
117                     for ( PlexusConfiguration mojoConfig : mojoConfigs )
118                     {
119                         ai.getGoals().add( mojoConfig.getChild( "goal" ).getValue() );
120                     }
121                 }
122                 finally
123                 {
124                     is.close();
125                 }
126             }
127         }
128         catch ( Exception e )
129         {
130             if ( getLogger().isDebugEnabled() )
131             {
132                 getLogger().info(
133                     "Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to exception:", e );
134             }
135             else
136             {
137                 getLogger().info(
138                     "Failed to parse Maven artifact " + artifact.getAbsolutePath() + " due to " + e.getMessage() );
139             }
140         }
141         finally
142         {
143             try
144             {
145                 ZipFacade.close( handle );
146             }
147             catch ( IOException e )
148             {
149             }
150         }
151     }
152 
153     public void updateDocument( ArtifactInfo ai, Document doc )
154     {
155         if ( ai.getPrefix() != null )
156         {
157             doc.add( FLD_PLUGIN_PREFIX.toField( ai.getPrefix() ) );
158         }
159 
160         if ( ai.getGoals() != null )
161         {
162             doc.add( FLD_PLUGIN_GOALS.toField( ArtifactInfo.lst2str( ai.getGoals() ) ) );
163         }
164     }
165 
166     public boolean updateArtifactInfo( Document doc, ArtifactInfo ai )
167     {
168         boolean res = false;
169 
170         if ( "maven-plugin".equals( ai.getPackaging() ) )
171         {
172             ai.setPrefix( doc.get( ArtifactInfo.PLUGIN_PREFIX ) );
173 
174             String goals = doc.get( ArtifactInfo.PLUGIN_GOALS );
175 
176             if ( goals != null )
177             {
178                 ai.setGoals( ArtifactInfo.str2lst( goals ) );
179             }
180 
181             res = true;
182         }
183 
184         return res;
185     }
186 
187     @Override
188     public String toString()
189     {
190         return ID;
191     }
192 
193     public Collection<IndexerField> getIndexerFields()
194     {
195         return Arrays.asList( FLD_PLUGIN_GOALS, FLD_PLUGIN_PREFIX );
196     }
197 }