package org.simantics.scl.osgi.internal;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.core.runtime.FileLocator;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.source.EncodedTextualModuleSource;
import org.simantics.scl.compiler.types.Type;
-public class BundleModuleSource extends EncodedTextualModuleSource {
+import gnu.trove.set.hash.THashSet;
+
+public class BundleModuleSource extends EncodedTextualModuleSource implements UpdateListener.Observable {
public static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
new ImportDeclaration("Builtin", ""),
public final URL url;
private byte[] digest;
- private ArrayList<UpdateListener> listeners;
+ private THashSet<UpdateListener> listeners;
public BundleModuleSource(String moduleName, Bundle bundle, URL url) {
super(moduleName);
this.bundle = bundle;
this.url = url;
}
+
+ @Override
+ public void removeListener(UpdateListener listener) {
+ if(listeners != null)
+ synchronized(listeners) {
+ listeners.remove(listener);
+ }
+ }
@Override
- protected ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
+ public ImportDeclaration[] getBuiltinImports(UpdateListener listener) {
if(bundle.getSymbolicName().equals("org.simantics.scl.runtime"))
return DEFAULT_IMPORTS_FOR_STANDARD_LIBRARY;
else
digest = computeDigest();
if(listener != null) {
if(listeners == null)
- listeners = new ArrayList<UpdateListener>(2);
+ listeners = new THashSet<UpdateListener>(4);
listeners.add(listener);
+ listener.addObservable(this);
}
return url.openStream();
}
byte[] newDigest = computeDigest();
if(!Arrays.equals(digest, newDigest)) {
digest = newDigest;
- ArrayList<UpdateListener> oldListeners = listeners;
+ THashSet<UpdateListener> oldListeners = listeners;
listeners = null;
for(UpdateListener listener : oldListeners)
listener.notifyAboutUpdate();
}
}
}
-
- private Path getPath() throws IOException {
- try {
- return Paths.get(FileLocator.toFileURL(url).toURI());
- } catch (URISyntaxException e) {
- throw new IOException(e);
+
+ /*
+ * This code is a copy from org.simantics.utils.ui.BundleUtils
+ */
+ public static File resolveWritableBundleFile(URL url) throws IOException {
+ // This returns file, jar, http etc. - essentially resolves the bundle protocol
+ URL resolved = FileLocator.resolve(url);
+ if (resolved.getProtocol().equals("file")) {
+ return new File(resolved.getPath());
}
+ return null;
}
-
+
+ private Path getPath() throws IOException {
+ File file = resolveWritableBundleFile(url);
+ return file != null ? file.toPath() : null;
+ }
+
@Override
public boolean isUpdateable() {
try {
- return Files.exists(getPath());
+ Path path = getPath();
+ if(path == null)
+ return false;
+ return Files.exists(path);
} catch (IOException e) {
return false;
}
public void update(String newSourceText) {
try {
Path path = getPath();
+ if(path == null)
+ return;
Files.write(path, newSourceText.getBytes(Charset.forName("UTF-8")));
} catch(IOException e) {
e.printStackTrace();
}
}
+ public JavaReferenceValidatorFactory getJavaReferenceValidatorFactory() {
+ return new OsgiJavaReferenceValidatorFactory(bundle);
+ }
}