Further patches related to FELIX-1324 - now abstracts uri scheme behind a resolver that allows for substitution of "real" urls for meta stubs:
start:sigil:<bsn>:version
for example
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@831004 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sigil/common/runtime/sigil.properties b/sigil/common/runtime/sigil.properties
index 23156cc..e2144c0 100644
--- a/sigil/common/runtime/sigil.properties
+++ b/sigil/common/runtime/sigil.properties
@@ -12,7 +12,7 @@
org.apache.felix.sigil.common.runtime, \
-imports: \
- org.apache.felix.sigil.common.runtime,\
+ org.apache.felix.sigil.common.runtime, \
org.osgi.framework, \
org.osgi.framework.launch, \
org.osgi.service.packageadmin, \
diff --git a/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/BundleForm.java b/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/BundleForm.java
index 57c1ed7..6aa0a48 100644
--- a/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/BundleForm.java
+++ b/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/BundleForm.java
@@ -19,6 +19,7 @@
package org.apache.felix.sigil.common.runtime;
import java.io.BufferedReader;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -38,6 +39,30 @@
public class BundleForm
{
+ public interface Resolver {
+ URI[] resolve(URI base) throws URISyntaxException;
+ }
+
+ public interface ResolutionContext {
+ Resolver findResolver(URI uri);
+ }
+
+ private static final Resolver NULL_RESOLVER = new Resolver() {
+
+ public URI[] resolve(URI base)
+ {
+ return new URI[] { base };
+ }
+
+ };
+ private static final ResolutionContext NULL_CONTEXT = new ResolutionContext()
+ {
+ public Resolver findResolver(URI uri)
+ {
+ return NULL_RESOLVER;
+ }
+ };
+
public static class BundleStatus
{
private String location;
@@ -101,29 +126,83 @@
}
}
- private String[] bundles;
- private Set<String> startMap = new HashSet<String>();
+ private URI[] bundles;
+ private Set<URI> startMap = new HashSet<URI>();
public BundleForm() {
}
- public static BundleForm resolve(URL formURL) throws IOException, URISyntaxException {
+ public BundleStatus[] resolve(ResolutionContext ctx) throws IOException, URISyntaxException {
+ if ( ctx == null ) {
+ ctx = NULL_CONTEXT;
+ }
+
+ ArrayList<BundleStatus> ret = new ArrayList<BundleStatus>(bundles.length);
+
+ for ( int i = 0; i < bundles.length; i++ ) {
+ Resolver resolver = ctx.findResolver(bundles[i]);
+ if ( resolver == null ) {
+ resolver = NULL_RESOLVER;
+ }
+ URI[] resolved = resolver.resolve(bundles[i]);
+ for ( URI uri : resolved ) {
+ ret.add( toBundle(uri, isStarted(bundles[i])) );
+ }
+ }
+
+ return ret.toArray(new BundleStatus[ret.size()] );
+
+ }
+
+ private BundleStatus toBundle(URI uri, boolean started) throws IOException
+ {
+ URL url = uri.toURL();
+ InputStream in = url.openStream();
+ try {
+ JarInputStream jin = new JarInputStream(in);
+ Manifest mf = jin.getManifest();
+ Attributes attr = mf.getMainAttributes();
+ String bsn = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
+ String ver = attr.getValue(Constants.BUNDLE_VERSION);
+ BundleStatus st = new BundleStatus();
+ st.setBundleSymbolicName(bsn);
+ st.setVersion(ver);
+ st.setLocation(url.toExternalForm());
+ st.setStatus(started ? Bundle.ACTIVE : Bundle.INSTALLED);
+ return st;
+ }
+ finally {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static BundleForm create(URL formURL) throws IOException, URISyntaxException {
InputStream in = formURL.openStream();
try {
BundleForm f = new BundleForm();
BufferedReader r = new BufferedReader(new InputStreamReader(in));
- LinkedList<String> locs = new LinkedList<String>();
+ LinkedList<URI> locs = new LinkedList<URI>();
for(;;) {
String l = r.readLine();
if ( l == null ) break;
- URI uri = URI.create(l);
- String status = uri.getScheme();
- uri = URI.create(uri.getSchemeSpecificPart());
- String loc = uri.toString();
- locs.add( loc );
- f.setStarted(loc, "start".equalsIgnoreCase(status) );
+ l = l.trim();
+ if ( !l.startsWith( "#" ) ) {
+ URI uri = URI.create(l);
+ String status = uri.getScheme();
+ uri = URI.create(uri.getSchemeSpecificPart());
+ locs.add( uri );
+ f.setStarted(uri, "start".equalsIgnoreCase(status) );
+ }
}
- f.setBundles(locs.toArray(new String[locs.size()]));
+ f.setBundles(locs.toArray(new URI[locs.size()]));
return f;
}
finally {
@@ -139,59 +218,26 @@
}
}
- public void setBundles(String[] bundles) {
+ public void setBundles(URI[] bundles) {
this.bundles = bundles;
}
- public String[] getBundles()
+ public URI[] getBundles()
{
return bundles;
}
- public boolean isStarted(String url)
+ public boolean isStarted(URI uri)
{
- return startMap.contains(url);
+ return startMap.contains(uri);
}
- public void setStarted(String url, boolean started) {
+ public void setStarted(URI uri, boolean started) {
if ( started ) {
- startMap.add(url);
+ startMap.add(uri);
}
else {
- startMap.remove(url);
+ startMap.remove(uri);
}
- }
-
- public BundleStatus[] toStatus() throws IOException {
- ArrayList<BundleStatus> ret = new ArrayList<BundleStatus>(bundles.length);
- for ( String loc : bundles ) {
- URL url = new URL(loc);
- InputStream in = url.openStream();
- try {
- JarInputStream jin = new JarInputStream(in);
- Manifest mf = jin.getManifest();
- Attributes attr = mf.getMainAttributes();
- String bsn = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
- String ver = attr.getValue(Constants.BUNDLE_VERSION);
- BundleStatus st = new BundleStatus();
- st.setBundleSymbolicName(bsn);
- st.setVersion(ver);
- st.setLocation(loc);
- st.setStatus(isStarted(loc) ? Bundle.ACTIVE : Bundle.INSTALLED);
- ret.add(st);
- }
- finally {
- try
- {
- in.close();
- }
- catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- return ret.toArray(new BundleStatus[ret.size()] );
- }
+ }
}
diff --git a/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java b/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java
index 807b783..8f9daa3 100644
--- a/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java
+++ b/sigil/common/runtime/src/org/apache/felix/sigil/common/runtime/Client.java
@@ -92,9 +92,7 @@
out = null;
}
- public void apply(BundleForm form) throws IOException, BundleException {
- BundleStatus[] newStatus = form.toStatus();
-
+ public void apply(BundleForm.BundleStatus[] newStatus) throws IOException, BundleException {
BundleStatus[] currentStatus = status();
stopOldBundles(currentStatus, newStatus);
diff --git a/sigil/eclipse/runtime/sigil.properties b/sigil/eclipse/runtime/sigil.properties
index 714009d..9d2d8c2 100644
--- a/sigil/eclipse/runtime/sigil.properties
+++ b/sigil/eclipse/runtime/sigil.properties
@@ -7,17 +7,22 @@
org.apache.felix.sigil.eclipse.runtime, \
-resources: \
- icons=icons, \
+ icons, \
plugin.xml, \
-sourcedirs: \
src, \
-imports: \
+ org.apache.felix.sigil.common.osgi;version=0.9.0, \
org.apache.felix.sigil.common.runtime, \
org.apache.felix.sigil.eclipse, \
org.apache.felix.sigil.eclipse.install, \
org.apache.felix.sigil.eclipse.model.project;version=0.9.0, \
+ org.apache.felix.sigil.model;version=0.9.0, \
+ org.apache.felix.sigil.model.eclipse;version=0.9.0, \
+ org.apache.felix.sigil.model.osgi;version=0.9.0, \
+ org.apache.felix.sigil.repository;version=0.9.0, \
org.apache.felix.sigil.ui.eclipse.ui, \
org.apache.felix.sigil.ui.eclipse.ui.util, \
org.eclipse.core.commands.common;resolve=compile, \
diff --git a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/LaunchHelper.java b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/LaunchHelper.java
index a02902c..7250bba 100644
--- a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/LaunchHelper.java
+++ b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/LaunchHelper.java
@@ -19,10 +19,19 @@
package org.apache.felix.sigil.eclipse.runtime;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.Properties;
+import org.apache.felix.sigil.common.runtime.BundleForm;
import org.apache.felix.sigil.common.runtime.Runtime;
+import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.install.IOSGiInstall;
+import org.apache.felix.sigil.eclipse.runtime.config.OSGiLaunchConfigurationConstants;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
public class LaunchHelper {
@@ -53,4 +62,45 @@
{
return 1000;
}
+
+ public static URL toURL(String loc) throws MalformedURLException
+ {
+ URL url = null;
+ try
+ {
+ url = new URL(loc);
+ }
+ catch (MalformedURLException e)
+ {
+ IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(loc));
+ if ( f.exists() ) {
+ url = f.getLocation().toFile().toURL();
+ }
+ else {
+ throw new MalformedURLException("Unknown file " + loc );
+ }
+ }
+ return url;
+ }
+
+ public static BundleForm getBundleForm(ILaunchConfiguration config) throws CoreException
+ {
+ String loc = config.getAttribute(OSGiLaunchConfigurationConstants.FORM_FILE_LOCATION, (String) null);
+ try
+ {
+ URL url = toURL(loc);
+ SigilCore.log("Resolving " + url);
+ return BundleForm.create(url);
+ }
+ catch (Exception e)
+ {
+ throw SigilCore.newCoreException("Failed to parse bundle form file", e);
+ }
+ }
+
+ public static String getRepositoryManagerName(ILaunchConfiguration config)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
diff --git a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/OSGiLauncher.java b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/OSGiLauncher.java
index aa38e60..cab1f2f 100644
--- a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/OSGiLauncher.java
+++ b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/OSGiLauncher.java
@@ -21,6 +21,7 @@
import java.io.IOException;
+
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -31,7 +32,7 @@
import org.apache.felix.sigil.common.runtime.Main;
import org.apache.felix.sigil.eclipse.SigilCore;
import org.apache.felix.sigil.eclipse.install.IOSGiInstall;
-import org.apache.felix.sigil.eclipse.runtime.config.OSGiLaunchConfigurationHelper;
+import org.apache.felix.sigil.repository.IRepositoryManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -43,7 +44,6 @@
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
-import org.osgi.framework.BundleException;
public class OSGiLauncher extends AbstractJavaLaunchConfigurationDelegate implements ILaunchConfigurationDelegate,
@@ -85,11 +85,13 @@
Client client = connect( config );
- BundleForm form = OSGiLaunchConfigurationHelper.getBundleForm(config);
+ BundleForm form = LaunchHelper.getBundleForm(config);
try
{
- client.apply(form);
+ String name = LaunchHelper.getRepositoryManagerName(config);
+ IRepositoryManager manager = SigilCore.getRepositoryManager(name);
+ client.apply(form.resolve(new RuntimeBundleResolver(manager)));
}
catch (Exception e)
{
diff --git a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/RuntimeBundleResolver.java b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/RuntimeBundleResolver.java
new file mode 100644
index 0000000..8c4416d
--- /dev/null
+++ b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/RuntimeBundleResolver.java
@@ -0,0 +1,98 @@
+package org.apache.felix.sigil.eclipse.runtime;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import org.apache.felix.sigil.common.osgi.VersionRange;
+import org.apache.felix.sigil.common.runtime.BundleForm.ResolutionContext;
+import org.apache.felix.sigil.common.runtime.BundleForm.Resolver;
+import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.model.project.ISigilProjectModel;
+import org.apache.felix.sigil.model.ModelElementFactory;
+import org.apache.felix.sigil.model.eclipse.ISigilBundle;
+import org.apache.felix.sigil.model.osgi.IRequiredBundle;
+import org.apache.felix.sigil.repository.IBundleResolver;
+import org.apache.felix.sigil.repository.IRepositoryManager;
+import org.apache.felix.sigil.repository.IResolution;
+import org.apache.felix.sigil.repository.ResolutionConfig;
+import org.apache.felix.sigil.repository.ResolutionException;
+import org.eclipse.core.runtime.CoreException;
+import org.osgi.framework.Version;
+
+public class RuntimeBundleResolver implements ResolutionContext
+{
+
+ public class SigilBundleResolver implements Resolver
+ {
+ public URI[] resolve(URI base) throws URISyntaxException
+ {
+ ArrayList<URI> uris = new ArrayList<URI>(1);
+
+ IBundleResolver resolver = manager.getBundleResolver();
+ IRequiredBundle element = ModelElementFactory.getInstance().newModelElement(IRequiredBundle.class);
+ String[] parts = base.getSchemeSpecificPart().split(":");
+ switch( parts.length ) {
+ case 2:
+ Version v = Version.parseVersion(parts[1]);
+ element.setVersions(new VersionRange(false, v, v, false));
+ // fall through on purpose
+ case 1:
+ element.setSymbolicName(parts[0]);
+ break;
+ default:
+ throw new URISyntaxException(base.toString(), "Unexpected number of parts: " + parts.length);
+ }
+ try
+ {
+ ResolutionConfig config = new ResolutionConfig(ResolutionConfig.IGNORE_ERRORS);
+ IResolution resolution = resolver.resolve(element, config, null);
+ if ( resolution.getBundles().isEmpty() ) {
+ SigilCore.error( "Failed to resolve bundle for " + base );
+ }
+ for ( ISigilBundle b : resolution.getBundles() ) {
+ ISigilProjectModel p = b.getAncestor(ISigilProjectModel.class);
+ if ( p != null ) {
+ uris.add(p.findBundleLocation().toFile().toURI());
+ }
+ else {
+ b.synchronize(null);
+ uris.add( b.getLocation().toFile().toURI() );
+ }
+ }
+ }
+ catch (ResolutionException e)
+ {
+ SigilCore.error("Failed to resolve " + base, e);
+ }
+ catch (IOException e)
+ {
+ SigilCore.error("Failed to synchronize " + base, e);
+ }
+ catch (CoreException e)
+ {
+ SigilCore.error("Failed to access " + base, e);
+ }
+ SigilCore.log( "Resolved " + uris );
+ return uris.toArray(new URI[uris.size()]);
+ }
+ }
+
+ private final IRepositoryManager manager;
+
+ public RuntimeBundleResolver(IRepositoryManager manager) {
+ this.manager = manager;
+ }
+
+ public Resolver findResolver(URI uri)
+ {
+ SigilCore.log( "Finding resolver for " + uri.getScheme() );
+ if ( "sigil".equals( uri.getScheme() ) ) {
+ SigilCore.log( "Found resolver for " + uri.getScheme() );
+ return new SigilBundleResolver();
+ }
+ return null;
+ }
+
+}
diff --git a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationHelper.java b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationHelper.java
deleted file mode 100644
index 8eb658e..0000000
--- a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationHelper.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.apache.felix.sigil.eclipse.runtime.config;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-import org.apache.felix.sigil.common.runtime.BundleForm;
-import org.apache.felix.sigil.eclipse.SigilCore;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.debug.core.ILaunchConfiguration;
-
-public class OSGiLaunchConfigurationHelper
-{
-
- public static URL toURL(String loc) throws MalformedURLException
- {
- URL url = null;
- try
- {
- url = new URL(loc);
- }
- catch (MalformedURLException e)
- {
- IFile f = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(loc));
- if ( f.exists() ) {
- url = f.getLocation().toFile().toURL();
- }
- else {
- throw new MalformedURLException("Unknown file " + loc );
- }
- }
- return url;
- }
-
- public static BundleForm getBundleForm(ILaunchConfiguration config) throws CoreException
- {
- String loc = config.getAttribute(OSGiLaunchConfigurationConstants.FORM_FILE_LOCATION, (String) null);
- try
- {
- URL url = OSGiLaunchConfigurationHelper.toURL(loc);
- SigilCore.log("Resolving " + url);
- return BundleForm.resolve(url);
- }
- catch (Exception e)
- {
- throw SigilCore.newCoreException("Failed to parse bundle form file", e);
- }
- }
-
-}
diff --git a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationTab.java b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationTab.java
index f44497a..bfc27e8 100644
--- a/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationTab.java
+++ b/sigil/eclipse/runtime/src/org/apache/felix/sigil/eclipse/runtime/config/OSGiLaunchConfigurationTab.java
@@ -24,6 +24,7 @@
import org.apache.felix.sigil.common.runtime.BundleForm;
import org.apache.felix.sigil.eclipse.SigilCore;
+import org.apache.felix.sigil.eclipse.runtime.LaunchHelper;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
@@ -110,9 +111,9 @@
if ( loc.trim().length() > 0 ) {
try
{
- URL url = OSGiLaunchConfigurationHelper.toURL(loc);
+ URL url = LaunchHelper.toURL(loc);
SigilCore.log("Resolving " + url);
- BundleForm.resolve(url);
+ BundleForm.create(url);
setErrorMessage(null);
setDirty(true);
}