1 package com.atlassian.plugin.osgi.factory.transform.stage;
2
3 import com.atlassian.plugin.osgi.factory.transform.PluginTransformationException;
4 import com.atlassian.plugin.osgi.factory.transform.TransformContext;
5 import com.atlassian.plugin.osgi.factory.transform.TransformStage;
6 import com.atlassian.plugin.osgi.hostcomponents.HostComponentRegistration;
7 import com.atlassian.plugin.util.ClassLoaderUtils;
8 import org.dom4j.Attribute;
9 import org.dom4j.DocumentHelper;
10 import org.dom4j.XPath;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.Method;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20
21
22
23
24
25 public class ScanDescriptorForHostClassesStage implements TransformStage
26 {
27 private static final Logger log = LoggerFactory.getLogger(ScanDescriptorForHostClassesStage.class);
28
29 @SuppressWarnings("unchecked")
30 public void execute(TransformContext context) throws PluginTransformationException
31 {
32 XPath xpath = DocumentHelper.createXPath("//@class");
33 List<Attribute> attributes = xpath.selectNodes(context.getDescriptorDocument());
34 for (Attribute attr : attributes)
35 {
36 String className = attr.getValue();
37
38 scanForHostComponents(context, className);
39
40 int dotpos = className.lastIndexOf(".");
41 if (dotpos > -1)
42 {
43 String pkg = className.substring(0, dotpos);
44 String pkgPath = pkg.replace('.', '/') + '/';
45
46
47 if (context.getSystemExports().isExported(pkg))
48 {
49 if (context.getPluginArtifact().doesResourceExist(pkgPath))
50 {
51 log.warn("The plugin '" + context.getPluginArtifact().toString() + "' uses a package '" +
52 pkg + "' that is also exported by the application. It is highly recommended that the " +
53 "plugin use its own packages.");
54 }
55 else
56 {
57 context.getExtraImports().add(pkg);
58 }
59 }
60 }
61 }
62 }
63
64 private void scanForHostComponents(TransformContext context, String className)
65 {
66
67 if (className != null && className.indexOf(":") != -1)
68 {
69 return;
70 }
71
72 Map<Class<?>, HostComponentRegistration> hostComponentInterfaces = new HashMap<Class<?>, HostComponentRegistration>();
73 for (HostComponentRegistration registration : context.getHostComponentRegistrations())
74 {
75 for (Class<?> cls : registration.getMainInterfaceClasses())
76 {
77 hostComponentInterfaces.put(cls, registration);
78 }
79 }
80
81 Class cls;
82 try
83 {
84 cls = ClassLoaderUtils.loadClass(className, getClass());
85 }
86 catch (ClassNotFoundException e)
87 {
88
89 return;
90 }
91
92
93 for (Constructor ctor : cls.getConstructors())
94 {
95 for (Class<?> ctorParam : ctor.getParameterTypes())
96 {
97 if (hostComponentInterfaces.containsKey(ctorParam))
98 {
99 context.addRequiredHostComponent(hostComponentInterfaces.get(ctorParam));
100 }
101 }
102 }
103
104
105 for (Method method : cls.getMethods())
106 {
107 if (method.getName().startsWith("set") && method.getParameterTypes().length == 1)
108 {
109 if (hostComponentInterfaces.containsKey(method.getParameterTypes()[0]))
110 {
111 context.addRequiredHostComponent(hostComponentInterfaces.get(method.getParameterTypes()[0]));
112 }
113 }
114 }
115 }
116 }