View Javadoc

1   package com.atlassian.plugin.spring.pluginns;
2   
3   import org.springframework.beans.factory.config.BeanDefinition;
4   import org.springframework.beans.factory.config.BeanDefinitionHolder;
5   import org.springframework.beans.factory.support.BeanDefinitionBuilder;
6   import org.springframework.beans.factory.support.BeanDefinitionRegistry;
7   import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
8   import org.springframework.beans.factory.xml.ParserContext;
9   import org.springframework.beans.factory.BeanFactory;
10  import org.springframework.beans.factory.HierarchicalBeanFactory;
11  import org.w3c.dom.Attr;
12  import org.w3c.dom.Node;
13  
14  import java.util.ArrayList;
15  import java.util.List;
16  import java.lang.IllegalStateException;
17  import static com.atlassian.plugin.spring.pluginns.SpringXmlHostComponentProvider.HOST_COMPONENT_PROVIDER;
18  
19  /**
20   * Processes an "available" attribute in the plugin namespace.  Also handles registering the {@link SpringXmlHostComponentProvider}.
21   *
22   * In the case of hierarchical contexts we will put the host
23   * component provider in the lowest possible context.
24   */
25  public class PluginAvailableBeanDefinitionDecorator implements BeanDefinitionDecorator
26  {
27  
28      /**
29       * Called when the Spring parser encounters an "available" attribute.
30       * @param source The attribute
31       * @param holder The containing bean definition
32       * @param ctx The parser context
33       * @return The containing bean definition
34       */
35      public BeanDefinitionHolder decorate(
36              Node source, BeanDefinitionHolder holder, ParserContext ctx)
37      {
38  
39          String isAvailable = ((Attr) source).getValue();
40          if (Boolean.parseBoolean(isAvailable))
41          {
42              BeanDefinition providerDef = registerHostComponent(ctx);
43              List<String> registrations = (List<String>) providerDef.getPropertyValues().getPropertyValue("registrations").getValue();
44              registrations.add(holder.getBeanName());
45          }
46          return holder;
47  
48      }
49  
50      /**
51       * Registered a host component provider, if none already exist
52       * @param ctx The parser context
53       * @return The discovered host component provider definition
54       */
55      private BeanDefinition registerHostComponent(ParserContext ctx)
56      {
57          BeanDefinition providerDef;
58  
59          BeanDefinitionRegistry registry = ctx.getRegistry();
60  
61          if (!registry.containsBeanDefinition(HOST_COMPONENT_PROVIDER))
62          {
63              BeanDefinitionBuilder providerDefBuilder = BeanDefinitionBuilder.rootBeanDefinition(SpringXmlHostComponentProvider.class);
64              providerDefBuilder.addPropertyValue("registrations", new ArrayList());
65              providerDef = providerDefBuilder.getBeanDefinition();
66              ctx.getRegistry().registerBeanDefinition(HOST_COMPONENT_PROVIDER, providerDef);
67          }
68          else
69              providerDef = registry.getBeanDefinition(HOST_COMPONENT_PROVIDER);
70  
71  
72          if (providerDef == null)
73          {
74              throw new IllegalStateException("Host component provider not found or created. This should never happen.");
75          }
76          
77          return providerDef;
78      }
79  }