View Javadoc

1   package com.atlassian.plugin.spring;
2   
3   import com.atlassian.plugin.osgi.hostcomponents.ContextClassLoaderStrategy;
4   import org.springframework.beans.factory.config.BeanDefinition;
5   import org.springframework.beans.factory.support.BeanDefinitionBuilder;
6   import org.springframework.beans.factory.support.BeanDefinitionRegistry;
7   
8   import java.util.ArrayList;
9   import java.util.Collection;
10  import java.util.Collections;
11  import java.util.HashMap;
12  import java.util.HashSet;
13  import java.util.List;
14  import java.util.Map;
15  import java.util.Set;
16  
17  import static com.atlassian.plugin.util.Assertions.notNull;
18  
19  public class PluginBeanDefinitionRegistry
20  {
21      public static final String HOST_COMPONENT_PROVIDER = "hostComponentProvider";
22  
23      private static final String BEAN_NAMES = "beanNames";
24      private static final String BEAN_INTERFACES = "beanInterfaces";
25      private static final String BEAN_CONTEXT_CLASS_LOADER_STRATEGIES = "beanContextClassLoaderStrategies";
26      private static final String BUNDLE_TRACKING_BEANS = "bundleTrackingBeans";
27  
28      private final BeanDefinitionRegistry registry;
29  
30      public PluginBeanDefinitionRegistry(BeanDefinitionRegistry registry)
31      {
32          this.registry = notNull("registry", registry);
33      }
34  
35      public BeanDefinition getBeanDefinition()
36      {
37          if (!registry.containsBeanDefinition(HOST_COMPONENT_PROVIDER))
38          {
39              BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(SpringHostComponentProviderFactoryBean.class);
40              BeanDefinition beanDef = builder.getBeanDefinition();
41              primeHostComponentBeanDefinition(beanDef);
42  
43              registry.registerBeanDefinition(HOST_COMPONENT_PROVIDER, beanDef);
44          }
45  
46          final BeanDefinition beanDef = registry.getBeanDefinition(HOST_COMPONENT_PROVIDER);
47          primeHostComponentBeanDefinition(beanDef);
48  
49          if (beanDef == null)
50          {
51              throw new IllegalStateException("Host component provider not found nor created. This should never happen.");
52          }
53          return beanDef;
54      }
55  
56      private void primeHostComponentBeanDefinition(BeanDefinition beanDef)
57      {
58          ensurePropertyNotNull(beanDef, BEAN_NAMES, new ArrayList<String>());
59          ensurePropertyNotNull(beanDef, BEAN_INTERFACES, new HashMap<String, List<String>>());
60          ensurePropertyNotNull(beanDef, BEAN_CONTEXT_CLASS_LOADER_STRATEGIES, new HashMap<String, ContextClassLoaderStrategy>());
61          ensurePropertyNotNull(beanDef, BUNDLE_TRACKING_BEANS, new HashSet<String>());
62      }
63  
64      private void ensurePropertyNotNull(BeanDefinition beanDef, String propertyName, Object defaultValue)
65      {
66          if (!beanDef.getPropertyValues().contains(propertyName))
67          {
68              beanDef.getPropertyValues().addPropertyValue(propertyName, defaultValue);
69          }
70      }
71  
72      public void addBeanName(String beanName)
73      {
74          getBeanNames().add(beanName);
75      }
76  
77      public void addBeanInterface(String beanName, String ifce)
78      {
79          addBeanInterfaces(beanName, Collections.singleton(ifce));
80      }
81  
82      public void addBeanInterfaces(String beanName, Collection<String> ifces)
83      {
84          final Map<String, List<String>> beanInterfaces = getBeanInterfaces();
85  
86          List<String> interfaces = beanInterfaces.get(beanName);
87          if (interfaces == null)
88          {
89              interfaces = new ArrayList<String>();
90              beanInterfaces.put(beanName, interfaces);
91          }
92          interfaces.addAll(ifces);
93      }
94  
95      public void addContextClassLoaderStrategy(String beanName, ContextClassLoaderStrategy strategy)
96      {
97          getBeanContextClassLoaderStrategies().put(beanName, strategy);
98      }
99  
100     public void addBundleTrackingBean(String beanName)
101     {
102         getBundleTrackingBeans().add(beanName);
103     }
104 
105     @SuppressWarnings("unchecked")
106     private Map<String, ContextClassLoaderStrategy> getBeanContextClassLoaderStrategies()
107     {
108         return (Map<String, ContextClassLoaderStrategy>) getPropertyValue(BEAN_CONTEXT_CLASS_LOADER_STRATEGIES);
109     }
110 
111     @SuppressWarnings("unchecked")
112     private Map<String, List<String>> getBeanInterfaces()
113     {
114         return (Map<String, List<String>>) getPropertyValue(BEAN_INTERFACES);
115     }
116 
117     @SuppressWarnings("unchecked")
118     private List<String> getBeanNames()
119     {
120         return (List<String>) getPropertyValue(BEAN_NAMES);
121     }
122 
123     @SuppressWarnings("unchecked")
124     private Set<String> getBundleTrackingBeans()
125     {
126         return (Set<String>) getPropertyValue(BUNDLE_TRACKING_BEANS);
127     }
128 
129     private Object getPropertyValue(String propertyName)
130     {
131         return getBeanDefinition().getPropertyValues().getPropertyValue(propertyName).getValue();
132     }
133 }