]> gerrit.simantics Code Review - simantics/platform.git/blob
2f3c869b478aa631bb652b07341ab66a8abd5dbe
[simantics/platform.git] /
1 package org.simantics.scl.osgi.internal;
2
3 import org.osgi.framework.Bundle;
4 import org.osgi.framework.BundleContext;
5 import org.osgi.framework.BundleException;
6 import org.osgi.framework.wiring.BundleWiring;
7 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
8 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
9 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
10 import org.simantics.scl.compiler.internal.codegen.types.RuntimeJavaReferenceValidator;
11 import org.simantics.scl.compiler.types.Type;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 @SuppressWarnings("restriction")
16 public class OsgiJavaReferenceValidatorFactory implements JavaReferenceValidatorFactory {
17
18     private static final Logger LOGGER = LoggerFactory.getLogger(OsgiJavaReferenceValidatorFactory.class);
19
20     private final Bundle bundle;
21
22     public OsgiJavaReferenceValidatorFactory(Bundle bundle) {
23         this.bundle = bundle;
24     }
25
26     private static ClassLoader getClassLoader(Bundle bundle) {
27         if (bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
28             return Type.class.getClassLoader();
29         else {
30             BundleWiring wiring = bundle.adapt(BundleWiring.class);
31             if (wiring == null && bundle.getState() == Bundle.INSTALLED) {
32                 LOGGER.info("Starting bundle {} with state {}", bundle.getSymbolicName(), BundleUtils.resolveBundleState(bundle));
33                 try {
34                     bundle.start();
35                 } catch (BundleException e) {
36                     throw new InternalCompilerError("Couldn't activate bundle " + bundle.getSymbolicName() + ". Bundle state is " + BundleUtils.resolveBundleState(bundle));
37                 }
38                 wiring = bundle.adapt(BundleWiring.class);
39             }
40             if (wiring != null)
41                 return wiring.getClassLoader();
42             else
43                 throw new InternalCompilerError("Cannot get the class loader for bundle " + bundle.getSymbolicName() + ". Bundle state is " + BundleUtils.resolveBundleState(bundle));
44         }
45     }
46
47     @SuppressWarnings("unchecked")
48     private static JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(Bundle bundle) {
49         if(bundle == null)
50             return null;
51         return (JavaReferenceValidator<Object, Object, Object, Object>)
52                 (JavaReferenceValidator<?, ?, ?, ?>)new RuntimeJavaReferenceValidator(getClassLoader(bundle));
53     }
54
55     private static Bundle getBundle(BundleContext bundleContext, String symbolicName) {
56         Bundle result = null;
57         for (Bundle candidate : bundleContext.getBundles())
58             if (candidate.getSymbolicName().equals(symbolicName))
59                 if (result == null || result.getVersion().compareTo(candidate.getVersion()) < 0)
60                     result = candidate;
61         return result;
62     }
63     
64     @Override
65     public JavaReferenceValidator<Object, Object, Object, Object> getJavaReferenceValidator(String bundleName) {
66         LOGGER.info("getJavaReferenceValidator(" + bundleName + ")");
67         return getJavaReferenceValidator(getBundle(bundle.getBundleContext(), bundleName));
68     }
69
70     @Override
71     public JavaReferenceValidator<Object, Object, Object, Object> getDefaultJavaReferenceValidator() {
72         return getJavaReferenceValidator(bundle);
73     }
74
75 }