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 package org.openrdf.elmo.rolemapper;
30
31 import java.io.DataInputStream;
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.net.URL;
36 import java.net.URLDecoder;
37 import java.util.ArrayList;
38 import java.util.Enumeration;
39 import java.util.List;
40 import java.util.zip.ZipEntry;
41 import java.util.zip.ZipFile;
42
43 import javassist.bytecode.AnnotationsAttribute;
44 import javassist.bytecode.ClassFile;
45 import javassist.bytecode.annotation.Annotation;
46
47 import org.openrdf.elmo.annotations.rdf;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52
53
54
55
56
57 class Scanner {
58 private final Logger logger = LoggerFactory.getLogger(HierarchicalRoleMapper.class);
59
60 private ClassLoader cl;
61
62 private String pkgName;
63
64 private String resource;
65
66 public Scanner(ClassLoader cl, String resource) {
67 this.cl = cl;
68 this.resource = resource;
69 pkgName = rdf.class.getPackage().getName();
70 }
71
72 public List<String> scan(URL url) throws IOException {
73 String urlPath = URLDecoder.decode(url.getFile(), "UTF-8");
74 assert urlPath.endsWith(resource);
75 urlPath = urlPath.substring(0, urlPath.length() - resource.length());
76 if (urlPath.startsWith("file:")) {
77 urlPath = urlPath.substring(5);
78 }
79 if (urlPath.lastIndexOf('!') > 0) {
80 urlPath = urlPath.substring(0, urlPath.lastIndexOf('!'));
81 }
82 List<String> roles = new ArrayList<String>();
83 File file = new File(urlPath);
84 logger.info("Scanning {}", file);
85 if (file.isDirectory()) {
86 roles.addAll(scanDirectory(file, null));
87 } else {
88 ZipFile zip = new ZipFile(file);
89 Enumeration<? extends ZipEntry> entries = zip.entries();
90 while (entries.hasMoreElements()) {
91 ZipEntry entry = entries.nextElement();
92 String name = getClassName(entry.getName());
93 if (name != null) {
94 roles.add(name);
95 }
96 }
97 }
98 return roles;
99 }
100
101 private List<String> scanDirectory(File file, String path)
102 throws IOException {
103 List<String> roles = new ArrayList<String>();
104 for (File child : file.listFiles()) {
105 String newPath = path == null ? child.getName() : path + '/'
106 + child.getName();
107 if (child.isDirectory()) {
108 roles.addAll(scanDirectory(child, newPath));
109 } else {
110 String name = getClassName(newPath);
111 if (name != null) {
112 roles.add(name);
113 }
114 }
115 }
116 return roles;
117 }
118
119 private String getClassName(String name) throws IOException {
120
121 if (!name.endsWith(".class") || name.contains("-"))
122 return null;
123 InputStream stream = cl.getResourceAsStream(name);
124 assert stream != null : name;
125 DataInputStream dstream = new DataInputStream(stream);
126 try {
127 ClassFile cf = new ClassFile(dstream);
128 AnnotationsAttribute attr = (AnnotationsAttribute) cf
129 .getAttribute(AnnotationsAttribute.visibleTag);
130 if (attr == null)
131 return null;
132 Annotation[] annotations = attr.getAnnotations();
133 if (annotations == null)
134 return null;
135 for (Annotation ann : annotations) {
136 if (ann.getTypeName().startsWith(pkgName))
137 return cf.getName();
138 }
139 return null;
140 } finally {
141 dstream.close();
142 stream.close();
143 }
144 }
145 }