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