1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.io;
17
18 import java.io.IOException;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.net.URL;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.List;
26
27 import org.apache.ibatis.logging.Log;
28 import org.apache.ibatis.logging.LogFactory;
29
30
31
32
33
34
35 public abstract class VFS {
36 private static final Log log = LogFactory.getLog(VFS.class);
37
38
39 public static final Class<?>[] IMPLEMENTATIONS = { JBoss6VFS.class, DefaultVFS.class };
40
41
42 public static final List<Class<? extends VFS>> USER_IMPLEMENTATIONS = new ArrayList<>();
43
44
45 private static class VFSHolder {
46 static final VFS INSTANCE = createVFS();
47
48 @SuppressWarnings("unchecked")
49 static VFS createVFS() {
50
51 List<Class<? extends VFS>> impls = new ArrayList<>();
52 impls.addAll(USER_IMPLEMENTATIONS);
53 impls.addAll(Arrays.asList((Class<? extends VFS>[]) IMPLEMENTATIONS));
54
55
56 VFS vfs = null;
57 for (int i = 0; vfs == null || !vfs.isValid(); i++) {
58 Class<? extends VFS> impl = impls.get(i);
59 try {
60 vfs = impl.getDeclaredConstructor().newInstance();
61 if (!vfs.isValid()) {
62 if (log.isDebugEnabled()) {
63 log.debug("VFS implementation " + impl.getName() +
64 " is not valid in this environment.");
65 }
66 }
67 } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
68 log.error("Failed to instantiate " + impl, e);
69 return null;
70 }
71 }
72
73 if (log.isDebugEnabled()) {
74 log.debug("Using VFS adapter " + vfs.getClass().getName());
75 }
76
77 return vfs;
78 }
79 }
80
81
82
83
84
85 public static VFS getInstance() {
86 return VFSHolder.INSTANCE;
87 }
88
89
90
91
92
93
94
95 public static void addImplClass(Class<? extends VFS> clazz) {
96 if (clazz != null) {
97 USER_IMPLEMENTATIONS.add(clazz);
98 }
99 }
100
101
102 protected static Class<?> getClass(String className) {
103 try {
104 return Thread.currentThread().getContextClassLoader().loadClass(className);
105
106 } catch (ClassNotFoundException e) {
107 if (log.isDebugEnabled()) {
108 log.debug("Class not found: " + className);
109 }
110 return null;
111 }
112 }
113
114
115
116
117
118
119
120
121 protected static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
122 if (clazz == null) {
123 return null;
124 }
125 try {
126 return clazz.getMethod(methodName, parameterTypes);
127 } catch (SecurityException e) {
128 log.error("Security exception looking for method " + clazz.getName() + "." + methodName + ". Cause: " + e);
129 return null;
130 } catch (NoSuchMethodException e) {
131 log.error("Method not found " + clazz.getName() + "." + methodName + "." + methodName + ". Cause: " + e);
132 return null;
133 }
134 }
135
136
137
138
139
140
141
142
143
144
145
146 @SuppressWarnings("unchecked")
147 protected static <T> T invoke(Method method, Object object, Object... parameters)
148 throws IOException, RuntimeException {
149 try {
150 return (T) method.invoke(object, parameters);
151 } catch (IllegalArgumentException | IllegalAccessException e) {
152 throw new RuntimeException(e);
153 } catch (InvocationTargetException e) {
154 if (e.getTargetException() instanceof IOException) {
155 throw (IOException) e.getTargetException();
156 } else {
157 throw new RuntimeException(e);
158 }
159 }
160 }
161
162
163
164
165
166
167
168
169
170 protected static List<URL> getResources(String path) throws IOException {
171 return Collections.list(Thread.currentThread().getContextClassLoader().getResources(path));
172 }
173
174
175 public abstract boolean isValid();
176
177
178
179
180
181
182
183
184
185
186
187 protected abstract List<String> list(URL url, String forPath) throws IOException;
188
189
190
191
192
193
194
195
196
197 public List<String> list(String path) throws IOException {
198 List<String> names = new ArrayList<>();
199 for (URL url : getResources(path)) {
200 names.addAll(list(url, path));
201 }
202 return names;
203 }
204 }