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.Method;
20  import java.net.URL;
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.ibatis.logging.Log;
26  import org.apache.ibatis.logging.LogFactory;
27  
28  
29  
30  
31  
32  
33  public class JBoss6VFS extends VFS {
34    private static final Log log = LogFactory.getLog(JBoss6VFS.class);
35  
36    
37    static class VirtualFile {
38      static Class<?> VirtualFile;
39      static Method getPathNameRelativeTo, getChildrenRecursively;
40  
41      Object virtualFile;
42  
43      VirtualFile(Object virtualFile) {
44        this.virtualFile = virtualFile;
45      }
46  
47      String getPathNameRelativeTo(VirtualFile parent) {
48        try {
49          return invoke(getPathNameRelativeTo, virtualFile, parent.virtualFile);
50        } catch (IOException e) {
51          
52          log.error("This should not be possible. VirtualFile.getPathNameRelativeTo() threw IOException.");
53          return null;
54        }
55      }
56  
57      List<VirtualFile> getChildren() throws IOException {
58        List<?> objects = invoke(getChildrenRecursively, virtualFile);
59        List<VirtualFile> children = new ArrayList<>(objects.size());
60        for (Object object : objects) {
61          children.add(new VirtualFile(object));
62        }
63        return children;
64      }
65    }
66  
67    
68    static class VFS {
69      static Class<?> VFS;
70      static Method getChild;
71  
72      private VFS() {
73        
74      }
75  
76      static VirtualFile getChild(URL url) throws IOException {
77        Object o = invoke(getChild, VFS, url);
78        return o == null ? null : new VirtualFile(o);
79      }
80    }
81  
82    
83    private static Boolean valid;
84  
85    
86    protected static synchronized void initialize() {
87      if (valid == null) {
88        
89        valid = Boolean.TRUE;
90  
91        
92        VFS.VFS = checkNotNull(getClass("org.jboss.vfs.VFS"));
93        VirtualFile.VirtualFile = checkNotNull(getClass("org.jboss.vfs.VirtualFile"));
94  
95        
96        VFS.getChild = checkNotNull(getMethod(VFS.VFS, "getChild", URL.class));
97        VirtualFile.getChildrenRecursively = checkNotNull(getMethod(VirtualFile.VirtualFile,
98            "getChildrenRecursively"));
99        VirtualFile.getPathNameRelativeTo = checkNotNull(getMethod(VirtualFile.VirtualFile,
100           "getPathNameRelativeTo", VirtualFile.VirtualFile));
101 
102       
103       checkReturnType(VFS.getChild, VirtualFile.VirtualFile);
104       checkReturnType(VirtualFile.getChildrenRecursively, List.class);
105       checkReturnType(VirtualFile.getPathNameRelativeTo, String.class);
106     }
107   }
108 
109   
110 
111 
112 
113 
114 
115   protected static <T> T checkNotNull(T object) {
116     if (object == null) {
117       setInvalid();
118     }
119     return object;
120   }
121 
122   
123 
124 
125 
126 
127 
128 
129 
130   protected static void checkReturnType(Method method, Class<?> expected) {
131     if (method != null && !expected.isAssignableFrom(method.getReturnType())) {
132       log.error("Method " + method.getClass().getName() + "." + method.getName()
133           + "(..) should return " + expected.getName() + " but returns "
134           + method.getReturnType().getName() + " instead.");
135       setInvalid();
136     }
137   }
138 
139   
140   protected static void setInvalid() {
141     if (JBoss6VFS.valid == Boolean.TRUE) {
142       log.debug("JBoss 6 VFS API is not available in this environment.");
143       JBoss6VFS.valid = Boolean.FALSE;
144     }
145   }
146 
147   static {
148     initialize();
149   }
150 
151   @Override
152   public boolean isValid() {
153     return valid;
154   }
155 
156   @Override
157   public List<String> list(URL url, String path) throws IOException {
158     VirtualFile directory;
159     directory = VFS.getChild(url);
160     if (directory == null) {
161       return Collections.emptyList();
162     }
163 
164     if (!path.endsWith("/")) {
165       path += "/";
166     }
167 
168     List<VirtualFile> children = directory.getChildren();
169     List<String> names = new ArrayList<>(children.size());
170     for (VirtualFile vf : children) {
171       names.add(path + vf.getPathNameRelativeTo(directory));
172     }
173 
174     return names;
175   }
176 }