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 " + ( dir.isResource() ? "re" : "" ) + "source " + dir.getPath() + ": output="
210 + dir.getOutput() + "; default output=" + defaultOutput );
211
212 boolean isSpecial = false;
213
214
215 if ( dir.isResource() )
216 {
217
218
219
220 if ( dir.getOutput() != null
221 && !dir.getOutput().equals( defaultOutput )
222 && dir.getOutput().startsWith( defaultOutput )
223 && byOutputDir.get( defaultOutput ) != null
224 && !( (List) byOutputDir.get( defaultOutput ) ).isEmpty()
225 )
226 {
227
228
229
230 log.debug( "Marking as special to prevent output folder nesting: " + dir.getPath() + " (output="
231 + dir.getOutput() + ")" );
232
233 isSpecial = true;
234 specialSources.add( dir );
235 }
236 }
237
238 writer.startElement( ELT_CLASSPATHENTRY );
239
240 writer.addAttribute( ATTR_KIND, "src" );
241 writer.addAttribute( ATTR_PATH, dir.getPath() );
242
243 if ( !isSpecial && dir.getOutput() != null && !defaultOutput.equals( dir.getOutput() ) )
244 {
245 writer.addAttribute( ATTR_OUTPUT, dir.getOutput() );
246 }
247
248 String includes = dir.getInclude();
249
250 if ( !dir.isResource() )
251 {
252
253
254 includes = StringUtils.isEmpty( includes ) ? "**/*.java" : includes + "|**/*.java";
255 }
256
257 if ( StringUtils.isNotEmpty( includes ) )
258 {
259 writer.addAttribute( ATTR_INCLUDING, includes );
260 }
261
262 String excludes = dir.getExclude();
263
264 if ( dir.isResource() )
265 {
266
267
268 excludes = StringUtils.isEmpty( excludes ) ? "**/*.java" : excludes + "|**/*.java";
269 }
270
271 if ( StringUtils.isNotEmpty( excludes ) )
272 {
273 writer.addAttribute( ATTR_EXCLUDING, excludes );
274 }
275
276 writer.endElement();
277
278 }
279
280
281 if ( !specialSources.isEmpty() )
282 {
283 log.info( "Creating maven-eclipse.xml Ant file to handle resources" );
284
285 try
286 {
287 Writer buildXmlWriter =
288 new OutputStreamWriter( new FileOutputStream( new File( config.getEclipseProjectDirectory(),
289 "maven-eclipse.xml" ) ), "UTF-8" );
290 PrettyPrintXMLWriter buildXmlPrinter = new PrettyPrintXMLWriter( buildXmlWriter );
291
292 buildXmlPrinter.startElement( "project" );
293 buildXmlPrinter.addAttribute( "default", "copy-resources" );
294
295 buildXmlPrinter.startElement( "target" );
296 buildXmlPrinter.addAttribute( NAME, "init" );
297
298 buildXmlPrinter.endElement();
299
300 buildXmlPrinter.startElement( "target" );
301 buildXmlPrinter.addAttribute( NAME, "copy-resources" );
302 buildXmlPrinter.addAttribute( "depends", "init" );
303
304 for ( Iterator it = specialSources.iterator(); it.hasNext(); )
305 {
306
307
308 EclipseSourceDir dir = (EclipseSourceDir) it.next();
309 buildXmlPrinter.startElement( "copy" );
310 buildXmlPrinter.addAttribute( "todir", dir.getOutput() );
311 buildXmlPrinter.addAttribute( "filtering", "" + dir.isFiltering() );
312
313 buildXmlPrinter.startElement( "fileset" );
314 buildXmlPrinter.addAttribute( "dir", dir.getPath() );
315 if ( dir.getInclude() != null )
316 {
317 buildXmlPrinter.addAttribute( "includes", dir.getInclude() );
318 }
319 if ( dir.getExclude() != null )
320 {
321 buildXmlPrinter.addAttribute( "excludes", dir.getExclude() );
322 }
323 buildXmlPrinter.endElement();
324
325 buildXmlPrinter.endElement();
326 }
327
328 buildXmlPrinter.endElement();
329
330 buildXmlPrinter.endElement();
331
332 IOUtil.close( buildXmlWriter );
333 }
334 catch ( IOException e )
335 {
336 throw new MojoExecutionException( "Cannot create " + config.getEclipseProjectDirectory()
337 + "/maven-eclipse.xml", e );
338 }
339
340 log.info( "Creating external launcher file" );
341
342 new EclipseAntExternalLaunchConfigurationWriter().init( log, config, "Maven_Ant_Builder.launch",
343 "maven-eclipse.xml" ).write();
344
345
346
347 config.getBuildCommands().add(
348 new BuildCommand(
349 "org.eclipse.ui.externaltools.ExternalToolBuilder",
350 "LaunchConfigHandle",
351 "<project>/"
352 + EclipseLaunchConfigurationWriter.FILE_DOT_EXTERNAL_TOOL_BUILDERS
353 + "Maven_Ant_Builder.launch" ) );
354 }
355
356
357
358
359
360 writer.startElement( ELT_CLASSPATHENTRY );
361 writer.addAttribute( ATTR_KIND, ATTR_OUTPUT );
362 writer.addAttribute( ATTR_PATH, defaultOutput );
363 writer.endElement();
364
365 Set addedDependencies = new HashSet();
366
367
368
369
370
371
372 IdeDependency[] depsToWrite = config.getDepsOrdered();
373 for ( int j = 0; j < depsToWrite.length; j++ )
374 {
375 IdeDependency dep = depsToWrite[j];
376 if ( dep.isJavaApi() )
377 {
378 String depId = getDependencyId( dep );
379 if ( !addedDependencies.contains( depId ) )
380 {
381 addDependency( writer, dep );
382 addedDependencies.add( depId );
383 }
384 }
385 }
386
387
388
389
390 for ( int j = 0; j < depsToWrite.length; j++ )
391 {
392 IdeDependency dep = depsToWrite[j];
393
394 if ( dep.isAddedToClasspath() )
395 {
396 String depId = getDependencyId( dep );
397
398 if ( !addedDependencies.contains( depId ) )
399 {
400 addDependency( writer, dep );
401 addedDependencies.add( depId );
402 }
403 }
404 }
405
406
407
408
409
410 for ( Iterator it = config.getClasspathContainers().iterator(); it.hasNext(); )
411 {
412 writer.startElement( ELT_CLASSPATHENTRY );
413 writer.addAttribute( ATTR_KIND, "con" );
414 writer.addAttribute( ATTR_PATH, (String) it.next() );
415 writer.endElement();
416 }
417
418 writer.endElement();
419
420 IOUtil.close( w );
421
422 }
423
424 private String getDependencyId( IdeDependency dep )
425 {
426 String depId =
427 dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getClassifier() + ":" + dep.getVersion();
428
429 if ( dep.isReferencedProject() )
430 {
431
432 depId = dep.getEclipseProjectName();
433 }
434 return depId;
435 }
436
437 protected void addDependency( XMLWriter writer, IdeDependency dep )
438 throws MojoExecutionException
439 {
440
441 String path;
442 String kind;
443 String sourcepath = null;
444 String javadocpath = null;
445
446 if ( dep.isReferencedProject() && !config.isPde() )
447 {
448 path = "/" + dep.getEclipseProjectName();
449 kind = ATTR_SRC;
450 }
451 else if ( dep.isReferencedProject() && config.isPde() )
452 {
453
454 return;
455 }
456 else
457 {
458 File artifactPath = dep.getFile();
459
460 if ( artifactPath == null )
461 {
462 log.error( Messages.getString( "EclipsePlugin.artifactpathisnull", dep.getId() ) );
463 return;
464 }
465
466 if ( dep.isSystemScoped() )
467 {
468 path = IdeUtils.toRelativeAndFixSeparator( config.getEclipseProjectDirectory(), artifactPath, false );
469
470 if ( log.isDebugEnabled() )
471 {
472 log.debug( Messages.getString( "EclipsePlugin.artifactissystemscoped",
473 new Object[] { dep.getArtifactId(), path } ) );
474 }
475
476 kind = ATTR_LIB;
477 }
478 else
479 {
480 File localRepositoryFile = new File( config.getLocalRepository().getBasedir() );
481
482
483
484 if ( config.isPde() && ( dep.isProvided() || dep.isOsgiBundle() ) )
485 {
486 return;
487 }
488 else if ( config.isPde() && !dep.isProvided() && !dep.isTestDependency() )
489 {
490
491 path = dep.getFile().getName();
492
493 kind = ATTR_LIB;
494 }
495
496
497 else
498 {
499 String fullPath = artifactPath.getPath();
500 String relativePath =
501 IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, new File( fullPath ), false );
502
503 if ( !new File( relativePath ).isAbsolute() )
504 {
505 path = M2_REPO + "/"
506 + relativePath;
507 kind = ATTR_VAR;
508 }
509 else
510 {
511 path = relativePath;
512 kind = ATTR_LIB;
513 }
514 }
515
516 if ( dep.getSourceAttachment() != null )
517 {
518 if ( ATTR_VAR.equals( kind ) )
519 {
520 sourcepath =
521 M2_REPO
522 + "/"
523 + IdeUtils.toRelativeAndFixSeparator( localRepositoryFile, dep.getSourceAttachment(),
524 false );
525 }
526 else
527 {
528
529 sourcepath = IdeUtils.getCanonicalPath( dep.getSourceAttachment() );
530 }
531 }
532
533 if ( dep.getJavadocAttachment() != null )
534 {
535
536
537 javadocpath =
538 StringUtils.replace( IdeUtils.getCanonicalPath( dep.getJavadocAttachment() ), "\\", "/" );
539 }
540
541 }
542
543 }
544
545
546 if ( ( config.getAjdtVersion() != 0 ) && dep.getArtifactId().toLowerCase().startsWith( "aspectj" ) )
547 {
548 return;
549 }
550
551 writer.startElement( ELT_CLASSPATHENTRY );
552 writer.addAttribute( ATTR_KIND, kind );
553 writer.addAttribute( ATTR_PATH, path );
554
555 if ( sourcepath != null )
556 {
557 writer.addAttribute( ATTR_SOURCEPATH, sourcepath );
558 }
559
560 boolean attributeElemOpen = false;
561
562 if ( javadocpath != null )
563 {
564 if ( !attributeElemOpen )
565 {
566 writer.startElement( ATTRIBUTES );
567 attributeElemOpen = true;
568 }
569
570 writer.startElement( ATTRIBUTE );
571 writer.addAttribute( VALUE, "jar:" + new File( javadocpath ).toURI() + "!/" );
572 writer.addAttribute( NAME, "javadoc_location" );
573 writer.endElement();
574
575 }
576
577 if ( Constants.PROJECT_PACKAGING_WAR.equals( this.config.getPackaging() ) && config.getWtpapplicationxml()
578 && kind.equals( ATTR_VAR ) && !dep.isTestDependency() && !dep.isProvided()
579 && !dep.isSystemScopedOutsideProject( this.config.getProject() ) )
580 {
581 if ( !attributeElemOpen )
582 {
583 writer.startElement( ATTRIBUTES );
584 attributeElemOpen = true;
585 }
586
587 writer.startElement( ATTRIBUTE );
588 writer.addAttribute( VALUE, "/WEB-INF/lib" );
589 writer.addAttribute( NAME, "org.eclipse.jst.component.dependency" );
590 writer.endElement();
591
592 }
593
594 if ( dep.isAjdtDependency() && ( config.getAjdtVersion() >= 1.5 ) )
595 {
596 if ( !attributeElemOpen )
597 {
598 writer.startElement( ATTRIBUTES );
599 attributeElemOpen = true;
600 }
601
602 writer.startElement( ATTRIBUTE );
603 writer.addAttribute( NAME, ORG_ECLIPSE_AJDT_ASPECTPATH );
604 writer.addAttribute( VALUE, Boolean.TRUE.toString() );
605 writer.endElement();
606
607 }
608
609 if ( dep.isAjdtWeaveDependency() && ( config.getAjdtVersion() >= 1.5 ) )
610 {
611 if ( !attributeElemOpen )
612 {
613 writer.startElement( ATTRIBUTES );
614 attributeElemOpen = true;
615 }
616
617 writer.startElement( ATTRIBUTE );
618 writer.addAttribute( NAME, ORG_ECLIPSE_AJDT_INPATH );
619 writer.addAttribute( VALUE, Boolean.TRUE.toString() );
620 writer.endElement();
621
622 }
623
624 if ( attributeElemOpen )
625 {
626 writer.endElement();
627 }
628 writer.endElement();
629
630 }
631 }