1 package org.simantics.scl.osgi.internal;
\r
4 import java.io.IOException;
\r
5 import java.io.InputStream;
\r
6 import java.net.URISyntaxException;
\r
8 import java.nio.charset.Charset;
\r
9 import java.nio.file.Files;
\r
10 import java.nio.file.Path;
\r
11 import java.nio.file.Paths;
\r
12 import java.security.MessageDigest;
\r
13 import java.security.NoSuchAlgorithmException;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Arrays;
\r
17 import org.eclipse.core.runtime.FileLocator;
\r
18 import org.osgi.framework.Bundle;
\r
19 import org.osgi.framework.wiring.BundleWiring;
\r
20 import org.simantics.scl.compiler.module.ImportDeclaration;
\r
21 import org.simantics.scl.compiler.module.repository.UpdateListener;
\r
22 import org.simantics.scl.compiler.source.EncodedTextualModuleSource;
\r
23 import org.simantics.scl.compiler.types.Type;
\r
25 public class BundleModuleSource extends EncodedTextualModuleSource {
\r
27 public static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
\r
28 new ImportDeclaration("Builtin", ""),
\r
29 new ImportDeclaration("StandardLibrary", "")
\r
32 public static final ImportDeclaration[] DEFAULT_IMPORTS_FOR_STANDARD_LIBRARY = new ImportDeclaration[] {
\r
33 new ImportDeclaration("Builtin", ""),
\r
36 public final Bundle bundle;
\r
37 public final URL url;
\r
39 private byte[] digest;
\r
40 private ArrayList<UpdateListener> listeners;
\r
42 public BundleModuleSource(String moduleName, Bundle bundle, URL url) {
\r
44 this.bundle = bundle;
\r
49 protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
\r
50 if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
\r
51 return DEFAULT_IMPORTS_FOR_STANDARD_LIBRARY;
\r
53 return DEFAULT_IMPORTS;
\r
56 private byte[] computeDigest() {
\r
58 InputStream stream = url.openStream();
\r
60 MessageDigest digest = MessageDigest.getInstance("SHA1");
\r
61 byte[] buffer = new byte[1024];
\r
63 int count = stream.read(buffer);
\r
66 digest.update(buffer, 0, count);
\r
68 return digest.digest();
\r
69 } catch (NoSuchAlgorithmException e) {
\r
70 e.printStackTrace();
\r
75 } catch(IOException e) {
\r
76 e.printStackTrace();
\r
82 protected InputStream getSourceStream(UpdateListener listener)
\r
83 throws IOException {
\r
85 digest = computeDigest();
\r
86 if(listener != null) {
\r
87 if(listeners == null)
\r
88 listeners = new ArrayList<UpdateListener>(2);
\r
89 listeners.add(listener);
\r
91 return url.openStream();
\r
95 public ClassLoader getClassLoader() {
\r
96 if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
\r
97 return Type.class.getClassLoader();
\r
99 BundleWiring wiring = bundle.adapt(BundleWiring.class);
\r
101 return wiring.getClassLoader();
\r
103 return getClass().getClassLoader();
\r
107 public void checkUpdates() {
\r
108 if(digest != null && listeners != null) {
\r
109 byte[] newDigest = computeDigest();
\r
110 if(!Arrays.equals(digest, newDigest)) {
\r
111 digest = newDigest;
\r
112 ArrayList<UpdateListener> oldListeners = listeners;
\r
114 for(UpdateListener listener : oldListeners)
\r
115 listener.notifyAboutUpdate();
\r
120 private Path getPath() throws IOException {
\r
122 return Paths.get(FileLocator.toFileURL(url).toURI());
\r
123 } catch (URISyntaxException e) {
\r
124 throw new IOException(e);
\r
129 public boolean isUpdateable() {
\r
131 return Files.exists(getPath());
\r
132 } catch (IOException e) {
\r
138 public void update(String newSourceText) {
\r
140 Path path = getPath();
\r
141 Files.write(path, newSourceText.getBytes(Charset.forName("UTF-8")));
\r
142 } catch(IOException e) {
\r
143 e.printStackTrace();
\r
148 public void clear() {
\r
149 if (listeners != null) {
\r