1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.spring.boot.autoconfigure;
17
18 import java.io.IOException;
19 import java.io.UncheckedIOException;
20 import java.net.URL;
21 import java.net.URLDecoder;
22 import java.nio.charset.Charset;
23 import java.text.Normalizer;
24 import java.util.List;
25 import java.util.function.Supplier;
26 import java.util.stream.Collectors;
27 import java.util.stream.Stream;
28
29 import org.apache.ibatis.io.VFS;
30 import org.springframework.core.io.Resource;
31 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
32 import org.springframework.core.io.support.ResourcePatternResolver;
33 import org.springframework.util.ClassUtils;
34
35
36
37
38
39
40 public class SpringBootVFS extends VFS {
41
42 private static Charset urlDecodingCharset;
43 private static Supplier<ClassLoader> classLoaderSupplier;
44 private final ResourcePatternResolver resourceResolver;
45
46 static {
47 setUrlDecodingCharset(Charset.defaultCharset());
48 setClassLoaderSupplier(ClassUtils::getDefaultClassLoader);
49 }
50
51 public SpringBootVFS() {
52 this.resourceResolver = new PathMatchingResourcePatternResolver(classLoaderSupplier.get());
53 }
54
55 @Override
56 public boolean isValid() {
57 return true;
58 }
59
60 @Override
61 protected List<String> list(URL url, String path) throws IOException {
62 String urlString = URLDecoder.decode(url.toString(), urlDecodingCharset.name());
63 String baseUrlString = urlString.endsWith("/") ? urlString : urlString.concat("/");
64 Resource[] resources = resourceResolver.getResources(baseUrlString + "**/*.class");
65 return Stream.of(resources).map(resource -> preserveSubpackageName(baseUrlString, resource, path))
66 .collect(Collectors.toList());
67 }
68
69
70
71
72
73
74
75
76
77
78
79
80 public static void setUrlDecodingCharset(Charset charset) {
81 urlDecodingCharset = charset;
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95 public static void setClassLoaderSupplier(Supplier<ClassLoader> supplier) {
96 classLoaderSupplier = supplier;
97 }
98
99 private static String preserveSubpackageName(final String baseUrlString, final Resource resource,
100 final String rootPath) {
101 try {
102 return rootPath + (rootPath.endsWith("/") ? "" : "/") + Normalizer
103 .normalize(URLDecoder.decode(resource.getURL().toString(), urlDecodingCharset.name()), Normalizer.Form.NFC)
104 .substring(baseUrlString.length());
105 } catch (IOException e) {
106 throw new UncheckedIOException(e);
107 }
108 }
109
110 }