1 package org.apache.maven.plugins.assembly.filter;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import junit.framework.TestCase;
23
24 import org.apache.maven.plugins.assembly.testutils.TestFileManager;
25 import org.codehaus.plexus.archiver.ArchiveEntry;
26 import org.codehaus.plexus.archiver.ArchiveFinalizer;
27 import org.codehaus.plexus.archiver.ArchivedFileSet;
28 import org.codehaus.plexus.archiver.Archiver;
29 import org.codehaus.plexus.archiver.ArchiverException;
30 import org.codehaus.plexus.archiver.FileSet;
31 import org.codehaus.plexus.archiver.ResourceIterator;
32 import org.codehaus.plexus.archiver.diags.NoOpArchiver;
33 import org.codehaus.plexus.archiver.zip.ZipArchiver;
34 import org.codehaus.plexus.components.io.resources.PlexusIoResource;
35 import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
36 import org.codehaus.plexus.util.IOUtil;
37 import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
38 import org.codehaus.plexus.util.xml.Xpp3Dom;
39 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
40 import org.jdom.Document;
41 import org.jdom.JDOMException;
42 import org.jdom.Text;
43 import org.jdom.input.SAXBuilder;
44 import org.jdom.xpath.XPath;
45
46 import javax.annotation.Nonnull;
47
48 import java.io.File;
49 import java.io.FileOutputStream;
50 import java.io.IOException;
51 import java.io.Reader;
52 import java.io.StringReader;
53 import java.io.StringWriter;
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.LinkedHashMap;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.NoSuchElementException;
60 import java.util.zip.ZipEntry;
61 import java.util.zip.ZipFile;
62
63 public class ComponentsXmlArchiverFileFilterTest
64 extends TestCase
65 {
66 private final TestFileManager fileManager = new TestFileManager( "componentsXmlArchiverFileFilter.test", ".zip" );
67
68 private ComponentsXmlArchiverFileFilter filter;
69
70 @Override
71 public void setUp()
72 {
73 filter = new ComponentsXmlArchiverFileFilter();
74 }
75
76 @Override
77 public void tearDown()
78 throws IOException
79 {
80 fileManager.cleanUp();
81 }
82
83 public void testAddComponentsXml_ShouldAddComponentWithoutRoleHint()
84 throws IOException, XmlPullParserException
85 {
86 final Reader reader = writeComponentsXml(
87 Collections.singletonList( new ComponentDef( "role", null, "org.apache.maven.Impl" ) ) );
88
89 filter.addComponentsXml( reader );
90
91 assertFalse( filter.components.isEmpty() );
92
93 final Xpp3Dom componentDom = filter.components.get( "role" );
94
95 assertEquals( "role", componentDom.getChild( "role" ).getValue() );
96 assertNull( componentDom.getChild( "role-hint" ) );
97 assertEquals( "org.apache.maven.Impl", componentDom.getChild( "implementation" ).getValue() );
98 }
99
100 public void testAddComponentsXml_ShouldAddComponentWithRoleHint()
101 throws IOException, XmlPullParserException
102 {
103 final Reader reader = writeComponentsXml(
104 Collections.singletonList( new ComponentDef( "role", "hint", "org.apache.maven.Impl" ) ) );
105
106 filter.addComponentsXml( reader );
107
108 assertFalse( filter.components.isEmpty() );
109
110 final Xpp3Dom componentDom = filter.components.get( "rolehint" );
111
112 assertEquals( "role", componentDom.getChild( "role" ).getValue() );
113 assertEquals( "hint", componentDom.getChild( "role-hint" ).getValue() );
114 assertEquals( "org.apache.maven.Impl", componentDom.getChild( "implementation" ).getValue() );
115 }
116
117 public void testAddComponentsXml_ShouldAddTwoComponentsWithRoleHints()
118 throws IOException, XmlPullParserException
119 {
120 final List<ComponentDef> defs = new ArrayList<ComponentDef>();
121
122 defs.add( new ComponentDef( "role", "hint", "org.apache.maven.Impl" ) );
123 defs.add( new ComponentDef( "role", "hint2", "org.apache.maven.Impl2" ) );
124
125 final Reader reader = writeComponentsXml( defs );
126
127 filter.addComponentsXml( reader );
128
129 assertFalse( filter.components.isEmpty() );
130
131 Xpp3Dom componentDom = filter.components.get( "rolehint" );
132
133 assertEquals( "role", componentDom.getChild( "role" ).getValue() );
134 assertEquals( "hint", componentDom.getChild( "role-hint" ).getValue() );
135 assertEquals( "org.apache.maven.Impl", componentDom.getChild( "implementation" ).getValue() );
136
137 componentDom = filter.components.get( "rolehint2" );
138
139 assertEquals( "role", componentDom.getChild( "role" ).getValue() );
140 assertEquals( "hint2", componentDom.getChild( "role-hint" ).getValue() );
141 assertEquals( "org.apache.maven.Impl2", componentDom.getChild( "implementation" ).getValue() );
142 }
143
144 public void testAddToArchive_ShouldWriteComponentWithoutHintToFile()
145 throws IOException, ArchiverException, JDOMException
146 {
147 final Xpp3Dom dom = createComponentDom( new ComponentDef( "role", null, "impl" ) );
148
149 filter.components = new LinkedHashMap<String, Xpp3Dom>();
150 filter.components.put( "role", dom );
151
152 final FileCatchingArchiver fca = new FileCatchingArchiver();
153
154 filter.finalizeArchiveCreation( fca );
155
156 assertEquals( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH, fca.getDestFileName() );
157
158 final SAXBuilder builder = new SAXBuilder( false );
159
160 final Document doc = builder.build( fca.getFile() );
161
162 final XPath role = XPath.newInstance( "//component[position()=1]/role/text()" );
163 final XPath hint = XPath.newInstance( "//component[position()=1]/role-hint/text()" );
164 final XPath implementation = XPath.newInstance( "//component[position()=1]/implementation/text()" );
165
166 assertEquals( "role", ( (Text) role.selectSingleNode( doc ) ).getText() );
167 assertNull( hint.selectSingleNode( doc ) );
168 assertEquals( "impl", ( (Text) implementation.selectSingleNode( doc ) ).getText() );
169 }
170
171 public void testAddToArchive_ShouldWriteComponentWithHintToFile()
172 throws IOException, ArchiverException, JDOMException
173 {
174 final Xpp3Dom dom = createComponentDom( new ComponentDef( "role", "hint", "impl" ) );
175
176 filter.components = new LinkedHashMap<String, Xpp3Dom>();
177 filter.components.put( "rolehint", dom );
178
179 final FileCatchingArchiver fca = new FileCatchingArchiver();
180
181 filter.finalizeArchiveCreation( fca );
182
183 assertEquals( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH, fca.getDestFileName() );
184
185 final SAXBuilder builder = new SAXBuilder( false );
186
187 final Document doc = builder.build( fca.getFile() );
188
189 final XPath role = XPath.newInstance( "//component[position()=1]/role/text()" );
190 final XPath hint = XPath.newInstance( "//component[position()=1]/role-hint/text()" );
191 final XPath implementation = XPath.newInstance( "//component[position()=1]/implementation/text()" );
192
193 assertEquals( "role", ( (Text) role.selectSingleNode( doc ) ).getText() );
194 assertEquals( "hint", ( (Text) hint.selectSingleNode( doc ) ).getText() );
195 assertEquals( "impl", ( (Text) implementation.selectSingleNode( doc ) ).getText() );
196 }
197
198 public void testAddToArchive_ShouldWriteTwoComponentToFile()
199 throws IOException, ArchiverException, JDOMException
200 {
201 filter.components = new LinkedHashMap<String, Xpp3Dom>();
202
203 final Xpp3Dom dom = createComponentDom( new ComponentDef( "role", "hint", "impl" ) );
204
205 filter.components.put( "rolehint", dom );
206
207 final Xpp3Dom dom2 = createComponentDom( new ComponentDef( "role", "hint2", "impl" ) );
208
209 filter.components.put( "rolehint2", dom2 );
210
211 final FileCatchingArchiver fca = new FileCatchingArchiver();
212
213 filter.finalizeArchiveCreation( fca );
214
215 assertEquals( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH, fca.getDestFileName() );
216
217 final SAXBuilder builder = new SAXBuilder( false );
218
219 final Document doc = builder.build( fca.getFile() );
220
221 final XPath role = XPath.newInstance( "//component[position()=1]/role/text()" );
222 final XPath hint = XPath.newInstance( "//component[position()=1]/role-hint/text()" );
223 final XPath implementation = XPath.newInstance( "//component[position()=1]/implementation/text()" );
224
225 assertEquals( "role", ( (Text) role.selectSingleNode( doc ) ).getText() );
226 assertEquals( "hint", ( (Text) hint.selectSingleNode( doc ) ).getText() );
227 assertEquals( "impl", ( (Text) implementation.selectSingleNode( doc ) ).getText() );
228
229 final XPath role2 = XPath.newInstance( "//component[position()=2]/role/text()" );
230 final XPath hint2 = XPath.newInstance( "//component[position()=2]/role-hint/text()" );
231 final XPath implementation2 = XPath.newInstance( "//component[position()=2]/implementation/text()" );
232
233 assertEquals( "role", ( (Text) role2.selectSingleNode( doc ) ).getText() );
234 assertEquals( "hint2", ( (Text) hint2.selectSingleNode( doc ) ).getText() );
235 assertEquals( "impl", ( (Text) implementation2.selectSingleNode( doc ) ).getText() );
236
237 }
238
239 public void testAddToArchive_ShouldWriteTwoComponentToArchivedFile()
240 throws IOException, ArchiverException, JDOMException
241 {
242 filter.components = new LinkedHashMap<String, Xpp3Dom>();
243
244 final Xpp3Dom dom = createComponentDom( new ComponentDef( "role", "hint", "impl" ) );
245
246 filter.components.put( "rolehint", dom );
247
248 final Xpp3Dom dom2 = createComponentDom( new ComponentDef( "role", "hint2", "impl" ) );
249
250 filter.components.put( "rolehint2", dom2 );
251
252 final ZipArchiver archiver = new ZipArchiver();
253
254 final File archiveFile = fileManager.createTempFile();
255
256 archiver.setDestFile( archiveFile );
257
258 final File descriptorFile = fileManager.createTempFile();
259
260 archiver.setArchiveFinalizers( Collections.<ArchiveFinalizer>singletonList( filter ) );
261
262 archiver.createArchive();
263
264 ZipFile zf = null;
265 FileOutputStream out = null;
266 try
267 {
268 zf = new ZipFile( archiveFile );
269
270 final ZipEntry ze = zf.getEntry( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH );
271
272 assertNotNull( ze );
273
274 out = new FileOutputStream( descriptorFile );
275
276 IOUtil.copy( zf.getInputStream( ze ), out );
277 out.close();
278 out = null;
279 zf.close();
280 zf = null;
281 }
282 finally
283 {
284 IOUtil.close( out );
285 try
286 {
287 if ( zf != null )
288 {
289 zf.close();
290 }
291 }
292 catch ( final IOException e )
293 {
294
295 }
296 }
297
298
299 final SAXBuilder builder = new SAXBuilder( false );
300
301 final Document doc = builder.build( descriptorFile );
302
303 final XPath role = XPath.newInstance( "//component[position()=1]/role/text()" );
304 final XPath hint = XPath.newInstance( "//component[position()=1]/role-hint/text()" );
305 final XPath implementation = XPath.newInstance( "//component[position()=1]/implementation/text()" );
306
307 assertEquals( "role", ( (Text) role.selectSingleNode( doc ) ).getText() );
308 assertEquals( "hint", ( (Text) hint.selectSingleNode( doc ) ).getText() );
309 assertEquals( "impl", ( (Text) implementation.selectSingleNode( doc ) ).getText() );
310
311 final XPath role2 = XPath.newInstance( "//component[position()=2]/role/text()" );
312 final XPath hint2 = XPath.newInstance( "//component[position()=2]/role-hint/text()" );
313 final XPath implementation2 = XPath.newInstance( "//component[position()=2]/implementation/text()" );
314
315 assertEquals( "role", ( (Text) role2.selectSingleNode( doc ) ).getText() );
316 assertEquals( "hint2", ( (Text) hint2.selectSingleNode( doc ) ).getText() );
317 assertEquals( "impl", ( (Text) implementation2.selectSingleNode( doc ) ).getText() );
318
319 }
320
321 private Xpp3Dom createComponentDom( final ComponentDef def )
322 {
323 final Xpp3Dom dom = new Xpp3Dom( "component" );
324
325 final Xpp3Dom role = new Xpp3Dom( "role" );
326 role.setValue( def.role );
327 dom.addChild( role );
328
329 final String hint = def.roleHint;
330 if ( hint != null )
331 {
332 final Xpp3Dom roleHint = new Xpp3Dom( "role-hint" );
333 roleHint.setValue( hint );
334 dom.addChild( roleHint );
335 }
336
337 final Xpp3Dom impl = new Xpp3Dom( "implementation" );
338 impl.setValue( def.implementation );
339 dom.addChild( impl );
340
341 return dom;
342 }
343
344 private Reader writeComponentsXml( final List<ComponentDef> componentDefs )
345 throws IOException
346 {
347 final StringWriter writer = new StringWriter();
348
349 final PrettyPrintXMLWriter xmlWriter = new PrettyPrintXMLWriter( writer );
350
351 xmlWriter.startElement( "component-set" );
352 xmlWriter.startElement( "components" );
353
354 for ( final ComponentDef def : componentDefs )
355 {
356 xmlWriter.startElement( "component" );
357
358 xmlWriter.startElement( "role" );
359 xmlWriter.writeText( def.role );
360 xmlWriter.endElement();
361
362 final String roleHint = def.roleHint;
363 if ( roleHint != null )
364 {
365 xmlWriter.startElement( "role-hint" );
366 xmlWriter.writeText( roleHint );
367 xmlWriter.endElement();
368 }
369
370 xmlWriter.startElement( "implementation" );
371 xmlWriter.writeText( def.implementation );
372 xmlWriter.endElement();
373
374 xmlWriter.endElement();
375 }
376
377 xmlWriter.endElement();
378 xmlWriter.endElement();
379
380 return new StringReader( writer.toString() );
381 }
382
383 private static final class ComponentDef
384 {
385 final String role;
386
387 final String roleHint;
388
389 final String implementation;
390
391 ComponentDef( final String role, final String roleHint, final String implementation )
392 {
393 this.role = role;
394 this.roleHint = roleHint;
395 this.implementation = implementation;
396
397 }
398 }
399
400 private static final class FileCatchingArchiver
401 extends NoOpArchiver
402 {
403
404 private File inputFile;
405
406 private String destFileName;
407
408 public void addDirectory( final @Nonnull File directory )
409 throws ArchiverException
410 {
411 throw new UnsupportedOperationException( "not supported" );
412 }
413
414 public void addDirectory( final @Nonnull File directory, final String prefix )
415 throws ArchiverException
416 {
417 throw new UnsupportedOperationException( "not supported" );
418 }
419
420 public void addDirectory( final @Nonnull File directory, final String[] includes, final String[] excludes )
421 throws ArchiverException
422 {
423 throw new UnsupportedOperationException( "not supported" );
424 }
425
426 public void addDirectory( final @Nonnull File directory, final String prefix, final String[] includes,
427 final String[] excludes )
428 throws ArchiverException
429 {
430 throw new UnsupportedOperationException( "not supported" );
431 }
432
433 public void addFile( final @Nonnull File inputFile, final @Nonnull String destFileName )
434 throws ArchiverException
435 {
436 this.inputFile = inputFile;
437 this.destFileName = destFileName;
438 }
439
440 File getFile()
441 {
442 return inputFile;
443 }
444
445 String getDestFileName()
446 {
447 return destFileName;
448 }
449
450 public void addFile( final @Nonnull File inputFile, final @Nonnull String destFileName, final int permissions )
451 throws ArchiverException
452 {
453 throw new UnsupportedOperationException( "not supported" );
454 }
455
456 public void createArchive()
457 throws ArchiverException, IOException
458 {
459 throw new UnsupportedOperationException( "not supported" );
460 }
461
462 public int getDefaultDirectoryMode()
463 {
464 throw new UnsupportedOperationException( "not supported" );
465 }
466
467 public void setDefaultDirectoryMode( final int mode )
468 {
469 throw new UnsupportedOperationException( "not supported" );
470 }
471
472 public int getDefaultFileMode()
473 {
474 throw new UnsupportedOperationException( "not supported" );
475 }
476
477 public void setDefaultFileMode( final int mode )
478 {
479 throw new UnsupportedOperationException( "not supported" );
480 }
481
482 public File getDestFile()
483 {
484 throw new UnsupportedOperationException( "not supported" );
485 }
486
487 public void setDestFile( final File destFile )
488 {
489 throw new UnsupportedOperationException( "not supported" );
490 }
491
492 public void addSymlink( String s, String s2 )
493 throws ArchiverException
494 {
495 throw new UnsupportedOperationException( "not supported" );
496 }
497
498 public void addSymlink( String s, int i, String s2 )
499 throws ArchiverException
500 {
501 throw new UnsupportedOperationException( "not supported" );
502 }
503
504 public Map<String, ArchiveEntry> getFiles()
505 {
506 throw new UnsupportedOperationException( "not supported" );
507 }
508
509 public boolean getIncludeEmptyDirs()
510 {
511 throw new UnsupportedOperationException( "not supported" );
512 }
513
514 public void setIncludeEmptyDirs( final boolean includeEmptyDirs )
515 {
516 throw new UnsupportedOperationException( "not supported" );
517 }
518
519 public void addArchivedFileSet( final @Nonnull File archiveFile )
520 throws ArchiverException
521 {
522 throw new UnsupportedOperationException( "not supported" );
523 }
524
525 public void addArchivedFileSet( final @Nonnull File archiveFile, final String prefix )
526 throws ArchiverException
527 {
528 throw new UnsupportedOperationException( "not supported" );
529 }
530
531 public void addArchivedFileSet( final File archiveFile, final String[] includes, final String[] excludes )
532 throws ArchiverException
533 {
534 throw new UnsupportedOperationException( "not supported" );
535 }
536
537 public void addArchivedFileSet( final @Nonnull File archiveFile, final String prefix, final String[] includes,
538 final String[] excludes )
539 throws ArchiverException
540 {
541 throw new UnsupportedOperationException( "not supported" );
542 }
543
544 public boolean isForced()
545 {
546 throw new UnsupportedOperationException( "not supported" );
547 }
548
549 public void setForced( final boolean forced )
550 {
551 throw new UnsupportedOperationException( "not supported" );
552 }
553
554 public boolean isSupportingForced()
555 {
556 throw new UnsupportedOperationException( "not supported" );
557 }
558
559 public void setDotFileDirectory( final File dotFileDirectory )
560 {
561 }
562
563 public void addArchivedFileSet( final ArchivedFileSet fileSet )
564 throws ArchiverException
565 {
566 throw new UnsupportedOperationException( "not supported" );
567 }
568
569 public void addFileSet( final @Nonnull FileSet fileSet )
570 throws ArchiverException
571 {
572 throw new UnsupportedOperationException( "not supported" );
573 }
574
575 public void addResource( final PlexusIoResource resource, final String destFileName, final int permissions )
576 throws ArchiverException
577 {
578 throw new UnsupportedOperationException( "not supported" );
579 }
580
581 public void addResources( final PlexusIoResourceCollection resources )
582 throws ArchiverException
583 {
584 throw new UnsupportedOperationException( "not supported" );
585 }
586
587 public
588 @Nonnull
589 ResourceIterator getResources()
590 throws ArchiverException
591 {
592 return new ResourceIterator()
593 {
594
595 public boolean hasNext()
596 throws ArchiverException
597 {
598 return false;
599 }
600
601 public ArchiveEntry next()
602 throws ArchiverException
603 {
604 throw new NoSuchElementException();
605 }
606
607 public void remove()
608 {
609 throw new NoSuchElementException();
610 }
611 };
612 }
613
614 public String getDuplicateBehavior()
615 {
616 return Archiver.DUPLICATES_ADD;
617 }
618
619 public void setDuplicateBehavior( final String duplicate )
620 {
621 }
622
623 public int getDirectoryMode()
624 {
625 throw new UnsupportedOperationException( "not supported" );
626 }
627
628 public void setDirectoryMode( final int mode )
629 {
630 throw new UnsupportedOperationException( "not supported" );
631 }
632
633 public int getFileMode()
634 {
635 throw new UnsupportedOperationException( "not supported" );
636 }
637
638 public void setFileMode( final int mode )
639 {
640 throw new UnsupportedOperationException( "not supported" );
641 }
642
643 public int getOverrideDirectoryMode()
644 {
645 throw new UnsupportedOperationException( "not supported" );
646 }
647
648 public int getOverrideFileMode()
649 {
650 throw new UnsupportedOperationException( "not supported" );
651 }
652 }
653
654 }