1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.plugin.eclipse;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Properties;
28  import java.util.jar.Attributes;
29  import java.util.jar.JarFile;
30  import java.util.jar.Manifest;
31  
32  import org.apache.maven.artifact.Artifact;
33  import org.apache.maven.artifact.repository.ArtifactRepository;
34  import org.apache.maven.plugin.AbstractMojo;
35  import org.apache.maven.plugin.MojoExecutionException;
36  import org.apache.maven.plugin.MojoFailureException;
37  import org.apache.maven.plugin.logging.Log;
38  import org.apache.maven.project.MavenProject;
39  import org.apache.maven.project.MavenProjectBuilder;
40  import org.apache.maven.project.ProjectBuildingException;
41  import org.apache.maven.shared.osgi.Maven2OsgiConverter;
42  import org.codehaus.plexus.archiver.ArchiverException;
43  import org.codehaus.plexus.archiver.UnArchiver;
44  import org.codehaus.plexus.archiver.manager.ArchiverManager;
45  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
46  import org.codehaus.plexus.components.interactivity.InputHandler;
47  import org.codehaus.plexus.util.FileUtils;
48  
49  
50  
51  
52  
53  
54  
55  
56  public class InstallPluginsMojo
57      extends AbstractMojo
58  {
59  
60      
61  
62  
63  
64      public static final String PROP_UNPACK_PLUGIN = "eclipse.unpack";
65  
66      
67  
68  
69  
70  
71      private File eclipseDir;
72  
73      
74  
75  
76  
77  
78      private boolean overwrite;
79  
80      
81  
82  
83  
84  
85  
86  
87  
88      private Collection artifacts;
89  
90      
91  
92  
93  
94  
95  
96      private String pluginDependencyTypes;
97  
98      
99  
100 
101 
102 
103 
104 
105     private ArtifactRepository localRepository;
106 
107     
108 
109 
110 
111 
112 
113     private MavenProjectBuilder projectBuilder;
114 
115     
116 
117 
118 
119 
120 
121 
122     private ArchiverManager archiverManager;
123 
124     
125 
126 
127 
128 
129     private InputHandler inputHandler;
130 
131     
132     private File pluginsDir;
133 
134     
135 
136 
137     private Maven2OsgiConverter maven2OsgiConverter;
138 
139     public InstallPluginsMojo()
140     {
141         
142     }
143 
144     
145     protected InstallPluginsMojo( File eclipseDir, boolean overwrite, List dependencyArtifacts,
146                                   String pluginDependencyTypes, ArtifactRepository localRepository,
147                                   MavenProjectBuilder projectBuilder, ArchiverManager archiverManager,
148                                   InputHandler inputHandler, Log log )
149     {
150         this.eclipseDir = eclipseDir;
151         this.overwrite = overwrite;
152         artifacts = dependencyArtifacts;
153         this.pluginDependencyTypes = pluginDependencyTypes;
154         this.localRepository = localRepository;
155         this.projectBuilder = projectBuilder;
156         this.archiverManager = archiverManager;
157         this.inputHandler = inputHandler;
158         setLog( log );
159     }
160 
161     
162 
163 
164 
165 
166     public void execute()
167         throws MojoExecutionException, MojoFailureException
168     {
169         if ( eclipseDir == null )
170         {
171             getLog().info( "Eclipse directory? " );
172 
173             String eclipseDirString;
174             try
175             {
176                 eclipseDirString = inputHandler.readLine();
177             }
178             catch ( IOException e )
179             {
180                 throw new MojoExecutionException( "Unable to read from standard input", e );
181             }
182 
183             eclipseDir = new File( eclipseDirString );
184         }
185 
186         if ( eclipseDir.exists() && !eclipseDir.isDirectory() )
187         {
188             throw new MojoFailureException( "Invalid Eclipse directory: " + eclipseDir );
189         }
190         else if ( !eclipseDir.exists() )
191         {
192             eclipseDir.mkdirs();
193         }
194 
195         for ( Iterator it = artifacts.iterator(); it.hasNext(); )
196         {
197             Artifact artifact = (Artifact) it.next();
198 
199             if ( pluginDependencyTypes.indexOf( artifact.getType() ) > -1 )
200             {
201                 getLog().debug( "Processing Eclipse plugin dependency: " + artifact.getId() );
202 
203                 MavenProject project;
204 
205                 try
206                 {
207                     project =
208                         projectBuilder.buildFromRepository( artifact, Collections.EMPTY_LIST, localRepository, true );
209                 }
210                 catch ( ProjectBuildingException e )
211                 {
212                     throw new MojoExecutionException( "Failed to load project metadata (POM) for: " + artifact.getId(),
213                                                       e );
214                 }
215 
216                 install( artifact, project );
217             }
218             else
219             {
220                 getLog().debug(
221                                 "Skipping dependency: " + artifact.getId() +
222                                     ". Set pluginDependencyTypes with a comma-separated list of types to change this." );
223             }
224         }
225     }
226 
227     
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 
246 
247 
248 
249 
250 
251     private void install( Artifact artifact, MavenProject project )
252         throws MojoExecutionException, MojoFailureException
253     {
254         if ( pluginsDir == null )
255         {
256             pluginsDir = new File( eclipseDir, "plugins" );
257         }
258 
259         if ( !pluginsDir.exists() || !pluginsDir.isDirectory() )
260         {
261             throw new MojoFailureException( "Invalid Eclipse directory: " + eclipseDir +
262                 " (plugins directory is missing or not a directory)." );
263         }
264 
265         boolean installAsJar = true;
266 
267         Properties properties = project.getProperties();
268         if ( properties != null )
269         {
270             installAsJar = !Boolean.valueOf( properties.getProperty( PROP_UNPACK_PLUGIN, "false" ) ).booleanValue();
271         }
272 
273         Attributes attributes = null;
274         try
275         {
276             
277             JarFile jar = new JarFile( artifact.getFile(), false );
278             Manifest manifest = jar.getManifest();
279             attributes = manifest.getMainAttributes();
280         }
281         catch ( IOException e )
282         {
283             throw new MojoExecutionException( "Unable to read manifest of plugin " +
284                 artifact.getFile().getAbsolutePath(), e );
285         }
286 
287         String bundleVersion = attributes.getValue( "Bundle-Version" );
288         String pluginName = formatEclipsePluginName( artifact, bundleVersion );
289 
290         File pluginFile = new File( pluginsDir, pluginName + ".jar" );
291         File pluginDir = new File( pluginsDir, pluginName );
292 
293         boolean skipped = true;
294 
295         
296         Object bundleName = attributes.getValue( "Bundle-Name" );
297         if ( bundleName == null )
298         {
299             getLog().debug(
300                             "Ignoring " + artifact.getArtifactId() +
301                                 " as it is not an OSGi bundle (no Bundle-Name in manifest)" );
302             return;
303         }
304 
305         if ( overwrite )
306         {
307             if ( pluginFile.exists() || pluginDir.exists() )
308             {
309                 getLog().warn( "Overwriting old plugin with contents of: " + artifact.getId() );
310 
311                 getLog().debug( "Removing old plugin from both: " + pluginFile + " and: " + pluginDir );
312 
313                 try
314                 {
315                     FileUtils.forceDelete( pluginDir );
316                     FileUtils.forceDelete( pluginFile );
317                 }
318                 catch ( IOException e )
319                 {
320                     throw new MojoExecutionException( "Failed to remove old plugin from: " + pluginFile + " or: " +
321                         pluginDir, e );
322                 }
323 
324                 getLog().debug( "Removal of old plugin is complete; proceeding with plugin installation." );
325             }
326 
327             performFileOperations( installAsJar, artifact, pluginFile, pluginDir );
328 
329             skipped = false;
330         }
331         else if ( installAsJar && !pluginFile.exists() )
332         {
333             performFileOperations( installAsJar, artifact, pluginFile, pluginDir );
334 
335             skipped = false;
336         }
337         else if ( !installAsJar && !pluginDir.exists() )
338         {
339             performFileOperations( installAsJar, artifact, pluginFile, pluginDir );
340 
341             skipped = false;
342         }
343 
344         if ( skipped )
345         {
346             if ( installAsJar )
347             {
348                 getLog().info(
349                                "Skipping plugin installation for: " + artifact.getId() + "; file: " + pluginFile +
350                                    " already exists. Set overwrite = true to override this." );
351             }
352             else if ( !installAsJar )
353             {
354                 getLog().info(
355                                "Skipping plugin installation for: " + artifact.getId() + "; directory: " + pluginDir +
356                                    " already exists. Set overwrite = true to override this." );
357             }
358         }
359     }
360 
361     private void performFileOperations( boolean installAsJar, Artifact artifact, File pluginFile, File pluginDir )
362         throws MojoExecutionException
363     {
364         File artifactFile = artifact.getFile();
365 
366         if ( installAsJar )
367         {
368             try
369             {
370                 getLog().debug( "Copying: " + artifact.getId() + " to: " + pluginFile );
371 
372                 FileUtils.copyFile( artifactFile, pluginFile );
373             }
374             catch ( IOException e )
375             {
376                 throw new MojoExecutionException( "Failed to copy Eclipse plugin: " + artifact.getId() + "\nfrom: " +
377                     artifact.getFile() + "\nto: " + pluginFile, e );
378             }
379         }
380         else
381         {
382             try
383             {
384                 getLog().debug( "Expanding: " + artifact.getId() + " into: " + pluginDir );
385 
386                 pluginDir.mkdirs();
387 
388                 UnArchiver unarchiver = archiverManager.getUnArchiver( artifactFile );
389 
390                 unarchiver.setSourceFile( artifactFile );
391                 unarchiver.setDestDirectory( pluginDir );
392                 unarchiver.extract();
393             }
394             catch ( NoSuchArchiverException e )
395             {
396                 throw new MojoExecutionException( "Could not find unarchiver for: " + artifactFile, e );
397             }
398             catch ( ArchiverException e )
399             {
400                 throw new MojoExecutionException( "Could not extract: " + artifactFile, e );
401             }
402             catch ( IOException e )
403             {
404                 throw new MojoExecutionException( "Could not extract: " + artifactFile, e );
405             }
406         }
407     }
408 
409     
410 
411 
412 
413 
414 
415     private String formatEclipsePluginName( Artifact artifact, String bundleVersion )
416     {
417         return maven2OsgiConverter.getBundleSymbolicName( artifact ) + "_" +
418             maven2OsgiConverter.getVersion( artifact.getVersion() );
419     }
420 
421 }