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