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.factory.transform.model.ComponentImport;
7 import com.atlassian.plugin.util.PluginUtils;
8 import org.dom4j.Document;
9 import org.dom4j.Element;
10 import org.osgi.framework.Constants;
11 import org.osgi.framework.ServiceReference;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15
16
17
18
19
20 public class ComponentImportSpringStage implements TransformStage {
21
22
23
24 private static final String SPRING_XML = "META-INF/spring/atlassian-plugins-component-imports.xml";
25
26 public static final String BEAN_SOURCE = "Component Import";
27
28 Logger log = LoggerFactory.getLogger(ComponentImportSpringStage.class);
29
30 public void execute(TransformContext context) throws PluginTransformationException {
31 if (SpringHelper.shouldGenerateFile(context, SPRING_XML)) {
32 Document springDoc = SpringHelper.createSpringDocument();
33 Element root = springDoc.getRootElement();
34
35 ServiceReference[] serviceReferences = context.getOsgiContainerManager().getRegisteredServices();
36 for (ComponentImport comp : context.getComponentImports().values()) {
37 if (!PluginUtils.doesModuleElementApplyToApplication(comp.getSource(), context.getApplications(), context.getInstallationMode())) {
38 continue;
39 }
40 Element osgiReference = root.addElement("osgi:reference");
41
42
43 context.trackBean(comp.getKey(), BEAN_SOURCE);
44
45 osgiReference.addAttribute("id", comp.getKey());
46
47 if (comp.getFilter() != null) {
48 osgiReference.addAttribute("filter", comp.getFilter());
49 }
50
51 Element interfaces = osgiReference.addElement("osgi:interfaces");
52 for (String infName : comp.getInterfaces()) {
53 validateInterface(infName, context.getPluginFile().getName(), serviceReferences);
54 context.getExtraImports().add(infName.substring(0, infName.lastIndexOf('.')));
55 Element e = interfaces.addElement("beans:value");
56 e.setText(infName);
57 }
58 }
59 if (root.elements().size() > 0) {
60 context.setShouldRequireSpring(true);
61 context.getFileOverrides().put(SPRING_XML, SpringHelper.documentToBytes(springDoc));
62 }
63 }
64 }
65
66 private void validateInterface(String interfaceName, String pluginName, ServiceReference[] serviceReferences) {
67 if (log.isDebugEnabled()) {
68 boolean found = false;
69 outer:
70 for (ServiceReference ref : serviceReferences) {
71
72 for (String clazz : (String[]) ref.getProperty(Constants.OBJECTCLASS)) {
73 if (interfaceName.equals(clazz)) {
74 found = true;
75 break outer;
76 }
77 }
78 }
79 if (!found) {
80 log.debug("Couldn't confirm that '{}' (used as a <component-import> in the plugin with name '{}')" +
81 " is a public component in the product's OSGi exports. If this is an interface you expect to" +
82 " be provided from the product, double check the spelling of '{}'; if this class" +
83 " is supposed to come from another plugin, you can probably ignore this warning.",
84 interfaceName, pluginName, interfaceName);
85 }
86 }
87
88 }
89 }