PageRenderTime 27ms CodeModel.GetById 16ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/plugin-module-codegen-engine/src/main/java/com/atlassian/plugins/codegen/annotations/asm/ModuleCreatorAnnotationParser.java

https://bitbucket.org/mmeinhold/amps
Java | 185 lines | 149 code | 31 blank | 5 comment | 8 complexity | 309cd813d6e1ce0e7383eee9b8a8f02c MD5 | raw file
  1package com.atlassian.plugins.codegen.annotations.asm;
  2
  3import java.io.InputStream;
  4import java.util.HashMap;
  5import java.util.Map;
  6
  7import com.atlassian.plugins.codegen.annotations.*;
  8import com.atlassian.plugins.codegen.modules.PluginModuleCreator;
  9import com.atlassian.plugins.codegen.modules.PluginModuleCreatorRegistry;
 10
 11import org.apache.commons.io.IOUtils;
 12import org.apache.commons.lang.ArrayUtils;
 13import org.apache.commons.lang.StringUtils;
 14import org.objectweb.asm.AnnotationVisitor;
 15import org.objectweb.asm.ClassReader;
 16import org.objectweb.asm.FieldVisitor;
 17import org.objectweb.asm.MethodVisitor;
 18import org.objectweb.asm.commons.EmptyVisitor;
 19
 20/**
 21 * @since 3.6
 22 */
 23public class ModuleCreatorAnnotationParser extends AbstractAnnotationParser
 24{
 25
 26    public static final String MODULE_PACKAGE = "com.atlassian.plugins.codegen.modules";
 27    protected static final Map<String, String> annotationProductMap = new HashMap<String, String>();
 28
 29    static
 30    {
 31        annotationProductMap.put(JiraPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.JIRA);
 32        annotationProductMap.put(ConfluencePluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.CONFLUENCE);
 33        annotationProductMap.put(BambooPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.BAMBOO);
 34        annotationProductMap.put(CrowdPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.CROWD);
 35        annotationProductMap.put(FeCruPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.FECRU);
 36        annotationProductMap.put(StashPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.STASH);
 37        annotationProductMap.put(RefAppPluginModuleCreator.class.getName(), PluginModuleCreatorRegistry.REFAPP);
 38    }
 39
 40    private final PluginModuleCreatorRegistry pluginModuleCreatorRegistry;
 41
 42    public ModuleCreatorAnnotationParser(PluginModuleCreatorRegistry pluginModuleCreatorRegistry)
 43    {
 44        super();
 45        this.pluginModuleCreatorRegistry = pluginModuleCreatorRegistry;
 46    }
 47
 48    public void parse() throws Exception
 49    {
 50        ClassLoader oldLoader = Thread.currentThread()
 51                .getContextClassLoader();
 52        Thread.currentThread()
 53                .setContextClassLoader(getClass().getClassLoader());
 54        parse(MODULE_PACKAGE, new ModuleClassVisitor());
 55        Thread.currentThread()
 56                .setContextClassLoader(oldLoader);
 57    }
 58
 59    public void parse(String basePackage) throws Exception
 60    {
 61        ClassLoader oldLoader = Thread.currentThread()
 62                .getContextClassLoader();
 63        Thread.currentThread()
 64                .setContextClassLoader(getClass().getClassLoader());
 65        parse(basePackage, new ModuleClassVisitor());
 66        Thread.currentThread()
 67                .setContextClassLoader(oldLoader);
 68    }
 69
 70    public class ModuleClassVisitor extends EmptyVisitor
 71    {
 72
 73        private String visitedClassname;
 74        private boolean isModuleCreator;
 75
 76        @Override
 77        public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)
 78        {
 79            this.visitedClassname = normalize(name);
 80            String iface = PluginModuleCreator.class.getName()
 81                    .replace('.', '/');
 82            this.isModuleCreator = ArrayUtils.contains(interfaces, iface);
 83            if (!isModuleCreator)
 84            {
 85                this.isModuleCreator = superHasInterface(superName, iface);
 86            }
 87        }
 88
 89        private boolean superHasInterface(String superName, String interfaceName)
 90        {
 91            boolean hasInterface = false;
 92
 93            if (normalize(superName).equals("java.lang.Object"))
 94            {
 95                return hasInterface;
 96            }
 97
 98            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 99            String path = superName.replace('.', '/');
100
101            InputStream is = null;
102            try
103            {
104                is = classLoader.getResourceAsStream(path + ".class");
105                if (null != is)
106                {
107
108                    ClassReader classReader = new ClassReader(is);
109                    hasInterface = ArrayUtils.contains(classReader.getInterfaces(), interfaceName);
110                    if (!hasInterface)
111                    {
112                        hasInterface = superHasInterface(classReader.getSuperName(), interfaceName);
113                    }
114                }
115            } catch (Exception e)
116            {
117                //don't care
118            } finally
119            {
120                IOUtils.closeQuietly(is);
121            }
122
123            return hasInterface;
124        }
125
126        @Override
127        public AnnotationVisitor visitAnnotation(String annotationName, boolean isVisible)
128        {
129            String normalizedName = normalize(annotationName);
130
131            if (isModuleCreator && annotationProductMap.containsKey(normalizedName))
132            {
133                return new ProductCreatorAnnotationVisitor(normalizedName);
134            }
135
136            return null;
137        }
138
139
140        @Override
141        public MethodVisitor visitMethod(int i, String s, String s1, String s2, String[] strings)
142        {
143            return null;
144        }
145
146        @Override
147        public FieldVisitor visitField(int i, String s, String s1, String s2, Object o)
148        {
149            return null;
150        }
151
152        private class ProductCreatorAnnotationVisitor extends EmptyVisitor
153        {
154
155            private String annotationName;
156
157            private ProductCreatorAnnotationVisitor(String annotationName)
158            {
159                this.annotationName = annotationName;
160            }
161
162            @Override
163            public void visitEnd()
164            {
165
166                super.visitEnd();
167
168                String productId = annotationProductMap.get(annotationName);
169                if (StringUtils.isNotBlank(productId))
170                {
171                    try
172                    {
173                        PluginModuleCreator creator = (PluginModuleCreator) Class.forName(visitedClassname)
174                                .newInstance();
175                        pluginModuleCreatorRegistry.registerModuleCreator(productId, creator);
176                    } catch (Exception e)
177                    {
178                        e.printStackTrace();
179                        //just don't register
180                    }
181                }
182            }
183        }
184    }
185}