blob: d32718196b2aac51a955e20d8e5513fbd730cdda (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
package com.vaadin.tests.server;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Allows to get classes from the current classpath using classes FQN filter.
* <p>
* The methods in the class return all real (not anonymous and not private)
* classes from the filtered classpath.
*
* @author Vaadin Ltd
*
*/
class ClasspathHelper {
private final Predicate<String> skipClassesFilter;
ClasspathHelper(Predicate<String> skipClassesFilter) {
this.skipClassesFilter = skipClassesFilter;
}
Stream<Class<?>> getVaadinClassesFromClasspath(
Predicate<String> classpathFilter,
Predicate<Class<?>> classFilter) {
return getRawClasspathEntries().stream().filter(classpathFilter)
.map(File::new).map(file -> getVaadinClassesFromFile(file))
.flatMap(List::stream).filter(classFilter)
.filter(cls -> !cls.isSynthetic() && !cls.isAnonymousClass()
&& !Modifier.isPrivate(cls.getModifiers()));
}
Stream<Class<?>> getVaadinClassesFromClasspath(
Predicate<String> classpathFilter) {
return getVaadinClassesFromClasspath(classpathFilter, cls -> true);
}
private List<Class<?>> getVaadinClassesFromFile(File classesRoot) {
try {
if (classesRoot.isDirectory()) {
return Files.walk(classesRoot.toPath())
.filter(Files::isRegularFile)
.filter(path -> path.toFile().getName()
.endsWith(".class"))
.filter(path -> classesRoot.toPath().relativize(path)
.toString().contains("com/vaadin/"))
.map(path -> getClassFromFile(path,
classesRoot.toPath()))
.filter(Objects::nonNull).collect(Collectors.toList());
} else if (classesRoot.getName().toLowerCase(Locale.ENGLISH)
.endsWith(".jar")) {
URI uri = URI.create("jar:file:" + classesRoot.getPath());
Path root = FileSystems
.newFileSystem(uri, Collections.emptyMap())
.getPath("/");
return Files.walk(root).filter(Files::isRegularFile)
.filter(path -> path.toUri().getSchemeSpecificPart()
.endsWith(".class"))
.filter(path -> root.relativize(path).toString()
.contains("com/vaadin/"))
.map(path -> getClassFromFile(path, root))
.filter(Objects::nonNull).collect(Collectors.toList());
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Class<?> getClassFromFile(Path path, Path root) {
Path relative = root.relativize(path);
String name = relative.toString();
name = name.substring(0, name.length() - ".class".length());
name = name.replace('/', '.');
if (skipClassesFilter.test(name)) {
return null;
}
try {
return Class.forName(name, false, getClass().getClassLoader());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private final static List<String> getRawClasspathEntries() {
List<String> locations = new ArrayList<>();
String pathSep = System.getProperty("path.separator");
String classpath = System.getProperty("java.class.path");
if (classpath.startsWith("\"")) {
classpath = classpath.substring(1);
}
if (classpath.endsWith("\"")) {
classpath = classpath.substring(0, classpath.length() - 1);
}
String[] split = classpath.split(pathSep);
for (int i = 0; i < split.length; i++) {
String classpathEntry = split[i];
locations.add(classpathEntry);
}
return locations;
}
}
|