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