1 package com.atlassian.plugin.spring.scanner.runtime.impl;
2
3 import com.atlassian.plugin.osgi.factory.OsgiPlugin;
4 import com.atlassian.plugin.spring.scanner.util.CommonConstants;
5 import org.eclipse.gemini.blueprint.service.importer.support.OsgiServiceProxyFactoryBean;
6 import org.osgi.framework.Bundle;
7 import org.osgi.framework.BundleContext;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.beans.BeansException;
11 import org.springframework.beans.factory.config.BeanDefinition;
12 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
13 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
14 import org.springframework.beans.factory.support.AbstractBeanDefinition;
15 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
16 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
17
18 import java.beans.Introspector;
19 import java.net.URL;
20 import java.util.Properties;
21 import java.util.Set;
22 import java.util.TreeSet;
23
24 import static com.atlassian.plugin.spring.scanner.runtime.impl.util.AnnotationIndexReader.getIndexFilesForProfiles;
25 import static com.atlassian.plugin.spring.scanner.runtime.impl.util.AnnotationIndexReader.readAllIndexFilesForProduct;
26 import static com.atlassian.plugin.spring.scanner.runtime.impl.util.AnnotationIndexReader.readPropertiesFile;
27 import static com.atlassian.plugin.spring.scanner.runtime.impl.util.AnnotationIndexReader.splitProfiles;
28
29
30
31
32
33
34 @SuppressWarnings("UnusedDeclaration")
35 public class ComponentImportBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
36 private final BundleContext bundleContext;
37 private String profileName;
38
39 private static final Logger log = LoggerFactory.getLogger(ComponentImportBeanFactoryPostProcessor.class);
40
41 public ComponentImportBeanFactoryPostProcessor(final BundleContext bundleContext) {
42 this.bundleContext = bundleContext;
43 this.profileName = null;
44 }
45
46
47
48
49
50
51
52 @Override
53 public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
54 final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
55
56 final Bundle bundle = bundleContext.getBundle();
57
58 final String[] profileNames = splitProfiles(profileName);
59 final Set<String> classNames = new TreeSet<String>();
60 for (final String fileToRead : getIndexFilesForProfiles(profileNames, CommonConstants.COMPONENT_IMPORT_KEY)) {
61 classNames.addAll(readAllIndexFilesForProduct(fileToRead, bundle, bundleContext));
62 }
63 for (final String className : classNames) {
64 final String[] typeAndName = className.split("#");
65 final String beanType = typeAndName[0];
66 final String beanName = (typeAndName.length > 1) ? typeAndName[1] : "";
67
68 try {
69 final Class beanClass = beanFactory.getBeanClassLoader().loadClass(beanType);
70 registerComponentImportBean(registry, beanClass, beanName);
71 } catch (final ClassNotFoundException e) {
72 log.error("Unable to load class '" + beanType + "' for component importation purposes. Skipping...");
73 }
74 }
75
76 processMetaData(registry, profileNames);
77 }
78
79 private void processMetaData(final BeanDefinitionRegistry registry, final String[] profileNames) {
80 for (final String fileToRead : getIndexFilesForProfiles(profileNames, CommonConstants.METADATA_FILE)) {
81 final URL url = bundleContext.getBundle().getEntry(fileToRead);
82 processMetaDataProperties(registry, readPropertiesFile(url));
83 }
84 }
85
86 private void processMetaDataProperties(final BeanDefinitionRegistry registry, final Properties properties) {
87
88
89
90 }
91
92
93
94
95
96
97
98
99 private void registerComponentImportBean(final BeanDefinitionRegistry registry, final Class beanClass, final String beanName) {
100 String serviceBeanName = beanName;
101
102 if ("".equals(serviceBeanName)) {
103 serviceBeanName = Introspector.decapitalize(beanClass.getSimpleName());
104 }
105
106 registerBeanDefinition(registry, serviceBeanName, "(objectClass=" + beanClass.getName() + ")", beanClass);
107 }
108
109
110
111
112
113
114
115
116
117 private void registerBeanDefinition(
118 final BeanDefinitionRegistry registry, final String beanName, final String filter, final Class interfaces) {
119
120
121 final Class osgiServiceProxyFactoryBeanClass = OsgiServiceProxyFactoryBean.class;
122 final BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(osgiServiceProxyFactoryBeanClass);
123 builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
124 builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
125
126
127 if (filter != null && !filter.trim().isEmpty()) {
128 builder.addPropertyValue("filter", filter);
129 }
130
131 builder.addPropertyValue("interfaces", new Class[]{interfaces});
132 builder.addPropertyValue("beanClassLoader", OsgiPlugin.class.getClassLoader());
133
134 final BeanDefinition newDefinition = builder.getBeanDefinition();
135
136 registry.registerBeanDefinition(beanName, newDefinition);
137 }
138
139 public void setProfileName(final String profileName) {
140 this.profileName = profileName;
141 }
142 }