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.writers;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStreamWriter;
25 import java.io.Writer;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.eclipse.BuildCommand;
36 import org.apache.maven.plugin.eclipse.Constants;
37 import org.apache.maven.plugin.eclipse.EclipseSourceDir;
38 import org.apache.maven.plugin.eclipse.Messages;
39 import org.apache.maven.plugin.ide.IdeDependency;
40 import org.apache.maven.plugin.ide.IdeUtils;
41 import org.codehaus.plexus.util.IOUtil;
42 import org.codehaus.plexus.util.StringUtils;
43 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
44 import org.codehaus.plexus.util.xml.XMLWriter;
45
46
47
48
49
50
51
52
53
54 public class EclipseClasspathWriter
55 extends AbstractEclipseWriter
56 {
57
58
59
60
61 private static final String ORG_ECLIPSE_AJDT_INPATH = "org.eclipse.ajdt.inpath";
62
63
64
65
66 private static final String ORG_ECLIPSE_AJDT_ASPECTPATH = "org.eclipse.ajdt.aspectpath";
67
68
69
70
71 private static final String NAME = "name";
72
73
74
75
76 private static final String VALUE = "value";
77
78
79
80
81 private static final String ATTRIBUTE = "attribute";
82
83
84
85
86 private static final String ATTRIBUTES = "attributes";
87
88
89
90
91 protected static final String M2_REPO = "M2_REPO";
92
93
94
95
96 private static final String ATTR_SOURCEPATH = "sourcepath";
97
98
99
100
101 private static final String ATTR_OUTPUT = "output";
102
103
104
105
106 private static final String ATTR_PATH = "path";
107
108
109
110
111 private static final String ATTR_KIND = "kind";
112
113
114
115
116 private static final String ATTR_VAR = "var";
117
118
119
120
121 private static final String ATTR_LIB = "lib";
122
123
124
125
126 private static final String ATTR_SRC = "src";
127
128
129
130
131 private static final String ATTR_INCLUDING = "including";
132
133
134
135
136 private static final String ATTR_EXCLUDING = "excluding";
137
138
139
140
141 private static final String ELT_CLASSPATHENTRY = "classpathentry";
142
143
144
145
146 private static final String ELT_CLASSPATH = "classpath";
147
148
149
150
151 private static final String FILE_DOT_CLASSPATH = ".classpath";
152
153
154
155
156 public void write()
157 throws MojoExecutionException
158 {
159
160 Writer w;
161
162 try
163 {
164 w =
165 new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
166 FILE_DOT_CLASSPATH ) ), "UTF-8" );
167 }
168 catch ( IOException ex )
169 {
170 throw new MojoExecutionException( Messages.getString( "EclipsePlugin.erroropeningfile" ), ex );
171 }
172
173 XMLWriter writer = new PrettyPrintXMLWriter( w );
174
175 writer.startElement( ELT_CLASSPATH );
176
177 String defaultOutput =
178 IdeUtils.toRelativeAndFixSeparator( config.getProjectBaseDir(), config.getBuildOutputDirectory(), false );
179
180
181
182
183
184
185 List specialSources = new ArrayList();
186
187
188 Map byOutputDir = new HashMap();
189
190 for ( int j = 0; j < config.getSourceDirs().length; j++ )
191 {
192 EclipseSourceDir dir = config.getSourceDirs()[j];
193
194
195 List byOutputDirs = (List) byOutputDir.get( dir.getOutput() );
196 if ( byOutputDirs == null )
197 {
198
199 byOutputDir.put( dir.getOutput() == null ? defaultOutput : dir.getOutput(), byOutputDirs =
200 new ArrayList() );
201 }
202 byOutputDirs.add( dir );
203 }
204
205 for ( int j = 0; j < config.getSourceDirs().length; j++ )
206 {
207 EclipseSourceDir dir = config.getSourceDirs()[j];
208
209 log.debug( "Processing classpath for: " + dir.toString() + "; default output=" + defaultOutput );
210
211 boolean isSpecial = false;
212
213
214 if ( dir.isResource() )
215 {
216
217
218
219 if ( dir.getOutput() != null
220 && !dir.getOutput().equals( defaultOutput )
221 && dir.getOutput().startsWith( defaultOutput )
222 && byOutputDir.get( defaultOutput ) != null
223 && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty()
224 )
225 {
226
227
228
229 log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output="
230 + dir.getOutput() + ")" );
231
232 isSpecial = true;
233 specialSources.add( dir );
234 }
235 }
236
237 writer.startElement( ELT_CLASSPATHENTRY );
238
239 writer.addAttribute( ATTR_KIND, "src" );
240 writer.addAttribute( ATTR_PATH, dir.getPath() );
241
242 if ( !isSpecial && dir.getOutput() != null && !defaultOutput.equals( dir.getOutput() ) )
243 {
244 writer.addAttribute( ATTR_OUTPUT, dir.getOutput() );
245 }
246
247 String includes = dir.getIncludeAsString();
248 if ( StringUtils.isNotEmpty( includes ) )
249 {
250 writer.addAttribute( ATTR_INCLUDING, includes );
251 }
252
253 String excludes = dir.getExcludeAsString();
254 if ( StringUtils.isNotEmpty( excludes ) )
255 {
256 writer.addAttribute( ATTR_EXCLUDING, excludes );
257 }
258
259 writer.endElement();
260
261 }
262
263
264 if ( !specialSources.isEmpty() )
265 {
266 log.info( "Creating maven-eclipse.xml Ant file to handle resources" );
267
268 try
269 {
270 Writer buildXmlWriter =
271 new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
272 "maven-eclipse.xml" ) ), "UTF-8" );
273 PrettyPrintXMLWriter buildXmlPrinter = new PrettyPrintXMLWriter( buildXmlWriter );
274
275 buildXmlPrinter.startElement( "project" );
276 buildXmlPrinter.addAttribute( "default", "copy-resources" );
277
278 buildXmlPrinter.startElement( "target" );
279 buildXmlPrinter.addAttribute( NAME, "init" );
280
281 buildXmlPrinter.endElement();
282
283 buildXmlPrinter.startElement( "target" );
284 buildXmlPrinter.addAttribute( NAME, "copy-resources" );
285 buildXmlPrinter.addAttribute( "depends", "init" );
286
287 for ( Iterator it = specialSources.iterator(); it.hasNext(); )
288 {
289
290
291 EclipseSourceDir dir = (EclipseSourceDir) it.next();
292 buildXmlPrinter.startElement( "copy" );
293 buildXmlPrinter.addAttribute( "todir", dir.getOutput() );
294 buildXmlPrinter.addAttribute( "filtering", "" + dir.isFiltering() );
295
296 buildXmlPrinter.startElement( "fileset" );
297 buildXmlPrinter.addAttribute( "dir", dir.getPath() );
298 if ( dir.getIncludeAsString() != null )
299 {
300 buildXmlPrinter.addAttribute( "includes", dir.getIncludeAsString() );
301 }
302 if ( dir.getExcludeAsString() != null )
303 {
304 buildXmlPrinter.addAttribute( "excludes", dir.getExcludeAsString() );
305 }
306 buildXmlPrinter.endElement();
307
308 buildXmlPrinter.endElement();
309 }
310
311 buildXmlPrinter.endElement();
312
313 buildXmlPrinter.endElement();
314
315 IOUtil.close( buildXmlWriter );
316 }
317 catch ( IOException e )
318 {
319 throw new MojoExecutionException( "Cannot create " + config.getEclipseProjectDirectory()
320 + "/maven-eclipse.xml", e );
321 }
322
323 log.info( "Creating external launcher file" );
324
325 new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch",
326 "maven-eclipse.xml" ).write();
327
328
329
330 config.getBuildCommands().add(
331 new BuildCommand(
332 "org.eclipse.ui.externaltools.ExternalToolBuilder",
333 "LaunchConfigHandle",
334 "<project>/"
335 + EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS
336 + "Maven_Ant_Builder.launch" ) );
337 }
338
339
340
341
342
343 writer.startElement( ELT_CLASSPATHENTRY );
344 writer.addAttribute( ATTR_KIND, ATTR_OUTPUT );
345 writer.addAttribute( ATTR_PATH, defaultOutput );
346 writer.endElement();
347
348 Set addedDependencies = new HashSet();
349
350
351
352
353
354
355 IdeDependency[] depsToWrite = config.getDepsOrdered();
356 for ( int j = 0; j < depsToWrite.length; j++ )
357 {
358 IdeDependency dep = depsToWrite[j];
359 if ( dep.isJavaApi() )
360 {
361 String depId = getDependencyId( dep );
362 if ( !addedDependencies.contains( depId ) )
363 {
364 addDependency( writer, dep );
365 addedDependencies.add( depId );
366 }
367 }
368 }
369
370
371
372
373 for ( int j = 0; j < depsToWrite.length; j++ )
374 {
375 IdeDependency dep = depsToWrite[j];
376
377 if ( dep.isAddedToClasspath() )
378 {
379 String depId = getDependencyId( dep );
380
381 if ( !addedDependencies.contains( depId ) )
382 {
383 addDependency( writer, dep );
384 addedDependencies.add( depId );
385 }
386 }
387 }
388
389
390
391
392
393 for ( Iterator it = config.getClasspathContainers().iterator(); it.hasNext(); )
394 {
395 writer.startElement( ELT_CLASSPATHENTRY );
396 writer.addAttribute( ATTR_KIND, "con" );
397 writer.addAttribute( ATTR_PATH, (String) it.next() );
398 writer.endElement();
399 }
400
401 writer.endElement();
402
403 IOUtil.close( w );
404
405 }
406
407 private String getDependencyId( IdeDependency dep )
408 {
409 String depId =
410 dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getClassifier() + ":" + dep.getVersion();
411
412 if ( dep.isReferencedProject() )
413 {
414
415 depId = dep.getEclipseProjectName();
416 }
417 return depId;
418 }
419
420 protected void addDependency( XMLWriter writer, IdeDependency dep )
421 throws MojoExecutionException
422 {
423
424 String path;
425 String kind;
426 String sourcepath = null;
427 String javadocpath = null;
428
429 if ( dep.isReferencedProject() && !config.isPde() )
430 {
431 path = "/" + dep.getEclipseProjectName();
432 kind = ATTR_SRC;
433 }
434 else if ( dep.isReferencedProject() && config.isPde() )
435 {
436
437 return;
438 }
439 else
440 {
441 File artifactPath = dep.getFile();
442
443 if ( artifactPath == null )
444 {
445 log.error( Messages.getString( "EclipsePlugin.artifactpathisnull", dep.getId() ) );
446 return;
447 }
448
449 if ( dep.isSystemScoped() )
450 {
451 path = IdeUtils.toRelativeAndFixSeparator( config.getEclipseProjectDirectory(), artifactPath, false );
452
453 if ( log.isDebugEnabled() )
454 {
455 log.debug( Messages.getString( "EclipsePlugin.artifactissystemscoped",
456 new Object[] { dep.getArtifactId(), path } ) );
457 }
458
459 kind = ATTR_LIB;
460 }
461 else
462 {
463 File localRepositoryFile = new File( config.getLocalRepository().getBasedir() );
464
465
466
467 if ( config.isPde() && ( dep.isProvided() || dep.isOsgiBundle() ) )
468 {
469 return;
470 }
471 else if ( config.isPde() && !dep.isProvided() && !dep.isTestDependency() )
472 {
473
474 path = dep.getFile().getName();
475
476 kind = ATTR_LIB;
477 }
478
479
480 else
481 {
482 String fullPath = artifactPath.getPath();
483 String relativePath =
484 IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, new File( fullPath ), false );
485
486 if ( !new File( relativePath ).isAbsolute() )
487 {
488 path = M2_REPO + "/"
489 + relativePath;
490 kind = ATTR_VAR;
491 }
492 else
493 {
494 path = relativePath;
495 kind = ATTR_LIB;
496 }
497 }
498
499 if ( dep.getSourceAttachment() != null )
500 {
501 if ( ATTR_VAR.equals( kind ) )
502 {
503 sourcepath =
504 M2_REPO
505 + "/"
506 + IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, dep.getSourceAttachment(),
507 false );
508 }
509 else
510 {
511
512 sourcepath = IdeUtils.getCanonicalPath( dep.getSourceAttachment() );
513 }
514 }
515
516 if ( dep.getJavadocAttachment() != null )
517 {
518
519
520 javadocpath =
521 StringUtils.replace( IdeUtils.getCanonicalPath( dep.getJavadocAttachment() ), "\\", "/" );
522 }
523
524 }
525
526 }
527
528
529 if ( ( config.getAjdtVersion() != 0 ) && dep.getArtifactId().toLowerCase().indexOf( "aspectj" ) >= 0 )
530 {
531 return;
532 }
533
534 writer.startElement( ELT_CLASSPATHENTRY );
535 writer.addAttribute( ATTR_KIND, kind );
536 writer.addAttribute( ATTR_PATH, path );
537
538 if ( sourcepath != null )
539 {
540 writer.addAttribute( ATTR_SOURCEPATH, sourcepath );
541 }
542
543 boolean attributeElemOpen = false;
544
545 if ( javadocpath != null )
546 {
547 if ( !attributeElemOpen )
548 {
549 writer.startElement( ATTRIBUTES );
550 attributeElemOpen = true;
551 }
552
553 writer.startElement( ATTRIBUTE );
554 writer.addAttribute( VALUE, "jar:" + new File( javadocpath ).toURI() + "!/" );
555 writer.addAttribute( NAME, "javadoc_location" );
556 writer.endElement();
557
558 }
559
560 if ( Constants.PROJECT_PACKAGING_WAR.equals( this.config.getPackaging() ) && config.getWtpapplicationxml()
561 && kind.equals( ATTR_VAR ) && !dep.isTestDependency() && !dep.isProvided()
562 && !dep.isSystemScopedOutsideProject( this.config.getProject() ) )
563 {
564 if ( !attributeElemOpen )
565 {
566 writer.startElement( ATTRIBUTES );
567 attributeElemOpen = true;
568 }
569
570 writer.startElement( ATTRIBUTE );
571 writer.addAttribute( VALUE, "/WEB-INF/lib" );
572 writer.addAttribute( NAME, "org.eclipse.jst.component.dependency" );
573 writer.endElement();
574
575 }
576
577 if ( dep.isAjdtDependency() && ( config.getAjdtVersion() >= 1.5 ) )
578 {
579 if ( !attributeElemOpen )
580 {
581 writer.startElement( ATTRIBUTES );
582 attributeElemOpen = true;
583 }
584
585 writer.startElement( ATTRIBUTE );
586 writer.addAttribute( NAME, ORG_ECLIPSE_AJDT_ASPECTPATH );
587 writer.addAttribute( VALUE, Boolean.TRUE.toString() );
588 writer.endElement();
589
590 }
591
592 if ( dep.isAjdtWeaveDependency() && ( config.getAjdtVersion() >= 1.5 ) )
593 {
594 if ( !attributeElemOpen )
595 {
596 writer.startElement( ATTRIBUTES );
597 attributeElemOpen = true;
598 }
599
600 writer.startElement( ATTRIBUTE );
601 writer.addAttribute( NAME, ORG_ECLIPSE_AJDT_INPATH );
602 writer.addAttribute( VALUE, Boolean.TRUE.toString() );
603 writer.endElement();
604
605 }
606
607 if ( attributeElemOpen )
608 {
609 writer.endElement();
610 }
611 writer.endElement();
612
613 }
614 }