1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.osgi;
20
21 import java.util.ArrayList;
22 import java.util.Dictionary;
23 import java.util.Hashtable;
24 import java.util.List;
25
26 import org.apache.chemistry.opencmis.client.api.SessionFactory;
27 import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
28 import org.apache.chemistry.opencmis.commons.impl.ClassLoaderUtil;
29 import org.osgi.framework.Bundle;
30 import org.osgi.framework.BundleActivator;
31 import org.osgi.framework.BundleContext;
32 import org.osgi.framework.BundleEvent;
33 import org.osgi.framework.Constants;
34 import org.osgi.framework.SynchronousBundleListener;
35 import org.osgi.framework.wiring.BundleWiring;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43 public class Activator implements BundleActivator, SynchronousBundleListener {
44
45
46
47
48
49 private static final String OPENCMIS_SPI_HEADER = "OpenCMIS-SPI";
50
51 private static Logger LOG = LoggerFactory.getLogger(Activator.class);
52
53 private BundleContext bundleContext;
54
55 @Override
56 public void start(final BundleContext context) {
57
58 this.bundleContext = context;
59
60
61 context.addBundleListener(this);
62
63 try {
64
65 for (Bundle bundle : context.getBundles()) {
66 if (bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.STARTING
67 || bundle.getState() == Bundle.ACTIVE || bundle.getState() == Bundle.STOPPING) {
68 register(bundle);
69 }
70 }
71 } catch (Exception e) {
72
73
74 LOG.warn("Could not find and register bundles that contain " + OPENCMIS_SPI_HEADER + " headers: ",
75 e.toString(), e);
76 }
77
78
79 Dictionary<String, String> props = new Hashtable<String, String>();
80 props.put(Constants.SERVICE_DESCRIPTION, "Apache Chemistry OpenCMIS Client Session Factory");
81 props.put(Constants.SERVICE_VENDOR, "Apache Software Foundation");
82
83 SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
84 context.registerService(SessionFactory.class.getName(), sessionFactory, props);
85 }
86
87 @Override
88 public void stop(final BundleContext context) {
89
90 context.removeBundleListener(this);
91
92
93 bundleContext = null;
94
95
96 ClassLoaderUtil.unregisterAllBundleClassLoaders();
97
98
99 }
100
101 @Override
102 public void bundleChanged(final BundleEvent event) {
103
104 synchronized (this) {
105 if (bundleContext == null) {
106 return;
107 }
108 }
109
110 if (event.getType() == BundleEvent.RESOLVED) {
111 register(event.getBundle());
112 } else if (event.getType() == BundleEvent.UNRESOLVED || event.getType() == BundleEvent.UNINSTALLED) {
113 unregister(event.getBundle().getBundleId());
114 }
115 }
116
117 private void register(final Bundle bundle) {
118 BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
119 if (bundleWiring == null) {
120 return;
121 }
122
123 ClassLoader classLoader = bundleWiring.getClassLoader();
124 if (classLoader == null) {
125 return;
126 }
127
128 List<String> classes = getOpenCmisSpiHeader(bundle);
129 if (classes != null) {
130 ClassLoaderUtil.registerBundleClassLoader(bundle.getBundleId(), classLoader, classes);
131 }
132 }
133
134 private void unregister(final long bundleId) {
135 ClassLoaderUtil.unregisterBundleClassLoader(bundleId);
136 }
137
138 private List<String> getOpenCmisSpiHeader(final Bundle bundle) {
139 String spiHeader = bundle.getHeaders().get(OPENCMIS_SPI_HEADER);
140 if (spiHeader == null) {
141 return null;
142 }
143
144 List<String> headerValues = new ArrayList<String>();
145
146 String[] split = spiHeader.split(",");
147 for (String className : split) {
148 if (className != null && !className.trim().isEmpty()) {
149 headerValues.add(className.trim());
150 }
151 }
152
153 return headerValues;
154 }
155 }