1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.dependency.analyzer;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.net.URL;
26 import java.nio.charset.StandardCharsets;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.jar.JarOutputStream;
32 import java.util.zip.ZipEntry;
33
34 import org.junit.jupiter.api.Test;
35 import org.junit.jupiter.api.io.TempDir;
36
37 import static org.assertj.core.api.Assertions.assertThat;
38 import static org.assertj.core.api.Assertions.fail;
39
40
41
42
43
44
45
46 class ClassFileVisitorUtilsTest {
47
48 @TempDir
49 private Path tempDir;
50
51 private TestVisitor visitor = new TestVisitor();
52
53 private static class TestVisitor implements ClassFileVisitor {
54 final List<String> classNames = new ArrayList<>();
55
56 final List<String> data = new ArrayList<>();
57
58 @Override
59 public void visitClass(String className, InputStream in) {
60 classNames.add(className);
61 BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
62 reader.lines().forEach(data::add);
63 }
64 }
65
66 @Test
67 void testAcceptJar() throws IOException {
68 Path path = Files.createTempFile(tempDir, "test", ".jar");
69
70 try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(path))) {
71 addZipEntry(out, "a/b/c.class", "class a.b.c");
72 addZipEntry(out, "x/y/z.class", "class x.y.z");
73 }
74
75 ClassFileVisitorUtils.accept(path.toUri().toURL(), visitor);
76
77 assertThat(visitor.classNames).contains("a.b.c");
78 assertThat(visitor.classNames).contains("x.y.z");
79 assertThat(visitor.data).contains("class a.b.c");
80 assertThat(visitor.data).contains("class x.y.z");
81 }
82
83 @Test
84 void testAcceptJarWithNonClassEntry() throws IOException {
85 Path path = Files.createTempFile(tempDir, "test", ".jar");
86
87 try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(path))) {
88 addZipEntry(out, "a/b/c.jpg", "jpeg a.b.c");
89 }
90
91 ClassFileVisitorUtils.accept(path.toUri().toURL(), visitor);
92
93 assertThat(visitor.classNames).isEmpty();
94 }
95
96 @Test
97 void testAcceptDir() throws IOException {
98 Path dir = Files.createTempDirectory(tempDir, "d-a-test");
99
100 Path abDir = Files.createDirectories(dir.resolve("a/b"));
101 writeToFile(abDir, "c.class", "class a.b.c");
102
103 Path xyDir = Files.createDirectories(dir.resolve("x/y"));
104 writeToFile(xyDir, "z.class", "class x.y.z");
105
106 ClassFileVisitorUtils.accept(dir.toUri().toURL(), visitor);
107
108 assertThat(visitor.classNames).contains("a.b.c");
109 assertThat(visitor.classNames).contains("x.y.z");
110 assertThat(visitor.data).contains("class a.b.c");
111 assertThat(visitor.data).contains("class x.y.z");
112 }
113
114 @Test
115 void testAcceptDirWithNonClassFile() throws IOException {
116 Path dir = Files.createTempDirectory(tempDir, "d-a-test");
117
118 Path abDir = Files.createDirectories(dir.resolve("a/b"));
119 writeToFile(abDir, "c.jpg", "jpeg a.b.c");
120
121 ClassFileVisitorUtils.accept(dir.toUri().toURL(), visitor);
122
123 assertThat(visitor.classNames).isEmpty();
124 }
125
126 @Test
127 void testAcceptWithFile() throws IOException {
128 Path path = Files.createTempFile(tempDir, "test", ".class");
129 URL url = path.toUri().toURL();
130
131 try {
132 ClassFileVisitorUtils.accept(url, visitor);
133 fail("expected IllegalArgumentException");
134 } catch (IllegalArgumentException exception) {
135 assertThat(exception).hasMessage("Cannot accept visitor on URL: " + url);
136 }
137 }
138
139 @Test
140 void testAcceptWithUnsupportedScheme() throws IOException {
141 URL url = new URL("http://localhost/");
142
143 try {
144 ClassFileVisitorUtils.accept(url, visitor);
145 fail("expected IllegalArgumentException");
146 } catch (IllegalArgumentException exception) {
147 assertThat(exception).hasMessage("Cannot accept visitor on URL: " + url);
148 }
149 }
150
151 private void writeToFile(Path parent, String file, String data) throws IOException {
152 Files.write(parent.resolve(file), data.getBytes(StandardCharsets.UTF_8));
153 }
154
155 private void addZipEntry(JarOutputStream out, String fileName, String content) throws IOException {
156 out.putNextEntry(new ZipEntry(fileName));
157 byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
158 out.write(bytes, 0, bytes.length);
159 }
160 }