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