1 package com.atlassian.maven.plugins.amps.codegen.annotations.asm;
2
3 import java.io.InputStream;
4 import java.util.Map;
5
6 import com.atlassian.plugins.codegen.annotations.asm.AbstractAnnotationParser;
7
8 import org.apache.commons.io.IOUtils;
9 import org.apache.commons.lang.ArrayUtils;
10 import org.apache.commons.lang.StringUtils;
11 import org.apache.maven.plugin.logging.Log;
12 import org.objectweb.asm.AnnotationVisitor;
13 import org.objectweb.asm.ClassReader;
14 import org.objectweb.asm.FieldVisitor;
15 import org.objectweb.asm.MethodVisitor;
16 import org.objectweb.asm.commons.EmptyVisitor;
17
18
19
20
21 public class CustomFieldTypeLocator extends AbstractAnnotationParser
22 {
23 public static final String JIRA_FIELDS_PACKAGE = "com.atlassian.jira.issue.customfields.impl";
24
25 private Log log;
26 private Map<String, String> fieldTypeRegistry;
27
28 public CustomFieldTypeLocator(Map<String, String> fieldTypeRegistry)
29 {
30 this.fieldTypeRegistry = fieldTypeRegistry;
31 }
32
33 public void parse() throws Exception
34 {
35 parse(JIRA_FIELDS_PACKAGE, new FieldClassVisitor());
36 }
37
38 public void parse(String basePackage) throws Exception
39 {
40 parse(basePackage, new FieldClassVisitor());
41 }
42
43 public class FieldClassVisitor extends EmptyVisitor
44 {
45
46 private String visitedClassname;
47 private boolean isCustomFieldType;
48
49 @Override
50 public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)
51 {
52 this.visitedClassname = normalize(name);
53 String iface = "com/atlassian/jira/issue/customfields/CustomFieldType";
54
55 this.isCustomFieldType = false;
56
57 this.isCustomFieldType = ArrayUtils.contains(interfaces, iface);
58 if (!isCustomFieldType)
59 {
60 this.isCustomFieldType = superHasInterface(superName, iface);
61 }
62
63 if (isCustomFieldType)
64 {
65 String simpleName = StringUtils.substringAfterLast(visitedClassname, ".");
66 fieldTypeRegistry.put(simpleName, visitedClassname);
67 }
68
69 }
70
71 private boolean superHasInterface(String superName, String interfaceName)
72 {
73 boolean hasInterface = false;
74
75 if (normalize(superName).equals("java.lang.Object"))
76 {
77 return hasInterface;
78 }
79
80 ClassLoader classLoader = Thread.currentThread()
81 .getContextClassLoader();
82 String path = superName.replace('.', '/');
83
84 InputStream is = null;
85 try
86 {
87 is = classLoader.getResourceAsStream(path + ".class");
88 if (null != is)
89 {
90
91 ClassReader classReader = new ClassReader(is);
92 String[] interfaces = classReader.getInterfaces();
93 hasInterface = ArrayUtils.contains(classReader.getInterfaces(), interfaceName);
94 if (!hasInterface)
95 {
96 hasInterface = superHasInterface(classReader.getSuperName(), interfaceName);
97 }
98 }
99 } catch (Exception e)
100 {
101
102 } finally
103 {
104 IOUtils.closeQuietly(is);
105 }
106
107 return hasInterface;
108 }
109
110 @Override
111 public AnnotationVisitor visitAnnotation(String annotationName, boolean isVisible)
112 {
113 return null;
114 }
115
116 @Override
117 public MethodVisitor visitMethod(int i, String s, String s1, String s2, String[] strings)
118 {
119 return null;
120 }
121
122 @Override
123 public FieldVisitor visitField(int i, String s, String s1, String s2, Object o)
124 {
125 return null;
126 }
127 }
128 }