View Javadoc

1   package org.apache.maven.plugin.assembly.filter;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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 }