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 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 }