1 package com.atlassian.plugins.codegen.annotations.asm;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.JarURLConnection;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.Enumeration;
10 import java.util.List;
11 import java.util.jar.JarEntry;
12 import java.util.jar.JarFile;
13
14 import org.apache.commons.io.FileUtils;
15 import org.apache.commons.io.IOUtils;
16 import org.objectweb.asm.ClassReader;
17 import org.objectweb.asm.ClassVisitor;
18
19
20
21
22 public abstract class AbstractAnnotationParser
23 {
24
25 public void parse(String basePackage, ClassVisitor classVisitor) throws Exception
26 {
27 ClassLoader classLoader = Thread.currentThread()
28 .getContextClassLoader();
29
30 String path = basePackage.replace('.', '/');
31
32 Enumeration<URL> resources = classLoader.getResources(path);
33 List<File> dirs = new ArrayList<File>();
34 while (resources.hasMoreElements())
35 {
36 URL resource = resources.nextElement();
37 processResource(resource, basePackage, classVisitor);
38 }
39 }
40
41 protected void processResource(URL resource, String packageName, ClassVisitor classVisitor) throws IOException
42 {
43 if (resource.getProtocol()
44 .equals("file"))
45 {
46 processFileDirectory(new File(resource.getFile()), packageName, classVisitor);
47 } else if (resource.getProtocol()
48 .equals("jar"))
49 {
50 JarURLConnection conn = (JarURLConnection) resource.openConnection();
51 processJarDirectory(conn.getJarFile(), packageName, classVisitor);
52 }
53 }
54
55 protected void processJarDirectory(JarFile jarFile, String packageName, ClassVisitor classVisitor) throws IOException
56 {
57 Enumeration<JarEntry> entries = jarFile.entries();
58 String basePath = packageName.replace('.', '/');
59 while (entries.hasMoreElements())
60 {
61 JarEntry entry = entries.nextElement();
62 String name = entry.getName();
63 if (name.startsWith(basePath) && !entry.isDirectory() && name.endsWith(".class"))
64 {
65 InputStream is = jarFile.getInputStream(entry);
66 try
67 {
68 processClassFile(is, classVisitor);
69 } finally
70 {
71 IOUtils.closeQuietly(is);
72 }
73 }
74 }
75 }
76
77 protected void processFileDirectory(File directory, String packageName, ClassVisitor classVisitor) throws IOException
78 {
79 if (!directory.exists())
80 {
81 return;
82 }
83 File[] files = directory.listFiles();
84 for (File file : files)
85 {
86 if (file.isDirectory())
87 {
88 assert !file.getName()
89 .contains(".");
90 processFileDirectory(file, packageName + "." + file.getName(), classVisitor);
91 } else if (file.getName()
92 .endsWith(".class"))
93 {
94 InputStream is = FileUtils.openInputStream(file);
95
96 try
97 {
98 processClassFile(is, classVisitor);
99 } finally
100 {
101 IOUtils.closeQuietly(is);
102 }
103
104 }
105 }
106 }
107
108 protected void processClassFile(InputStream is, ClassVisitor classVisitor) throws IOException
109 {
110 ClassReader classReader = new ClassReader(is);
111 classReader.accept(classVisitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
112 }
113
114 protected static String normalize(String name)
115 {
116 if (name == null)
117 {
118 return null;
119 }
120
121 if (name.startsWith("L") && name.endsWith(";"))
122 {
123 name = name.substring(1, name.length() - 1);
124 }
125
126 if (name.endsWith(".class"))
127 {
128 name = name.substring(0, name.length() - ".class".length());
129 }
130
131 return name.replace('/', '.');
132 }
133 }