1 package org.simantics.scl.osgi.internal;
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.net.URISyntaxException;
7 import java.nio.charset.Charset;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10 import java.nio.file.Paths;
11 import java.security.MessageDigest;
12 import java.security.NoSuchAlgorithmException;
13 import java.util.ArrayList;
14 import java.util.Arrays;
16 import org.eclipse.core.runtime.FileLocator;
17 import org.osgi.framework.Bundle;
18 import org.osgi.framework.wiring.BundleWiring;
19 import org.simantics.scl.compiler.module.ImportDeclaration;
20 import org.simantics.scl.compiler.module.repository.UpdateListener;
21 import org.simantics.scl.compiler.source.EncodedTextualModuleSource;
22 import org.simantics.scl.compiler.types.Type;
24 public class BundleModuleSource extends EncodedTextualModuleSource {
26 public static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
27 new ImportDeclaration("Builtin", ""),
28 new ImportDeclaration("StandardLibrary", "")
31 public static final ImportDeclaration[] DEFAULT_IMPORTS_FOR_STANDARD_LIBRARY = new ImportDeclaration[] {
32 new ImportDeclaration("Builtin", ""),
35 public final Bundle bundle;
38 private byte[] digest;
39 private ArrayList<UpdateListener> listeners;
41 public BundleModuleSource(String moduleName, Bundle bundle, URL url) {
48 protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
49 if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
50 return DEFAULT_IMPORTS_FOR_STANDARD_LIBRARY;
52 return DEFAULT_IMPORTS;
55 private byte[] computeDigest() {
57 InputStream stream = url.openStream();
59 MessageDigest digest = MessageDigest.getInstance("SHA1");
60 byte[] buffer = new byte[1024];
62 int count = stream.read(buffer);
65 digest.update(buffer, 0, count);
67 return digest.digest();
68 } catch (NoSuchAlgorithmException e) {
74 } catch(IOException e) {
81 protected InputStream getSourceStream(UpdateListener listener)
84 digest = computeDigest();
85 if(listener != null) {
87 listeners = new ArrayList<UpdateListener>(2);
88 listeners.add(listener);
90 return url.openStream();
94 public ClassLoader getClassLoader() {
95 if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
96 return Type.class.getClassLoader();
98 BundleWiring wiring = bundle.adapt(BundleWiring.class);
100 return wiring.getClassLoader();
102 return getClass().getClassLoader();
106 public void checkUpdates() {
107 if(digest != null && listeners != null) {
108 byte[] newDigest = computeDigest();
109 if(!Arrays.equals(digest, newDigest)) {
111 ArrayList<UpdateListener> oldListeners = listeners;
113 for(UpdateListener listener : oldListeners)
114 listener.notifyAboutUpdate();
119 private Path getPath() throws IOException {
121 return Paths.get(FileLocator.toFileURL(url).toURI());
122 } catch (URISyntaxException e) {
123 throw new IOException(e);
128 public boolean isUpdateable() {
130 return Files.exists(getPath());
131 } catch (IOException e) {
137 public void update(String newSourceText) {
139 Path path = getPath();
140 Files.write(path, newSourceText.getBytes(Charset.forName("UTF-8")));
141 } catch(IOException e) {
147 public void clear() {
148 if (listeners != null) {