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 }