summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java136
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleActivator.java152
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionScanner.java222
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java75
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java117
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java73
6 files changed, 775 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java
new file mode 100644
index 0000000000..3f82f6fb17
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/BundleReference.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+/**
+ * A reference to an OSGi bundle
+ *
+ * @version $Rev$ $Date$
+ */
+public class BundleReference {
+
+ /**
+ * The bundle.
+ */
+ private Bundle bundle;
+
+ /**
+ * The bundle version.
+ */
+ private String version;
+
+ /**
+ * The bundle name and version.
+ */
+ private String symbolicName;
+
+ /**
+ * Constructs a new BundleReference.
+ *
+ * @param bundle
+ */
+ public BundleReference(Bundle bundle) {
+ this.bundle = bundle;
+ this.symbolicName = bundle.getSymbolicName();
+ this.version = (String)bundle.getHeaders().get(Constants.BUNDLE_VERSION);
+ }
+
+ /**
+ * Constructs a new BundleReference.
+ *
+ * @param bundleSymbolicName The bundle symbolic name
+ * @param bundleVersion The bundle version
+ */
+ public BundleReference(String bundleSymbolicName, String bundleVersion) {
+ this.version = bundleVersion;
+ this.symbolicName = bundleSymbolicName;
+ }
+
+ /**
+ * Get the referenced bundle.
+ *
+ * @return The referenced bundle
+ */
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+ /**
+ * Get the referenced bundle version.
+ *
+ * @return The bundle version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Get the referenced bundle name and version.
+ *
+ * @return The bundle name
+ */
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ /**
+ * Returns true if the bundle reference is unresolved.
+ *
+ * @return Whether or not the bundle has been resolved
+ */
+ public boolean isUnresolved() {
+ return bundle == null;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((symbolicName == null) ? 0 : symbolicName.hashCode());
+ result = prime * result + ((version == null) ? 0 : version.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BundleReference other = (BundleReference)obj;
+ if (symbolicName == null) {
+ if (other.symbolicName != null)
+ return false;
+ } else if (!symbolicName.equals(other.symbolicName))
+ return false;
+ if (version == null) {
+ if (other.version != null)
+ return false;
+ } else if (!version.equals(other.version))
+ return false;
+ return true;
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleActivator.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleActivator.java
new file mode 100644
index 0000000000..af13d2ee98
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleActivator.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+
+/**
+ * The Bundle Activator that receives the BundleContext
+ */
+public class OSGiBundleActivator implements BundleActivator {
+ private static BundleContext bundleContext;
+
+ public static BundleContext getBundleContext() {
+ return bundleContext;
+ }
+
+ public void start(BundleContext context) throws Exception {
+ bundleContext = context;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ bundleContext = null;
+ }
+
+ public static Bundle findBundle(URL bundleURL) {
+ if (bundleContext == null) {
+ return null;
+ }
+ Bundle[] installedBundles = bundleContext.getBundles();
+ for (Bundle bundle : installedBundles) {
+ URL root = bundle.getEntry("/");
+ if (root != null && root.getHost() != null && root.getHost().equals(bundleURL.getHost())) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ public static Bundle findBundle(String symbolicName, String version) {
+ if (bundleContext == null) {
+ return null;
+ }
+ Bundle[] bundles = bundleContext.getBundles();
+ if (version == null) {
+ version = "0.0.0";
+ }
+ for (Bundle b : bundles) {
+ String v = (String)b.getHeaders().get(Constants.BUNDLE_VERSION);
+ if (v == null) {
+ v = "0.0.0";
+ }
+ if (b.getSymbolicName().equals(symbolicName) && (version.equals("0.0.0") || v.equals(version))) {
+ return b;
+ }
+ }
+ return null;
+ }
+
+ public static Bundle installBundle(String location, InputStream is) throws BundleException {
+ getBundleContext();
+ return bundleContext.installBundle(location, is);
+ }
+
+ public static Bundle installBundle(String location) throws BundleException, IOException {
+ getBundleContext();
+
+ URL url = new URL(location);
+ Bundle bundle = null;
+ InputStream is = url.openStream();
+ JarInputStream jar = new JarInputStream(is);
+
+ Manifest manifest = jar.getManifest();
+ jar.close();
+ if (manifest != null) {
+ String symbolicName = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+ String version = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+ if (symbolicName != null) {
+ bundle = findBundle(symbolicName, version);
+ if (bundle != null) {
+ return bundle;
+ }
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ try {
+ is = url.openStream();
+ bundle = bundleContext.installBundle(location, is);
+ } finally {
+ is.close();
+ }
+ return bundle;
+ }
+
+ public static Bundle findBundleByLocation(String bundleLocation) {
+ if (bundleContext != null) {
+ Bundle[] installedBundles = bundleContext.getBundles();
+ for (Bundle bundle : installedBundles) {
+ if (bundle.getLocation().equals(bundleLocation))
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ public static Bundle findBundle(String bundleLocation) {
+ if (bundleContext != null) {
+ if (bundleLocation.startsWith("bundle:") || bundleLocation.startsWith("bundleresource:")
+ || bundleLocation.startsWith("bundleentry:")) {
+ try {
+ return findBundle(new URL(bundleLocation));
+ } catch (MalformedURLException e) {
+ // ignore
+ }
+ } else {
+ return findBundleByLocation(bundleLocation);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionScanner.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionScanner.java
new file mode 100644
index 0000000000..111f1f370c
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleContributionScanner.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.PackageType;
+import org.apache.tuscany.sca.contribution.processor.ContributionException;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.scanner.ContributionScanner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+
+/**
+ * Bundle Contribution package processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OSGiBundleContributionScanner implements ContributionScanner {
+ private ContributionFactory contributionFactory;
+
+ public OSGiBundleContributionScanner(ContributionFactory contributionFactory) {
+ this.contributionFactory = contributionFactory;
+ }
+
+ public String getContributionType() {
+ return PackageType.BUNDLE;
+ }
+
+ public List<Artifact> scan(Contribution contribution) throws ContributionReadException {
+ Bundle bundle = OSGiBundleActivator.findBundle(contribution.getLocation());
+
+ if (bundle == null) {
+ throw new IllegalArgumentException("Could not find OSGi bundle " + contribution.getLocation());
+ }
+
+ List<Artifact> artifacts = new ArrayList<Artifact>();
+ Set<String> bundleClassPath = new HashSet<String>();
+ String cp = (String)bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
+ if (cp != null) {
+ String[] paths = cp.split(",");
+ for (String path : paths) {
+ bundleClassPath.add(path.trim());
+ }
+ }
+
+ try {
+ // Test if the bundle is an Eclipse project
+ boolean devMode = (bundle.getEntry("/.project") != null);
+ // FIXME: The entries can come from fragments. Do we need to have a way to differentiate the entries?
+ Enumeration<?> entries = bundle.findEntries("/", "*", true);
+ while (entries.hasMoreElements()) {
+ URL entry = (URL)entries.nextElement();
+ String entryName = entry.getPath();
+ if (devMode && entryName.contains("/.svn/")
+ || entryName.startsWith("/.")
+ || entryName.startsWith("/target/")
+ || entryName.startsWith("/src/")) {
+ // Ignore .svn files
+ // Ignore .classpath, .project, src, and target
+ continue;
+ }
+ if (entryName.startsWith("/")) {
+ entryName = entryName.substring(1);
+ }
+
+ //Add artifact to list
+ Artifact artifact = contributionFactory.createArtifact();
+ artifact.setURI(entryName);
+ artifact.setLocation(entry.toString());
+
+ artifacts.add(artifact);
+
+ //if Artifact is a JAR, add jar artifacts as well
+ /*
+ if (entryName.endsWith(".jar") && bundleClassPath.contains(entryName)) {
+ List<String> jarArtifactURIs = getJarArtifacts(entry, entry.openStream());
+ for( String uri : jarArtifactURIs) {
+ Artifact jarArtifact = contributionFactory.createArtifact();
+ jarArtifact.setURI(uri);
+ URL url = bundle.getResource(uri);
+ String location = null;
+ if(url!=null) {
+ location = url.toString();
+ }
+ jarArtifact.setLocation(location);
+ artifacts.add(jarArtifact);
+
+ }
+ }
+ */
+
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ contribution.getExtensions().add(bundle);
+ contribution.getTypes().add(getContributionType());
+ contribution.setClassLoader(new BundleClassLoader(bundle));
+ return artifacts;
+ }
+
+ /**
+ * Retrieve a list of Artifact URIs for a given JAR
+ * @param packageSourceURL
+ * @param inputStream
+ * @return
+ * @throws ContributionException
+ * @throws IOException
+ */
+ private List<String> getJarArtifacts(URL packageSourceURL, InputStream inputStream) throws ContributionException, IOException {
+ if (packageSourceURL == null) {
+ throw new IllegalArgumentException("Invalid null package source URL.");
+ }
+
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Invalid null source inputstream.");
+ }
+
+ // Assume the root is a jar file
+ JarInputStream jar = new JarInputStream(inputStream);
+ try {
+ Set<String> names = new HashSet<String>();
+ while (true) {
+ JarEntry entry = jar.getNextJarEntry();
+ if (entry == null) {
+ // EOF
+ break;
+ }
+
+ // FIXME: Maybe we should externalize the filter as a property
+ String name = entry.getName();
+ if (!name.startsWith(".") && !entry.isDirectory()) {
+
+ // Trim trailing /
+ if (name.endsWith("/")) {
+ name = name.substring(0, name.length() - 1);
+ }
+
+ // Add the entry name
+ if (!names.contains(name) && name.length() > 0) {
+ names.add(name);
+
+ }
+ }
+ }
+
+ // Return list of URIs
+ List<String> artifacts = new ArrayList<String>();
+ for (String name : names) {
+ artifacts.add(name);
+ }
+ return artifacts;
+
+ } finally {
+ jar.close();
+ }
+ }
+
+
+
+ private static class BundleClassLoader extends ClassLoader {
+ private Bundle bundle;
+ public BundleClassLoader(Bundle bundle) {
+ super(null);
+ this.bundle = bundle;
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ return bundle.loadClass(name);
+ }
+
+ @Override
+ protected URL findResource(String name) {
+ return bundle.getResource(name);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Enumeration<URL> findResources(String name) throws IOException {
+ Enumeration<URL> urls = bundle.getResources(name);
+ if (urls == null) {
+ List<URL> list = Collections.emptyList();
+ return Collections.enumeration(list);
+ } else {
+ return urls;
+ }
+ }
+ }
+
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java
new file mode 100644
index 0000000000..0b0d49de3e
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleProcessor.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi.impl;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.osgi.BundleReference;
+import org.osgi.framework.Bundle;
+
+/**
+ * OSGi bundle processor
+ *
+ * @version $Rev$ $Date$
+ */
+public class OSGiBundleProcessor {
+
+ // private boolean initializedOSGi;
+ // private OSGiRuntime osgiRuntime;
+
+ public OSGiBundleProcessor() {
+ }
+
+ public Object installContributionBundle(Contribution contribution) {
+
+ Object bundle = null;
+ try {
+ bundle = OSGiBundleActivator.installBundle(contribution.getLocation());
+ } catch (Exception e) {
+ // If OSGi cannot process the jar, treat the bundle as a plain jar file.
+ }
+ return bundle;
+ }
+
+ public BundleReference installNestedBundle(Contribution contribution,
+ String bundleSymbolicName,
+ String bundleVersion) {
+
+ BundleReference bundleReference = null;
+
+ List<Artifact> artifacts = contribution.getArtifacts();
+ for (Artifact a : artifacts) {
+ if (a.getURI().endsWith(".jar")) {
+ try {
+ Bundle bundle = OSGiBundleActivator.installBundle(a.getLocation());
+ if (bundle != null) {
+ bundleReference = new BundleReference(bundle);
+ break;
+ }
+ } catch (Exception e) {
+ // If OSGi cannot process the jar, treat the bundle as a plain jar file.
+ }
+ }
+ }
+ return bundleReference;
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java
new file mode 100644
index 0000000000..7958eb4b6d
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiBundleReferenceModelResolver.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.osgi.BundleReference;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.osgi.framework.Bundle;
+
+/**
+ * A Model Resolver for BundleReferences.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OSGiBundleReferenceModelResolver implements ModelResolver {
+ private Contribution contribution;
+ private Map<BundleReference, BundleReference> refs = new HashMap<BundleReference, BundleReference>();
+
+ private OSGiBundleProcessor bundleProcessor;
+
+ public OSGiBundleReferenceModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ this.contribution = contribution;
+ this.bundleProcessor = new OSGiBundleProcessor();
+ }
+
+ public void addModel(Object resolved, ProcessorContext context) {
+ BundleReference bundleRef = (BundleReference)resolved;
+ refs.put(bundleRef, bundleRef);
+ }
+
+ public Object removeModel(Object resolved, ProcessorContext context) {
+ return refs.remove(resolved);
+ }
+
+ /**
+ * Handle artifact resolution when the specific class reference is imported from another contribution
+ * @param unresolved
+ * @param context
+ * @return
+ */
+ private BundleReference resolveImportedModel(BundleReference unresolved, ProcessorContext context) {
+ BundleReference resolved = unresolved;
+
+ if (this.contribution != null) {
+ for (Import import_ : this.contribution.getImports()) {
+
+ resolved = import_.getModelResolver().resolveModel(BundleReference.class, unresolved, context);
+ if (resolved != unresolved)
+ break;
+ }
+
+ }
+ return resolved;
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved, ProcessorContext context) {
+ Object resolved = refs.get(unresolved);
+
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+
+ if (OSGiBundleActivator.getBundleContext() == null)
+ return unresolved;
+
+ //Load a class on demand
+ Bundle bundle = null;
+ String bundleName = ((BundleReference)unresolved).getSymbolicName();
+ String bundleVersion = ((BundleReference)unresolved).getVersion();
+
+ bundle = OSGiBundleActivator.findBundle(bundleName, bundleVersion);
+ BundleReference bundleReference;
+
+ if (bundle == null) {
+ bundleReference = bundleProcessor.installNestedBundle(contribution, bundleName, bundleVersion);
+ } else {
+ bundleReference = new BundleReference(bundle);
+ }
+
+ if (bundleReference != null) {
+ //if we load the class
+
+ refs.put(((BundleReference)unresolved), bundleReference);
+
+ // Return the resolved BundleReference
+ return modelClass.cast(bundleReference);
+ } else {
+ //delegate resolution of the class
+ resolved = this.resolveImportedModel((BundleReference)unresolved, context);
+ return modelClass.cast(resolved);
+ }
+
+ }
+}
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java
new file mode 100644
index 0000000000..3963968940
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/contribution-osgi/src/main/java/org/apache/tuscany/sca/contribution/osgi/impl/OSGiClassReferenceModelResolver.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.osgi.impl;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.osgi.framework.Bundle;
+
+/**
+ * A Model Resolver for ClassReferences.
+ *
+ * @version $Rev$ $Date$
+ */
+public class OSGiClassReferenceModelResolver implements ModelResolver {
+ // private Contribution contribution;
+ private Bundle bundle;
+
+ public OSGiClassReferenceModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ // this.contribution = contribution;
+ this.bundle = OSGiBundleActivator.findBundle(contribution.getLocation());
+ }
+
+ public void addModel(Object resolved, ProcessorContext context) {
+ }
+
+ public Object removeModel(Object resolved, ProcessorContext context) {
+ return resolved;
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved, ProcessorContext context) {
+ //Load a class on demand
+ Class<?> clazz = null;
+ if (bundle != null) {
+ try {
+ clazz = bundle.loadClass(((ClassReference)unresolved).getClassName());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+
+ if (clazz != null) {
+ //if we load the class
+ // Store a new ClassReference wrapping the loaded class
+ ClassReference classReference = new ClassReference(clazz);
+
+ // Return the resolved ClassReference
+ return modelClass.cast(classReference);
+ } else {
+ return unresolved;
+ }
+
+ }
+}