View Javadoc
1   package org.apache.maven.shared.dependency.analyzer;
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.commons.io.FileUtils;
23  import org.apache.commons.io.IOUtils;
24  import org.junit.Before;
25  import org.junit.Test;
26  
27  import java.io.File;
28  import java.io.FileOutputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.net.URL;
32  import java.nio.charset.StandardCharsets;
33  import java.nio.file.Files;
34  import java.nio.file.Path;
35  import java.util.ArrayList;
36  import java.util.List;
37  import java.util.jar.JarOutputStream;
38  import java.util.zip.ZipEntry;
39  
40  import static org.assertj.core.api.Assertions.assertThat;
41  import static org.assertj.core.api.Assertions.fail;
42  
43  /**
44   * Tests <code>ClassFileVisitorUtils</code>.
45   * 
46   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
47   * @see ClassFileVisitorUtils
48   */
49  public class ClassFileVisitorUtilsTest
50  {
51      private MockVisitor visitor;
52  
53      private static class MockVisitor implements ClassFileVisitor
54      {
55          final List<String> classNames = new ArrayList<>();
56          final List<String> data = new ArrayList<>();
57  
58          @Override
59          public void visitClass( String className, InputStream in )
60          {
61              classNames.add( className );
62              try
63              {
64                  List<String> lines = IOUtils.readLines( in, StandardCharsets.UTF_8 );
65                  data.addAll( lines );
66              }
67              catch ( IOException ex )
68              {
69                  throw new RuntimeException( ex );
70              }
71          }
72      }
73  
74      @Before
75      public void setUp()
76      {
77          visitor = new MockVisitor();
78      }
79  
80      @Test
81      public void testAcceptJar() throws IOException
82      {
83          File file = File.createTempFile( "test", ".jar" );
84          file.deleteOnExit();
85  
86          try ( JarOutputStream out = new JarOutputStream( new FileOutputStream( file ) ) )
87          {
88              addZipEntry( out, "a/b/c.class", "class a.b.c" );
89              addZipEntry( out, "x/y/z.class", "class x.y.z" );
90          }
91  
92          ClassFileVisitorUtils.accept( file.toURI().toURL(), visitor );
93  
94          assertThat( visitor.classNames ).contains( "a.b.c" );
95          assertThat( visitor.classNames ).contains( "x.y.z" );
96          assertThat( visitor.data ).contains( "class a.b.c" );
97          assertThat( visitor.data ).contains( "class x.y.z" );
98      }
99  
100     @Test
101     public void testAcceptJarWithNonClassEntry() throws IOException
102     {
103         File file = File.createTempFile( "test", ".jar" );
104         file.deleteOnExit();
105 
106         try ( JarOutputStream out = new JarOutputStream( new FileOutputStream( file ) ) )
107         {
108             addZipEntry( out, "a/b/c.jpg", "jpeg a.b.c" );
109         }
110 
111         ClassFileVisitorUtils.accept( file.toURI().toURL(), visitor );
112 
113         assertThat( visitor.classNames ) .isEmpty();
114     }
115 
116     @Test
117     public void testAcceptDir() throws IOException
118     {
119         Path dir = Files.createTempDirectory( "d-a-test" );
120 
121         Path abDir = Files.createDirectories( dir.resolve( "a/b" ) );
122         writeToFile( abDir, "c.class", "class a.b.c" );
123 
124         Path xyDir = Files.createDirectories( dir.resolve( "x/y" ) );
125         writeToFile( xyDir, "z.class", "class x.y.z" );
126 
127         ClassFileVisitorUtils.accept( dir.toUri().toURL(), visitor );
128 
129         FileUtils.deleteDirectory( dir.toFile() );
130 
131         assertThat( visitor.classNames ).contains( "a.b.c" );
132         assertThat( visitor.classNames ).contains( "x.y.z" );
133         assertThat( visitor.data ).contains( "class a.b.c" );
134         assertThat( visitor.data ).contains( "class x.y.z" );
135     }
136 
137     @Test
138     public void testAcceptDirWithNonClassFile() throws IOException
139     {
140         Path dir = Files.createTempDirectory( "d-a-test" );
141 
142         Path abDir = Files.createDirectories( dir.resolve( "a/b" ) );
143         writeToFile( abDir, "c.jpg", "jpeg a.b.c" );
144 
145         ClassFileVisitorUtils.accept( dir.toUri().toURL(), visitor );
146 
147         FileUtils.deleteDirectory( dir.toFile() );
148 
149         assertThat( visitor.classNames ).isEmpty();
150     }
151 
152     @Test
153     public void testAcceptWithFile() throws IOException
154     {
155         File file = File.createTempFile( "test", ".class" );
156         file.deleteOnExit();
157 
158         URL url = file.toURI().toURL();
159 
160         try
161         {
162             ClassFileVisitorUtils.accept( url, visitor );
163             fail( "expected IllegalArgumentException" );
164         }
165         catch ( IllegalArgumentException exception )
166         {
167             assertThat( exception ).hasMessage( "Cannot accept visitor on URL: " + url );
168         }
169     }
170 
171     @Test
172     public void testAcceptWithUnsupportedScheme() throws IOException
173     {
174         URL url = new URL( "http://localhost/" );
175 
176         try
177         {
178             ClassFileVisitorUtils.accept( url, visitor );
179             fail( "expected IllegalArgumentException" );
180         }
181         catch ( IllegalArgumentException exception )
182         {
183             assertThat( exception ).hasMessage( "Cannot accept visitor on URL: " + url );
184         }
185     }
186 
187     private void writeToFile( Path parent, String file, String data ) throws IOException
188     {
189         Files.write( parent.resolve( file ), data.getBytes( StandardCharsets.UTF_8 ) );
190     }
191 
192     private void addZipEntry( JarOutputStream out, String fileName, String content ) throws IOException
193     {
194         out.putNextEntry( new ZipEntry( fileName ) );
195         byte[] bytes = content.getBytes( StandardCharsets.UTF_8 );
196         out.write( bytes, 0, bytes.length );
197     }
198 }