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