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