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 static com.atlassian.plugin.util.validation.ValidationPattern.createPattern;
7   import static com.atlassian.plugin.util.validation.ValidationPattern.test;
8   import com.atlassian.plugin.util.validation.ValidationPattern;
9   import com.atlassian.plugin.util.PluginUtils;
10  import org.dom4j.Document;
11  import org.dom4j.Element;
12  
13  import java.util.List;
14  
15  /**
16   * Transforms module-type elements into the appropriate Spring XML configuration file
17   *
18   * @since 2.2.0
19   */
20  public class ModuleTypeSpringStage implements TransformStage
21  {
22      /** The name of the generated Spring XML file for this stage */
23      private static final String SPRING_XML = "META-INF/spring/atlassian-plugins-module-types.xml";
24      static final String HOST_CONTAINER = "springHostContainer";
25      static final String SPRING_HOST_CONTAINER = "com.atlassian.plugin.osgi.bridge.external.SpringHostContainer";
26  
27      public void execute(TransformContext context) throws PluginTransformationException
28      {
29          if (SpringHelper.shouldGenerateFile(context, SPRING_XML))
30          {
31              Document doc = SpringHelper.createSpringDocument();
32              Element root = doc.getRootElement();
33              List<Element> elements = context.getDescriptorDocument().getRootElement().elements("module-type");
34              if (elements.size() > 0)
35              {
36                  context.getExtraImports().add("com.atlassian.plugin.osgi.external");
37                  context.getExtraImports().add("com.atlassian.plugin.osgi.bridge.external");
38                  context.getExtraImports().add("com.atlassian.plugin");
39                  Element hostContainerBean = root.addElement("beans:bean");
40                  hostContainerBean.addAttribute("id", HOST_CONTAINER);
41                  hostContainerBean.addAttribute("class", SPRING_HOST_CONTAINER);
42  
43                  ValidationPattern validation = createPattern().
44                          rule(
45                              test("@key").withError("The key is required"),
46                              test("@class").withError("The class is required"));
47                  for (Element e : elements)
48                  {
49                      if (!PluginUtils.doesModuleElementApplyToApplication(e, context.getApplicationKeys()))
50                      {
51                          continue;
52                      }
53                      validation.evaluate(e);
54                      Element bean = root.addElement("beans:bean");
55                      bean.addAttribute("id", getBeanId(e));
56                      bean.addAttribute("class", "com.atlassian.plugin.osgi.external.SingleModuleDescriptorFactory");
57  
58                      Element arg = bean.addElement("beans:constructor-arg");
59                      arg.addAttribute("index", "0");
60                      arg.addAttribute("ref", HOST_CONTAINER);
61                      Element arg2 = bean.addElement("beans:constructor-arg");
62                      arg2.addAttribute("index", "1");
63                      Element value2 = arg2.addElement("beans:value");
64                      value2.setText(e.attributeValue("key"));
65                      Element arg3 = bean.addElement("beans:constructor-arg");
66                      arg3.addAttribute("index", "2");
67                      Element value3 = arg3.addElement("beans:value");
68                      value3.setText(e.attributeValue("class"));
69  
70                      Element osgiService = root.addElement("osgi:service");
71                      osgiService.addAttribute("id", getBeanId(e) + "_osgiService");
72                      osgiService.addAttribute("ref", getBeanId(e));
73                      osgiService.addAttribute("auto-export", "interfaces");
74                  }
75              }
76  
77              if (root.elements().size() > 0)
78              {
79                  context.setShouldRequireSpring(true);
80                  context.getFileOverrides().put(SPRING_XML, SpringHelper.documentToBytes(doc));
81              }
82          }
83      }
84  
85      private String getBeanId(Element e)
86      {
87          return "moduleType-" + e.attributeValue("key");
88      }
89  }