1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.struts2.osgi;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27 import java.net.MalformedURLException;
28 import java.util.*;
29 import java.util.Map.Entry;
30
31 import org.osgi.framework.Bundle;
32 import org.osgi.framework.BundleContext;
33 import org.osgi.framework.InvalidSyntaxException;
34 import org.osgi.framework.ServiceReference;
35
36 import com.opensymphony.xwork2.util.logging.Logger;
37 import com.opensymphony.xwork2.util.logging.LoggerFactory;
38 import com.opensymphony.xwork2.ActionContext;
39 import com.opensymphony.xwork2.ActionInvocation;
40 import com.opensymphony.xwork2.ActionProxy;
41 import com.opensymphony.xwork2.inject.Inject;
42 import com.opensymphony.xwork2.config.entities.ActionConfig;
43
44 /***
45 * Helper class that find resources and loads classes from the list of bundles
46 */
47 public class DefaultBundleAccessor implements BundleAccessor {
48
49 private static DefaultBundleAccessor self;
50 private static final Logger LOG = LoggerFactory.getLogger(DefaultBundleAccessor.class);
51
52 private BundleContext bundleContext;
53 private Map<String, String> packageToBundle = new HashMap<String, String>();
54 private Map<Bundle, Set<String>> packagesByBundle = new HashMap<Bundle, Set<String>>();
55 private OsgiHost osgiHost;
56
57 public DefaultBundleAccessor() {
58 self = this;
59 }
60
61 public static DefaultBundleAccessor getInstance() {
62 return self;
63 }
64
65 public Object getService(ServiceReference ref) {
66 return bundleContext != null ? bundleContext.getService(ref) : null;
67 }
68
69 public ServiceReference getServiceReference(String className) {
70 return bundleContext != null ? bundleContext.getServiceReference(className) : null;
71 }
72
73 public ServiceReference[] getAllServiceReferences(String className) {
74 if (bundleContext != null) {
75 try {
76 return bundleContext.getServiceReferences(className, null);
77 } catch (InvalidSyntaxException e) {
78
79 if (LOG.isErrorEnabled())
80 LOG.error("Invalid syntax for service lookup", e);
81 }
82 }
83
84 return null;
85 }
86
87 public ServiceReference[] getServiceReferences(String className, String params) throws InvalidSyntaxException {
88 return bundleContext != null ? bundleContext.getServiceReferences(className, params) : null;
89 }
90
91 /***
92 * Add as Bundle -> Package mapping
93 * @param bundle the bundle where the package was loaded from
94 * @param packageName the anme of the loaded package
95 */
96 public void addPackageFromBundle(Bundle bundle, String packageName) {
97 this.packageToBundle.put(packageName, bundle.getSymbolicName());
98 Set<String> pkgs = packagesByBundle.get(bundle);
99 if (pkgs == null) {
100 pkgs = new HashSet<String>();
101 packagesByBundle.put(bundle, pkgs);
102 }
103 pkgs.add(packageName);
104 }
105
106 public Class<?> loadClass(String className) throws ClassNotFoundException {
107 Bundle bundle = getCurrentBundle();
108 if (bundle != null) {
109 Class cls = bundle.loadClass(className);
110 if (LOG.isTraceEnabled())
111 LOG.trace("Located class [#0] in bundle [#1]", className, bundle.getSymbolicName());
112 return cls;
113 }
114
115 throw new ClassNotFoundException("Unable to find class " + className);
116 }
117
118 private Bundle getCurrentBundle() {
119 ActionContext ctx = ActionContext.getContext();
120 String bundleName = (String) ctx.get(CURRENT_BUNDLE_NAME);
121 if (bundleName == null) {
122 ActionInvocation inv = ctx.getActionInvocation();
123 ActionProxy proxy = inv.getProxy();
124 ActionConfig actionConfig = proxy.getConfig();
125 bundleName = packageToBundle.get(actionConfig.getPackageName());
126 }
127 if (bundleName != null) {
128 return osgiHost.getActiveBundles().get(bundleName);
129 }
130 return null;
131 }
132
133 public List<URL> loadResources(String name) throws IOException {
134 return loadResources(name, false);
135 }
136
137 public List<URL> loadResources(String name, boolean translate) throws IOException {
138 Bundle bundle = getCurrentBundle();
139 if (bundle != null) {
140 List<URL> resources = new ArrayList<URL>();
141 Enumeration e = bundle.getResources(name);
142 while (e.hasMoreElements()) {
143 resources.add(translate ? OsgiUtil.translateBundleURLToJarURL((URL) e.nextElement(), getCurrentBundle()) : (URL) e.nextElement());
144 }
145 return resources;
146 }
147
148 return null;
149 }
150
151 public URL loadResourceFromAllBundles(String name) throws IOException {
152 for (Map.Entry<String, Bundle> entry : osgiHost.getActiveBundles().entrySet()) {
153 Enumeration e = entry.getValue().getResources(name);
154 if (e.hasMoreElements()) {
155 return (URL) e.nextElement();
156 }
157 }
158
159 return null;
160 }
161
162 public InputStream loadResourceFromAllBundlesAsStream(String name) throws IOException {
163 URL url = loadResourceFromAllBundles(name);
164 if (url != null) {
165 return url.openStream();
166 }
167 return null;
168 }
169
170 public URL loadResource(String name) {
171 return loadResource(name, false);
172 }
173
174 public URL loadResource(String name, boolean translate) {
175 Bundle bundle = getCurrentBundle();
176 if (bundle != null) {
177 URL url = bundle.getResource(name);
178 try {
179 return translate ? OsgiUtil.translateBundleURLToJarURL(url, getCurrentBundle()) : url;
180 } catch (Exception e) {
181 if (LOG.isErrorEnabled()) {
182 LOG.error("Unable to translate bundle URL to jar URL", e);
183 }
184
185 return null;
186 }
187 }
188
189 return null;
190 }
191
192 public Set<String> getPackagesByBundle(Bundle bundle) {
193 return packagesByBundle.get(bundle);
194 }
195
196 public InputStream loadResourceAsStream(String name) throws IOException {
197 URL url = loadResource(name);
198 if (url != null) {
199 return url.openStream();
200 }
201 return null;
202 }
203
204 public void setBundleContext(BundleContext bundleContext) {
205 this.bundleContext = bundleContext;
206 }
207
208 public void setOsgiHost(OsgiHost osgiHost) {
209 this.osgiHost = osgiHost;
210 }
211 }