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