summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-0.99/modules/host-embedded/src/main
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-0.99/modules/host-embedded/src/main
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-0.99/modules/host-embedded/src/main')
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomain.java272
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomainBean.java121
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCATestCaseRunner.java213
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ComponentManagerImpl.java115
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/DefaultSCADomain.java500
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/EmbeddedSCADomain.java204
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/HotUpdatableSCADomain.java391
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntime.java242
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntimeBuilder.java245
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentListener.java29
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentManager.java43
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentInfo.java32
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentListener.java31
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManager.java43
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManagerService.java36
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentInfoImpl.java45
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerImpl.java105
-rw-r--r--branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerServiceImpl.java66
18 files changed, 2733 insertions, 0 deletions
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomain.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomain.java
new file mode 100644
index 0000000000..6954110bc5
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomain.java
@@ -0,0 +1,272 @@
+/*
+ * 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.host.embedded;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.tuscany.sca.host.embedded.impl.DefaultSCADomain;
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * A handle to an SCA domain.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class SCADomain {
+
+ final static String LOCAL_DOMAIN_URI = "http://localhost";
+
+ /**
+ * Static variable to hold the most recent instance of SCADomain
+ */
+ // TODO: Temporary support for SCADomain.connect() API
+ private static SCADomain theDomain;
+
+
+ /**
+ * Returns a new instance of a local SCA domain.
+ *
+ * @return
+ */
+ public static SCADomain newInstance() {
+ return createNewInstance(LOCAL_DOMAIN_URI, null);
+ }
+
+ /**
+ * Returns a new instance of a local SCA domain. The specified deployable
+ * composite will be included in the SCA domain.
+ *
+ * @param composite the deployable composite to include in the SCA domain.
+ * @return
+ */
+ public static SCADomain newInstance(String composite) {
+ return createNewInstance(LOCAL_DOMAIN_URI, "/", composite);
+ }
+
+ /**
+ * Returns a new instance of a local SCA domain. The specified deployable
+ * composites will be included in the SCA domain.
+ *
+ * @param domainURI the URI of the SCA domain
+ * @param contributionLocation the location of an SCA contribution
+ * @param composites the deployable composites to include in the SCA domain.
+ * @return
+ */
+ public static SCADomain newInstance(String domainURI, String contributionLocation, String... composites) {
+ return createNewInstance(domainURI, contributionLocation, composites);
+ }
+
+ /**
+ * Removes the specified local SCA Domain instance
+ *
+ * @param domainInstance the instance to be removed
+ */
+ // FIXME: Adding this as temporary support for the "connect" API
+ public static void removeInstance(SCADomain domainInstance) {
+ theDomain = null;
+ }
+
+ /**
+ * Returns an SCADomain representing a remote SCA domain.
+ *
+ * @param domainURI the URI of the SCA domain
+ * @return
+ */
+ // FIXME : this is a temporary implementation to get the capability working
+ public static SCADomain connect(String domainURI) {
+ return theDomain;
+ }
+
+ /**
+ * Close the SCA domain.
+ */
+ public void close() {
+ // TODO: temporary to support initial SCADomain.connect capability
+ SCADomain.removeInstance(this);
+ }
+
+ /**
+ * Returns the URI of the SCA Domain.
+ *
+ * @return the URI of the SCA Domain
+ */
+ public abstract String getURI();
+
+ /**
+ * Cast a type-safe reference to a CallableReference. Converts a type-safe
+ * reference to an equivalent CallableReference; if the target refers to a
+ * service then a ServiceReference will be returned, if the target refers to
+ * a callback then a CallableReference will be returned.
+ *
+ * @param target a reference proxy provided by the SCA runtime
+ * @param <B> the Java type of the business interface for the reference
+ * @param <R> the type of reference to be returned
+ * @return a CallableReference equivalent for the proxy
+ * @throws IllegalArgumentException if the supplied instance is not a
+ * reference supplied by the SCA runtime
+ */
+ public abstract <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException;
+
+ /**
+ * Returns a proxy for a service provided by a component in the SCA domain.
+ *
+ * @param businessInterface the interface that will be used to invoke the
+ * service
+ * @param serviceName the name of the service
+ * @param <B> the Java type of the business interface for the service
+ * @return an object that implements the business interface
+ */
+ public abstract <B> B getService(Class<B> businessInterface, String serviceName);
+
+ /**
+ * Returns a ServiceReference for a service provided by a component in the
+ * SCA domain.
+ *
+ * @param businessInterface the interface that will be used to invoke the
+ * service
+ * @param serviceName the name of the service
+ * @param <B> the Java type of the business interface for the service
+ * @return a ServiceReference for the designated service
+ */
+ public abstract <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName);
+
+ /**
+ * Read the service name from a configuration file
+ *
+ * @param classLoader
+ * @param name The name of the service class
+ * @return A class name which extends/implements the service class
+ * @throws IOException
+ */
+ private static String getServiceName(ClassLoader classLoader, String name) throws IOException {
+ InputStream is = classLoader.getResourceAsStream("META-INF/services/" + name);
+ if (is == null) {
+ return null;
+ }
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(is));
+ while (true) {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ } else if (!line.startsWith("#")) {
+ return line.trim();
+ }
+ }
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an SCADomain instance. If the system property
+ * "org.apache.tuscany.sca.host.embedded.SCADomain" is set, its value is used as
+ * the name of the implementation class. Otherwise, if the resource
+ * "META-INF/services/org.apache.tuscany.sca.host.embedded.SCADomain" can be
+ * loaded from the supplied classloader. Otherwise, it will use
+ * "org.apache.tuscany.sca.host.embedded.impl.DefaultSCADomain" as the default.
+ * The named class is loaded from the supplied classloader.
+ *
+ * @param classLoader
+ * @param domainURI
+ * @param contributionLocation
+ * @param composites
+ * @return
+ */
+ static SCADomain createNewInstance(String domainURI, String contributionLocation, String... composites) {
+
+ SCADomain domain = null;
+
+ try {
+ // Determine the runtime and application classloader
+ final ClassLoader runtimeClassLoader = SCADomain.class.getClassLoader();
+ final ClassLoader applicationClassLoader = Thread.currentThread().getContextClassLoader();
+
+ // Discover the SCADomain implementation
+ final String name = SCADomain.class.getName();
+ String className = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return System.getProperty(name);
+ }
+ });
+
+ if (className == null) {
+ className = getServiceName(runtimeClassLoader, name);
+ }
+
+ if (className == null) {
+
+ // Create a default SCA domain implementation
+ domain =
+ new DefaultSCADomain(runtimeClassLoader,
+ applicationClassLoader,
+ domainURI,
+ contributionLocation,
+ composites);
+ } else {
+
+ // Create an instance of the discovered SCA domain implementation
+ Class cls = Class.forName(className, true, runtimeClassLoader);
+ Constructor<?> constructor = null;
+ try {
+ constructor = cls.getConstructor(ClassLoader.class, ClassLoader.class,
+ String.class, String.class, String[].class);
+ } catch (NoSuchMethodException e) {}
+ if (constructor != null) {
+ domain = (SCADomain)constructor.newInstance(runtimeClassLoader,
+ applicationClassLoader,
+ domainURI,
+ contributionLocation,
+ composites);
+ } else {
+
+ constructor = cls.getConstructor(ClassLoader.class, String.class);
+ domain = (SCADomain)constructor.newInstance(runtimeClassLoader, domainURI);
+ }
+ }
+
+ // FIXME: temporary support for connect() API
+ theDomain = domain;
+
+ return domain;
+
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public ComponentManager getComponentManager() {
+ return null;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomainBean.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomainBean.java
new file mode 100644
index 0000000000..9ee7c274fd
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCADomainBean.java
@@ -0,0 +1,121 @@
+/*
+ * 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.host.embedded;
+
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ServiceReference;
+
+public class SCADomainBean extends SCADomain {
+
+ private SCADomain instance;
+
+ private String uri = LOCAL_DOMAIN_URI;
+ private String location = "/";
+ private String[] composites;
+
+ /**
+ * Constructs a new SCA domain
+ */
+ public SCADomainBean() {
+ }
+
+ @Override
+ public String getURI() {
+ return uri;
+ }
+
+ public void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ public void setContributionLocation(String contributionLocation) {
+ this.location = contributionLocation;
+ }
+
+ public String getContributionLocation() {
+ return location;
+ }
+
+ public void setDeployableComposite(String composite) {
+ setDeployableComposites(composite);
+ }
+
+ public void setDeployableComposites(String... composites) {
+ this.composites = composites;
+ }
+
+ public String[] getDeployableComposites() {
+ return composites;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ if (instance == null) {
+ instance = SCADomain.createNewInstance(uri, location, composites);
+ }
+ Object result = instance.cast(target);
+ return (R) result;
+ }
+
+ @Override
+ public void close() {
+ if (instance == null) {
+ instance = SCADomain.createNewInstance(uri, location, composites);
+ }
+ instance.close();
+ instance = null;
+ }
+
+ @Override
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+ if (instance == null) {
+ instance = SCADomain.createNewInstance(uri, location, composites);
+ }
+ return instance.getService(businessInterface, serviceName);
+ }
+
+ @Override
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
+ if (instance == null) {
+ instance = SCADomain.createNewInstance(uri, location, composites);
+ }
+ return instance.getServiceReference(businessInterface, referenceName);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+
+ // Make sure that the SCA domain is closed
+ if (instance != null) {
+ instance.close();
+ instance = null;
+ }
+ }
+
+ @Override
+ public ComponentManager getComponentManager() {
+ if (instance == null) {
+ instance = SCADomain.createNewInstance(uri, location, composites);
+ }
+ return instance.getComponentManager();
+ }
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCATestCaseRunner.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCATestCaseRunner.java
new file mode 100644
index 0000000000..3aa334a3d5
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/SCATestCaseRunner.java
@@ -0,0 +1,213 @@
+/*
+ * 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.host.embedded;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * A helper class that can be used to run an SCA JUnit test case. The test case will run in an isolated class loader.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SCATestCaseRunner {
+
+ private ClassLoader classLoader;
+ private Class<?> testSuiteClass;
+ private Object testSuite;
+ private Class<?> testResultClass;
+ private Class<?> testCaseClass;
+ private Object testCase;
+
+ private Class<?> beforeAnnotation;
+ private Class<?> beforeClassAnnotation;
+ private Class<?> afterAnnotation;
+ private Class<?> afterClassAnnotation;
+ private Class<?> junit4AdapterClass;
+ private Class<?> junit3TestCaseClass;
+
+ /**
+ * Constructs a new TestCase runner.
+ *
+ * @param testClass
+ */
+ public SCATestCaseRunner(Class testClass) {
+ try {
+ classLoader = testClass.getClassLoader();
+ if (classLoader instanceof URLClassLoader) {
+ URL[] urls = ((URLClassLoader)classLoader).getURLs();
+ classLoader = new URLClassLoader(urls, classLoader.getParent());
+ } else {
+ classLoader = new URLClassLoader(new URL[0], classLoader);
+ }
+
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ testCaseClass = Class.forName(testClass.getName(), true, classLoader);
+ testCase = testCaseClass.newInstance();
+
+ junit3TestCaseClass = Class.forName("junit.framework.TestCase", true, classLoader);
+
+ testSuiteClass = Class.forName("junit.framework.TestSuite", true, classLoader);
+ Constructor testSuiteConstructor = testSuiteClass.getConstructor(Class.class);
+ testSuite = testSuiteConstructor.newInstance(testCaseClass);
+
+ testResultClass = Class.forName("junit.framework.TestResult", true, classLoader);
+
+ try {
+ beforeAnnotation = Class.forName("org.junit.Before", true, classLoader);
+ afterAnnotation = Class.forName("org.junit.After", true, classLoader);
+ beforeClassAnnotation = Class.forName("org.junit.BeforeClass", true, classLoader);
+ afterClassAnnotation = Class.forName("org.junit.AfterClass", true, classLoader);
+ junit4AdapterClass = Class.forName("junit.framework.JUnit4TestAdapter", true, classLoader);
+ } catch (Exception e) {
+ // Unexpected
+ throw new AssertionError(e);
+ }
+
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Run the test case
+ */
+ public void run() {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ if (junit3TestCaseClass.isAssignableFrom(testCaseClass)) {
+ Object testResult = testResultClass.newInstance();
+ Method runMethod = testSuiteClass.getMethod("run", testResultClass);
+ runMethod.invoke(testSuite, testResult);
+ } else {
+ Object junit4Adapter = junit4AdapterClass.getConstructor(Class.class).newInstance(testCaseClass);
+ Object testResult = testResultClass.newInstance();
+ Method runMethod = junit4AdapterClass.getMethod("run", testResultClass);
+ runMethod.invoke(junit4Adapter, testResult);
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+ /**
+ * Invoke the setUp method
+ */
+ public void setUp() {
+ execute("setUp");
+ }
+
+ /**
+ * Invoke the before methods
+ */
+ public void before() {
+ execute(beforeAnnotation);
+ }
+
+ /**
+ * Invoke the beforeClass methods
+ */
+ public void beforeClass() {
+ execute(beforeClassAnnotation);
+ }
+
+ /**
+ * Invoke the tearDown method
+ */
+ public void tearDown() {
+ execute("tearDown");
+ }
+
+ /**
+ * Invoke the after methods
+ */
+ public void after() {
+ execute(afterAnnotation);
+ }
+
+ /**
+ * Invoke the afterClass methods
+ */
+ public void afterClass() {
+ execute(afterClassAnnotation);
+ }
+
+ /**
+ * Invoke the specified test method.
+ */
+ public void run(String methodName) {
+ execute(methodName);
+ }
+
+ /**
+ * Invoke the methods annotated with the specified annotation.
+ */
+ private void execute(Class<?> annotationClass) {
+ if (annotationClass == null) {
+ throw new RuntimeException(new NoSuchMethodException());
+ }
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ for (Method method : testCaseClass.getDeclaredMethods()) {
+ for (Annotation annotation : method.getAnnotations()) {
+ if (annotation.annotationType() == annotationClass) {
+ method.invoke(testCase);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+ /**
+ * Invoke the specified method
+ */
+ private void execute(String methodName) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ Method setUpMethod = testCaseClass.getDeclaredMethod(methodName);
+ setUpMethod.setAccessible(true);
+ setUpMethod.invoke(testCase);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(tccl);
+ }
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ComponentManagerImpl.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ComponentManagerImpl.java
new file mode 100644
index 0000000000..8a512de5f8
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ComponentManagerImpl.java
@@ -0,0 +1,115 @@
+/*
+ * 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.host.embedded.impl;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl;
+import org.apache.tuscany.sca.host.embedded.management.ComponentListener;
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+
+public class ComponentManagerImpl implements ComponentManager {
+
+ protected List<ComponentListener> listeners = new CopyOnWriteArrayList<ComponentListener>();
+ protected EmbeddedSCADomain domain;
+
+ public ComponentManagerImpl(EmbeddedSCADomain domain) {
+ this.domain = domain;
+ }
+
+ public void addComponentListener(ComponentListener listener) {
+ this.listeners.add(listener);
+ }
+
+ public void removeComponentListener(ComponentListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ public Set<String> getComponentNames() {
+ Set<String> names = new HashSet<String>();
+ for (Composite composite: domain.getDomainComposite().getIncludes()) {
+ for (Component component: composite.getComponents()) {
+ names.add(component.getName());
+ }
+ }
+ return names;
+ }
+
+ public Component getComponent(String componentName) {
+ for (Composite composite: domain.getDomainComposite().getIncludes()) {
+ for (Component component: composite.getComponents()) {
+ if (component.getName().equals(componentName)) {
+ return component;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void startComponent(String componentName) throws ActivationException {
+ Component component = getComponent(componentName);
+ if (component == null) {
+ throw new IllegalArgumentException("no component: " + componentName);
+ }
+ domain.getCompositeActivator().start(component);
+ notifyComponentStarted(componentName);
+ }
+
+ public void stopComponent(String componentName) throws ActivationException {
+ Component component = getComponent(componentName);
+ if (component == null) {
+ throw new IllegalArgumentException("no component: " + componentName);
+ }
+ domain.getCompositeActivator().stop(component);
+ notifyComponentStopped(componentName);
+ }
+
+ public void notifyComponentStarted(String componentName) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStarted(componentName);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public void notifyComponentStopped(String componentName) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStopped(componentName);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public boolean isComponentStarted(String componentName) {
+ RuntimeComponentImpl runtimeComponent = (RuntimeComponentImpl)getComponent(componentName);
+ return runtimeComponent.isStarted();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/DefaultSCADomain.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/DefaultSCADomain.java
new file mode 100644
index 0000000000..1e6a5cb3b1
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/DefaultSCADomain.java
@@ -0,0 +1,500 @@
+/*
+ * 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.host.embedded.impl;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.DeployedArtifact;
+import org.apache.tuscany.sca.contribution.service.ContributionException;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.service.util.FileHelper;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+import org.apache.tuscany.sca.host.embedded.management.ComponentListener;
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.Constants;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * A default SCA domain facade implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultSCADomain extends SCADomain {
+
+ private String uri;
+ private String[] composites;
+ private Composite domainComposite;
+ private Contribution contribution;
+ private Map<String, Component> components = new HashMap<String, Component>();
+ private ReallySmallRuntime runtime;
+ private ComponentManager componentManager;
+
+ /**
+ * Constructs a new domain facade.
+ *
+ * @param domainURI
+ * @param contributionLocation
+ * @param composites
+ */
+ public DefaultSCADomain(ClassLoader runtimeClassLoader,
+ ClassLoader applicationClassLoader,
+ String domainURI,
+ String contributionLocation,
+ String... composites) {
+ this.uri = domainURI;
+ this.composites = composites;
+
+ // Create and start the runtime
+ runtime = new ReallySmallRuntime(runtimeClassLoader);
+ try {
+ runtime.start();
+
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+
+ // Contribute the given contribution to an in-memory repository
+ ContributionService contributionService = runtime.getContributionService();
+ URL contributionURL;
+ try {
+ contributionURL = getContributionLocation(applicationClassLoader, contributionLocation, this.composites);
+ if (contributionURL != null) {
+ // Make sure the URL is correctly encoded (for example, escape the space characters)
+ contributionURL = contributionURL.toURI().toURL();
+ }
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+
+ try {
+ String contributionURI = FileHelper.getName(contributionURL.getPath());
+ if(contributionURI == null || contributionURI.length() == 0) {
+ contributionURI = contributionURL.toString();
+ }
+ contribution = contributionService.contribute(contributionURI, contributionURL, false);
+ } catch (ContributionException e) {
+ throw new ServiceRuntimeException(e);
+ } catch (IOException e) {
+ throw new ServiceRuntimeException(e);
+ }
+
+ // Create an in-memory domain level composite
+ AssemblyFactory assemblyFactory = runtime.getAssemblyFactory();
+ domainComposite = assemblyFactory.createComposite();
+ domainComposite.setName(new QName(Constants.SCA_NS, "domain"));
+ domainComposite.setURI(domainURI);
+
+ //when the deployable composites were specified when initializing the runtime
+ if (composites != null && composites.length > 0 && composites[0].length() > 0) {
+ // Include all specified deployable composites in the SCA domain
+ Map<String, Composite> compositeArtifacts = new HashMap<String, Composite>();
+ for (DeployedArtifact artifact : contribution.getArtifacts()) {
+ if (artifact.getModel() instanceof Composite) {
+ compositeArtifacts.put(artifact.getURI(), (Composite)artifact.getModel());
+ }
+ }
+ for (String compositePath : composites) {
+ Composite composite = compositeArtifacts.get(compositePath);
+ if (composite == null) {
+ throw new ServiceRuntimeException("Composite not found: " + compositePath);
+ }
+ domainComposite.getIncludes().add(composite);
+ }
+ } else {
+ // in this case, a sca-contribution.xml should have been specified
+ for(Composite composite : contribution.getDeployables()) {
+ domainComposite.getIncludes().add(composite);
+ }
+
+ }
+
+ // Build the SCA composites
+ CompositeBuilder compositeBuilder = runtime.getCompositeBuilder();
+
+ for (Composite composite: domainComposite.getIncludes()) {
+ try {
+ compositeBuilder.build(composite);
+ } catch (CompositeBuilderException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ // Activate and start composites
+ CompositeActivator compositeActivator = runtime.getCompositeActivator();
+ compositeActivator.setDomainComposite(domainComposite);
+ for (Composite composite: domainComposite.getIncludes()) {
+ try {
+ compositeActivator.activate(composite);
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ for (Composite composite: domainComposite.getIncludes()) {
+ try {
+ for (Component component : composite.getComponents()) {
+ compositeActivator.start(component);
+ }
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ // Index the top level components
+ for (Composite composite: domainComposite.getIncludes()) {
+ for (Component component : composite.getComponents()) {
+ components.put(component.getName(), component);
+ }
+ }
+
+ this.componentManager = new DefaultSCADomainComponentManager(this);
+ }
+
+ @Override
+ public void close() {
+
+ super.close();
+
+ // Stop and deactivate composites
+ CompositeActivator compositeActivator = runtime.getCompositeActivator();
+ for (Composite composite: domainComposite.getIncludes()) {
+ try {
+ for (Component component : composite.getComponents()) {
+ compositeActivator.stop(component);
+ }
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ for (Composite composite: domainComposite.getIncludes()) {
+ try {
+ compositeActivator.deactivate(composite);
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ // Remove the contribution from the in-memory repository
+ ContributionService contributionService = runtime.getContributionService();
+ try {
+ contributionService.remove(contribution.getURI());
+ } catch (ContributionException e) {
+ throw new ServiceRuntimeException(e);
+ }
+
+ // Stop the runtime
+ try {
+ runtime.stop();
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Determine the location of a contribution, given a contribution path and a
+ * list of composites.
+ *
+ * @param contributionPath
+ * @param composites
+ * @param classLoader
+ * @return
+ * @throws MalformedURLException
+ */
+ private URL getContributionLocation(ClassLoader classLoader, String contributionPath, String[] composites)
+ throws MalformedURLException {
+ if (contributionPath != null && contributionPath.length() > 0) {
+ //encode spaces as they would cause URISyntaxException
+ contributionPath = contributionPath.replace(" ", "%20");
+ URI contributionURI = URI.create(contributionPath);
+ if (contributionURI.isAbsolute() || composites.length == 0) {
+ return new URL(contributionPath);
+ }
+ }
+
+ String contributionArtifactPath = null;
+ URL contributionArtifactURL = null;
+ if (composites != null && composites.length > 0 && composites[0].length() > 0) {
+
+ // Here the SCADomain was started with a reference to a composite file
+ contributionArtifactPath = composites[0];
+ contributionArtifactURL = classLoader.getResource(contributionArtifactPath);
+ if (contributionArtifactURL == null) {
+ throw new IllegalArgumentException("Composite not found: " + contributionArtifactPath);
+ }
+ } else {
+
+ // Here the SCADomain was started without any reference to a composite file
+ // We are going to look for an sca-contribution.xml or sca-contribution-generated.xml
+
+ // Look for META-INF/sca-contribution.xml
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_META;
+ contributionArtifactURL = classLoader.getResource(contributionArtifactPath);
+
+ // Look for META-INF/sca-contribution-generated.xml
+ if( contributionArtifactURL == null ) {
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_GENERATED_META;
+ contributionArtifactURL = classLoader.getResource(contributionArtifactPath);
+ }
+
+ // Look for META-INF/sca-deployables directory
+ if (contributionArtifactURL == null) {
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_DEPLOYABLES;
+ contributionArtifactURL = classLoader.getResource(contributionArtifactPath);
+ }
+ }
+
+ if (contributionArtifactURL == null) {
+ throw new IllegalArgumentException("Can't determine contribution deployables. Either specify a composite file, or use an sca-contribution.xml file to specify the deployables.");
+ }
+
+ URL contributionURL = null;
+ // "jar:file://....../something.jar!/a/b/c/app.composite"
+ try {
+ String url = contributionArtifactURL.toExternalForm();
+ String protocol = contributionArtifactURL.getProtocol();
+ if ("file".equals(protocol)) {
+ // directory contribution
+ if (url.endsWith(contributionArtifactPath)) {
+ String location = url.substring(0, url.lastIndexOf(contributionArtifactPath));
+ // workaround from evil url/uri form maven
+ contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
+ }
+
+ } else if ("jar".equals(protocol)) {
+ // jar contribution
+ String location = url.substring(4, url.lastIndexOf("!/"));
+ // workaround for evil url/uri from maven
+ contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
+ }
+ } catch (MalformedURLException mfe) {
+ throw new IllegalArgumentException(mfe);
+ }
+
+ return contributionURL;
+ }
+
+ @Override
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ return (R) runtime.getProxyFactory().cast(target);
+ }
+
+ @Override
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+ ServiceReference<B> serviceReference = getServiceReference(businessInterface, serviceName);
+ if (serviceReference == null) {
+ throw new ServiceRuntimeException("Service not found: " + serviceName);
+ }
+ return serviceReference.getService();
+ }
+
+ @Override
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String name) {
+
+ // Extract the component name
+ String componentName;
+ String serviceName;
+ int i = name.indexOf('/');
+ if (i != -1) {
+ componentName = name.substring(0, i);
+ serviceName = name.substring(i + 1);
+
+ } else {
+ componentName = name;
+ serviceName = null;
+ }
+
+ // Lookup the component in the domain
+ Component component = components.get(componentName);
+ if (component == null) {
+ throw new ServiceRuntimeException("Component not found: " + componentName);
+ }
+ ComponentContext componentContext = null;
+
+ // If the component is a composite, then we need to find the
+ // non-composite component that provides the requested service
+ if (component.getImplementation() instanceof Composite) {
+ for (ComponentService componentService : component.getServices()) {
+ if (serviceName == null || serviceName.equals(componentService.getName())) {
+ CompositeService compositeService = (CompositeService)componentService.getService();
+ if (compositeService != null) {
+ if (serviceName != null) {
+ serviceName = "$promoted$." + serviceName;
+ }
+ componentContext = ((RuntimeComponent)compositeService.getPromotedComponent()).getComponentContext();
+ }
+ break;
+ }
+ }
+ if (componentContext == null) {
+ throw new ServiceRuntimeException("Composite service not found: " + name);
+ }
+ } else {
+ componentContext = ((RuntimeComponent)component).getComponentContext();
+ }
+
+ ServiceReference<B> serviceReference;
+ if (serviceName != null) {
+ serviceReference = componentContext.createSelfReference(businessInterface, serviceName);
+ } else {
+ serviceReference = componentContext.createSelfReference(businessInterface);
+ }
+ return serviceReference;
+
+ }
+
+ @Override
+ public String getURI() {
+ return uri;
+ }
+
+ @Override
+ public ComponentManager getComponentManager() {
+ return componentManager;
+ }
+
+ public Set<String> getComponentNames() {
+ Set<String> componentNames = new HashSet<String>();
+ for (DeployedArtifact artifact : contribution.getArtifacts()) {
+ if (artifact.getModel() instanceof Composite) {
+ for (Component component : ((Composite)artifact.getModel()).getComponents()) {
+ componentNames.add(component.getName());
+ }
+ }
+ }
+ return componentNames;
+ }
+
+
+ public Component getComponent(String componentName) {
+ for (DeployedArtifact artifact : contribution.getArtifacts()) {
+ if (artifact.getModel() instanceof Composite) {
+ for (Component component : ((Composite)artifact.getModel()).getComponents()) {
+ if (component.getName().equals(componentName)) {
+ return component;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void startComponent(String componentName) throws ActivationException {
+ Component component = getComponent(componentName);
+ if (component == null) {
+ throw new IllegalArgumentException("no component: " + componentName);
+ }
+ CompositeActivator compositeActivator = runtime.getCompositeActivator();
+ compositeActivator.start(component);
+ }
+
+ public void stopComponent(String componentName) throws ActivationException {
+ Component component = getComponent(componentName);
+ if (component == null) {
+ throw new IllegalArgumentException("no component: " + componentName);
+ }
+ CompositeActivator compositeActivator = runtime.getCompositeActivator();
+ compositeActivator.stop(component);
+ }
+}
+
+class DefaultSCADomainComponentManager implements ComponentManager {
+
+ protected DefaultSCADomain scaDomain;
+ protected List<ComponentListener> listeners = new CopyOnWriteArrayList<ComponentListener>();
+
+ public DefaultSCADomainComponentManager(DefaultSCADomain scaDomain) {
+ this.scaDomain = scaDomain;
+ }
+
+ public void addComponentListener(ComponentListener listener) {
+ this.listeners.add(listener);
+ }
+
+ public void removeComponentListener(ComponentListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ public Set<String> getComponentNames() {
+ return scaDomain.getComponentNames();
+ }
+
+ public Component getComponent(String componentName) {
+ return scaDomain.getComponent(componentName);
+ }
+
+ public void startComponent(String componentName) throws ActivationException {
+ scaDomain.startComponent(componentName);
+ }
+
+ public void stopComponent(String componentName) throws ActivationException {
+ scaDomain.stopComponent(componentName);
+ }
+
+ public void notifyComponentStarted(String componentName) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStarted(componentName);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public void notifyComponentStopped(String componentName) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStopped(componentName);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public boolean isComponentStarted(String componentName) {
+ RuntimeComponentImpl runtimeComponent = (RuntimeComponentImpl)getComponent(componentName);
+ return runtimeComponent.isStarted();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/EmbeddedSCADomain.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/EmbeddedSCADomain.java
new file mode 100644
index 0000000000..20fa2837a3
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/EmbeddedSCADomain.java
@@ -0,0 +1,204 @@
+/*
+ * 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.host.embedded.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ComponentContext;
+import org.osoa.sca.Constants;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * An SCA domain facade implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EmbeddedSCADomain extends SCADomain {
+
+ private String uri;
+ private Composite domainComposite;
+ private ReallySmallRuntime runtime;
+ private ComponentManagerImpl componentManager = new ComponentManagerImpl(this);
+
+ /**
+ * Constructs a new domain facade.
+ *
+ * @param runtimeClassLoader
+ * @param domainURI
+ */
+ public EmbeddedSCADomain(ClassLoader runtimeClassLoader,
+ String domainURI) {
+ this.uri = domainURI;
+
+ // Create a runtime
+ runtime = new ReallySmallRuntime(runtimeClassLoader);
+ }
+
+ public void start() throws ActivationException {
+
+ // Start the runtime
+ runtime.start();
+
+ // Create an in-memory domain level composite
+ AssemblyFactory assemblyFactory = runtime.getAssemblyFactory();
+ domainComposite = assemblyFactory.createComposite();
+ domainComposite.setName(new QName(Constants.SCA_NS, "domain"));
+ domainComposite.setURI(uri);
+
+ getCompositeActivator().setDomainComposite(domainComposite);
+ }
+
+ public void stop() throws ActivationException {
+
+ // Stop the runtime
+ runtime.stop();
+
+ // Cleanup
+ domainComposite = null;
+ }
+
+ public ContributionService getContributionService() {
+ return runtime.getContributionService();
+ }
+
+ public CompositeBuilder getCompositeBuilder() {
+ return runtime.getCompositeBuilder();
+ }
+
+ public CompositeActivator getCompositeActivator() {
+ return runtime.getCompositeActivator();
+ }
+
+ public Composite getDomainComposite() {
+ return domainComposite;
+ }
+
+ @Override
+ public ComponentManager getComponentManager() {
+ return componentManager;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ }
+
+ @Override
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+ ServiceReference<B> serviceReference = getServiceReference(businessInterface, serviceName);
+ if (serviceReference == null) {
+ throw new ServiceRuntimeException("Service not found: " + serviceName);
+ }
+ return serviceReference.getService();
+ }
+
+ @Override
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String name) {
+
+ // Extract the component name
+ String componentName;
+ String serviceName;
+ int i = name.indexOf('/');
+ if (i != -1) {
+ componentName = name.substring(0, i);
+ serviceName = name.substring(i + 1);
+
+ } else {
+ componentName = name;
+ serviceName = null;
+ }
+
+ // Lookup the component in the domain
+ Component component = null;
+ for (Composite composite: domainComposite.getIncludes()) {
+ for (Component c: composite.getComponents()) {
+ if (c.getName().equals(componentName)) {
+ component = c;
+ break;
+ }
+ }
+ if (component != null)
+ break;
+ }
+ if (component == null) {
+ throw new ServiceRuntimeException("Component not found: " + componentName);
+ }
+ ComponentContext componentContext = null;
+
+ // If the component is a composite, then we need to find the
+ // non-composite
+ // component that provides the requested service
+ if (component.getImplementation() instanceof Composite) {
+ for (ComponentService componentService : component.getServices()) {
+ if (serviceName == null || serviceName.equals(componentService.getName())) {
+
+ CompositeService compositeService = (CompositeService)componentService.getService();
+ if (compositeService != null) {
+ if (serviceName != null) {
+ serviceName = "$promoted$." + serviceName;
+ }
+ componentContext = ((RuntimeComponent)compositeService.getPromotedComponent()).getComponentContext();
+ }
+ break;
+ }
+ }
+ if (componentContext == null) {
+ throw new ServiceRuntimeException("Composite service not found: " + name);
+ }
+ } else {
+ componentContext = ((RuntimeComponent)component).getComponentContext();
+ }
+
+ ServiceReference<B> serviceReference;
+ if (serviceName != null) {
+ serviceReference = componentContext.createSelfReference(businessInterface, serviceName);
+ } else {
+ serviceReference = componentContext.createSelfReference(businessInterface);
+ }
+ return serviceReference;
+
+ }
+
+ @Override
+ public String getURI() {
+ return uri;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/HotUpdatableSCADomain.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/HotUpdatableSCADomain.java
new file mode 100644
index 0000000000..2942e61db2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/HotUpdatableSCADomain.java
@@ -0,0 +1,391 @@
+/*
+ * 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.host.embedded.impl;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
+import org.apache.tuscany.sca.contribution.resolver.impl.ModelResolverImpl;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.service.util.FileHelper;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+import org.apache.tuscany.sca.host.embedded.management.ComponentManager;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * An SCADomain that starts a Tuscany runtime supporting multiple
+ * SCA contribution jars. All contribution jars found in a repository
+ * directory will be contributed to the SCA domain. Any changes to the
+ * contributions in that repository will be automatically detected and
+ * the sca domain updated accordingly.
+ *
+ * TODO: find how to properly add/remove contributions and start/activate the doamain
+ * TODO: support contributions that are folders as well as jar's
+ * TODO: needs to restart the entire scadomain when a contribution changes
+ * as the domain classpath includes all the contribution jar's, would
+ * be nice to find a way to avoid this
+ * TODO: hot update requires copying contribution jars to a temp location
+ * to avoid the classpath lock preventing updating the contribution
+ * jars, would be nice to find a way to avoid that
+ */
+public class HotUpdatableSCADomain extends SCADomain {
+ private static final Logger logger = Logger.getLogger(HotUpdatableSCADomain.class.getName());
+ protected String domainURI;
+ protected File contributionRepository;
+
+ protected EmbeddedSCADomain scaDomain;
+
+ protected boolean hotUpdateActive;
+ protected Thread hotUpdateThread;
+ protected int hotUpdateInterval; // milliseconds, 0 = hotupdate disabled
+
+ protected HashMap<URL, Long> existingContributions; // value is last modified time
+ protected ClassLoader originalCCL;
+
+ protected static final String REPOSITORY_FOLDER = "sca-contributions";
+
+ public HotUpdatableSCADomain(String domainURI, File contributionRepository, int hotupdateInterval) {
+ this.domainURI = domainURI;
+ this.contributionRepository = contributionRepository;
+ this.hotUpdateInterval = hotupdateInterval;
+ this.originalCCL = Thread.currentThread().getContextClassLoader();
+ start();
+ }
+
+ protected void start() {
+ try {
+ initEmbeddedSCADomain();
+ activateHotUpdate();
+ for (URL url : existingContributions.keySet()) {
+ File f = new File(url.toURI());
+ logger.info("added contribution: " + f.getName());
+ }
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ } catch (URISyntaxException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ @Override
+ public void close() {
+ try {
+ hotUpdateActive = false;
+ scaDomain.stop();
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ Thread.currentThread().setContextClassLoader(originalCCL);
+ super.close();
+ }
+
+
+ protected SCADomain initEmbeddedSCADomain() throws ActivationException {
+
+ URL[] contributionJars = getContributionJarURLs(contributionRepository);
+
+ this.existingContributions = getLastModified(contributionJars);
+
+ if (hotUpdateInterval > 0) {
+ contributionJars = copyContributionsToTemp(contributionJars);
+ }
+
+ // Using the CCL as the parent exposes Tuscany to the contributions, want to do this?
+ URLClassLoader cl = new URLClassLoader(contributionJars, originalCCL);
+ Thread.currentThread().setContextClassLoader(cl);
+
+ scaDomain = new EmbeddedSCADomain(cl, domainURI);
+
+ scaDomain.start();
+
+ initContributions(scaDomain, cl, contributionJars);
+
+ return scaDomain;
+ }
+
+ protected URL[] getContributionJarURLs(File repositoryDir) {
+
+ String[] jars = repositoryDir.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }});
+
+ List<URL> contributionJars = new ArrayList<URL>();
+ if (jars != null) {
+ for (String jar : jars) {
+ try {
+ contributionJars.add(new File(repositoryDir, jar).toURL());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ return contributionJars.toArray(new URL[contributionJars.size()]);
+ }
+
+ /**
+ * TODO: No idea what the 'correct' way to add/contribute and activate/start things to an scaDomain is
+ * but this seems to work. Doesn't seem to start <service>s or <reference>s which are outside of
+ * a <component> so something is missing/wrong. Also this doesn't seem to be picking up composites
+ * located in META-INF/deployables or specified in the sca-deployables.xml. Maybe the EmbeddedSCADomain
+ * and ContributionService APIs should make all this easier?
+ */
+ protected void initContributions(EmbeddedSCADomain scaDomain, ClassLoader cl, URL[] contributionJars) {
+ ModelResolverImpl modelResolver = new ModelResolverImpl(cl);
+ ContributionService contributionService = scaDomain.getContributionService();
+ for (URL jar : contributionJars) {
+ InputStream is = null;
+ try {
+ is = jar.openStream();
+ contributionService.contribute(jar.toString(), jar, is , modelResolver);
+ } catch (Exception e) {
+ System.err.println("exception adding contribution: " + jar);
+ e.printStackTrace();
+ }
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ try {
+
+ for (Object m : modelResolver.getModels()) {
+ if (m instanceof Composite) {
+ Composite composite = (Composite)m;
+ scaDomain.getDomainComposite().getIncludes().add(composite);
+ scaDomain.getCompositeBuilder().build(composite);
+ scaDomain.getCompositeActivator().activate(composite);
+ }
+ }
+
+ for (Object m : modelResolver.getModels()) {
+ if (m instanceof Composite) {
+ Composite composite = (Composite)m;
+ scaDomain.getCompositeActivator().start(composite);
+ }
+ }
+
+ } catch (ActivationException e) {
+ throw new RuntimeException(e);
+ } catch (CompositeBuilderException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /**
+ * Copies Files to a temp location returning the URLs of the new temp files.
+ * For hot update to work need to be able to delete/update the contribution jar's
+ * but as they're in the classpath the URLClassLoader has an open lock on the jar's
+ * so you can't update them. This solution copies each contribution to a temp
+ * location for use on the classpath, nicer would be a ClassLoder impl that doesn't
+ * lock the jar's.
+ */
+ protected URL[] copyContributionsToTemp(URL[] contributionJars) {
+ try {
+
+ URL[] newURLs = new URL[contributionJars.length];
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ for (int i=0; i<contributionJars.length; i++) {
+ File fin = new File(contributionJars[i].toURI());
+ File fout = File.createTempFile("tuscany", fin.getName(), tempDir);
+ fout.deleteOnExit();
+ FileHelper.copyFile(fin, fout);
+ fout.setLastModified(System.currentTimeMillis());
+ newURLs[i] = fout.toURL();
+ }
+ return newURLs;
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns the last modified times of the files pointed to by the URLs
+ */
+ protected HashMap<URL, Long> getLastModified(URL[] contrabutions) {
+ try {
+
+ HashMap<URL, Long> contributionLastUpdates = new HashMap<URL, Long>();
+ for (URL url: contrabutions) {
+ File f = new File(url.toURI());
+ contributionLastUpdates.put(url, new Long(f.lastModified()));
+ }
+ return contributionLastUpdates;
+
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected void activateHotUpdate() {
+ if (hotUpdateInterval == 0) {
+ return; // hotUpdateInterval of 0 disables hotupdate
+ }
+
+ Runnable runable = new Runnable() {
+ public void run() {
+ logger.info("Tuscany contribution hotupdate running");
+ while (hotUpdateActive) {
+ try {
+ Thread.sleep(hotUpdateInterval);
+ } catch (InterruptedException e) {
+ }
+ if (hotUpdateActive) {
+ checkForUpdates();
+ }
+ }
+ logger.info("Tuscany contribution hotupdate stopped");
+ }
+ };
+ hotUpdateThread = new Thread(runable, "TuscanyHotUpdate");
+ hotUpdateActive = true;
+ hotUpdateThread.start();
+ }
+
+
+ /**
+ * Checks if any of the contributions have been updated and if so restarts the sca domain
+ * TODO: Ideally just the altered contribution would be restarted but thats not possible
+ * as the classloader used by the SCADomain includes the old contribution so need
+ * to restart the entire domain to use a new ClassLoader. Should there be seperate
+ * ClassLoader per contribution? But then have all the issues with sharing classes
+ * across contributions.
+ */
+ protected void checkForUpdates() {
+ URL[] currentContributions = getContributionJarURLs(contributionRepository);
+
+ if (areContributionsAltered(currentContributions)) {
+ try {
+ scaDomain.stop();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ try {
+ initEmbeddedSCADomain();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected boolean areContributionsAltered(URL[] currentContrabutions) {
+ try {
+
+ List addedContributions = getAddedContributions(currentContrabutions);
+ List removedContributions = getRemovedContributions(currentContrabutions);
+ List updatedContributions = getUpdatedContributions(currentContrabutions);
+
+ return (addedContributions.size() > 0 || removedContributions.size() > 0 || updatedContributions.size() > 0);
+
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected List<URL> getUpdatedContributions(URL[] currentContrabutions) throws URISyntaxException {
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : currentContrabutions) {
+ if (existingContributions.containsKey(url)) {
+ File curentFile = new File(url.toURI());
+ if (curentFile.lastModified() != existingContributions.get(url)) {
+ urls.add(url);
+ logger.info("updated contribution: " + curentFile.getName());
+ }
+ }
+ }
+ return urls;
+ }
+
+ protected List getRemovedContributions(URL[] currentContrabutions) throws URISyntaxException {
+ List<URL> currentUrls = Arrays.asList(currentContrabutions);
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : existingContributions.keySet()) {
+ if (!currentUrls.contains(url)) {
+ urls.add(url);
+ }
+ }
+ for (URL url : urls) {
+ logger.info("removed contributions: " + new File(url.toURI()).getName());
+ }
+ return urls;
+ }
+
+ protected List getAddedContributions(URL[] currentContrabutions) throws URISyntaxException {
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : currentContrabutions) {
+ if (!existingContributions.containsKey(url)) {
+ urls.add(url);
+ logger.info("added contribution: " + new File(url.toURI()).getName());
+ }
+ }
+ return urls;
+ }
+
+ @Override
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+ return scaDomain.getService(businessInterface, serviceName);
+ }
+
+ @Override
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String referenceName) {
+ return scaDomain.getServiceReference(businessInterface, referenceName);
+ }
+
+ @Override
+ public String getURI() {
+ return domainURI;
+ }
+
+ @Override
+ public ComponentManager getComponentManager(){
+ return scaDomain.getComponentManager();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntime.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntime.java
new file mode 100644
index 0000000000..40ec206b2c
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntime.java
@@ -0,0 +1,242 @@
+/*
+ * 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.host.embedded.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.context.DefaultContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.service.ContributionReadException;
+import org.apache.tuscany.sca.contribution.service.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.util.ServiceConfigurationUtil;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;
+import org.apache.tuscany.sca.core.invocation.MessageFactoryImpl;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.policy.DefaultPolicyFactory;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.SCADefinitions;
+import org.apache.tuscany.sca.policy.xml.SCADefinitionsDocumentProcessor;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+public class ReallySmallRuntime {
+
+ private List<ModuleActivator> modules;
+ private ExtensionPointRegistry registry;
+
+ private ClassLoader classLoader;
+ private AssemblyFactory assemblyFactory;
+ private ContributionService contributionService;
+ private CompositeActivator compositeActivator;
+ private CompositeBuilder compositeBuilder;
+ private WorkScheduler workScheduler;
+ private ScopeRegistry scopeRegistry;
+ private ProxyFactory proxyFactory;
+
+ public ReallySmallRuntime(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ public void start() throws ActivationException {
+
+ // Create our extension point registry
+ registry = new DefaultExtensionPointRegistry();
+
+// Get work scheduler
+ workScheduler = registry.getExtensionPoint(WorkScheduler.class);
+
+ // Create an interface contract mapper
+ InterfaceContractMapper mapper = new InterfaceContractMapperImpl();
+
+ // Get factory extension point
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+
+ // Create context factory extension point
+ ContextFactoryExtensionPoint contextFactories = new DefaultContextFactoryExtensionPoint();
+ registry.addExtensionPoint(contextFactories);
+
+ // Create Message factory
+ MessageFactory messageFactory = new MessageFactoryImpl();
+ factories.addFactory(messageFactory);
+
+ // Create a proxy factory
+ proxyFactory = ReallySmallRuntimeBuilder.createProxyFactory(registry, mapper, messageFactory);
+
+ // Create model factories
+ assemblyFactory = new RuntimeAssemblyFactory(mapper, proxyFactory);
+ factories.addFactory(assemblyFactory);
+ PolicyFactory policyFactory = new DefaultPolicyFactory();
+ factories.addFactory(policyFactory);
+ SCABindingFactory scaBindingFactory = factories.getFactory(SCABindingFactory.class);
+ factories.addFactory(scaBindingFactory);
+ ContributionFactory contributionFactory = factories.getFactory(ContributionFactory.class);
+
+ SCADefinitionsDocumentProcessor scaDocDefnProcessor =
+ ReallySmallRuntimeBuilder.createSCADefinitionsDocProcessor(registry, policyFactory);
+
+ // Create a contribution service
+ contributionService = ReallySmallRuntimeBuilder.createContributionService(classLoader,
+ registry,
+ contributionFactory,
+ assemblyFactory,
+ policyFactory,
+ mapper,
+ scaDocDefnProcessor.getDomainModelResolver());
+
+ // Create the ScopeRegistry
+ scopeRegistry = ReallySmallRuntimeBuilder.createScopeRegistry(registry);
+
+ // Create a composite builder
+ compositeBuilder = ReallySmallRuntimeBuilder.createCompositeBuilder(assemblyFactory,
+ scaBindingFactory,
+ mapper);
+
+ // Create a composite activator
+ compositeActivator = ReallySmallRuntimeBuilder.createCompositeActivator(registry,
+ assemblyFactory,
+ scaBindingFactory,
+ mapper,
+ proxyFactory,
+ scopeRegistry,
+ workScheduler);
+
+
+ // Load the runtime modules
+ modules = loadModules(registry, classLoader);
+
+ // Start the runtime modules
+ startModules(registry, modules);
+
+ loadDomainDefinitions(scaDocDefnProcessor);
+ }
+
+ private void loadDomainDefinitions(SCADefinitionsDocumentProcessor scaDocDefnProcessor) throws ActivationException {
+ URL url = this.classLoader.getResource("definitions.xml");
+
+ if ( url != null ) {
+ try {
+ SCADefinitions scaDefinitions = scaDocDefnProcessor.read(null, null, url);
+ scaDocDefnProcessor.resolve(scaDefinitions, scaDocDefnProcessor.getDomainModelResolver());
+ } catch ( ContributionReadException e ) {
+ throw new ActivationException(e);
+ } catch ( ContributionResolveException e ) {
+ throw new ActivationException(e);
+ }
+ }
+ }
+
+ public void stop() throws ActivationException {
+
+ // Stop the runtime modules
+ stopModules(registry, modules);
+
+ // Stop and destroy the work manager
+ workScheduler.destroy();
+
+ // Cleanup
+ modules = null;
+ registry = null;
+ assemblyFactory = null;
+ contributionService = null;
+ compositeActivator = null;
+ workScheduler = null;
+ scopeRegistry = null;
+ }
+
+ public ContributionService getContributionService() {
+ return contributionService;
+ }
+
+ public CompositeActivator getCompositeActivator() {
+ return compositeActivator;
+ }
+
+ public CompositeBuilder getCompositeBuilder() {
+ return compositeBuilder;
+ }
+
+ public AssemblyFactory getAssemblyFactory() {
+ return assemblyFactory;
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<ModuleActivator> loadModules(ExtensionPointRegistry registry, ClassLoader classLoader) throws ActivationException {
+
+ // Load and instantiate the modules found on the classpath
+ modules = new ArrayList<ModuleActivator>();
+ try {
+ List<String> classNames = ServiceConfigurationUtil.getServiceClassNames(classLoader, ModuleActivator.class.getName());
+ for (String className : classNames) {
+ Class moduleClass = Class.forName(className, true, classLoader);
+ ModuleActivator module = (ModuleActivator)moduleClass.newInstance();
+ modules.add(module);
+ }
+ } catch (IOException e) {
+ throw new ActivationException(e);
+ } catch (ClassNotFoundException e) {
+ throw new ActivationException(e);
+ } catch (InstantiationException e) {
+ throw new ActivationException(e);
+ } catch (IllegalAccessException e) {
+ throw new ActivationException(e);
+ }
+
+ return modules;
+ }
+
+ private void startModules(ExtensionPointRegistry registry, List<ModuleActivator> modules) throws ActivationException {
+
+ // Start all the extension modules
+ for (ModuleActivator activator : modules) {
+ activator.start(registry);
+ }
+ }
+
+ private void stopModules(ExtensionPointRegistry registry, List<ModuleActivator> modules) {
+ for (ModuleActivator module : modules) {
+ module.stop(registry);
+ }
+ }
+
+ /**
+ * @return the proxyFactory
+ */
+ public ProxyFactory getProxyFactory() {
+ return proxyFactory;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntimeBuilder.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntimeBuilder.java
new file mode 100644
index 0000000000..afe5180a64
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/impl/ReallySmallRuntimeBuilder.java
@@ -0,0 +1,245 @@
+/*
+ * 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.host.embedded.impl;
+
+import java.io.IOException;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.impl.CompositeBuilderImpl;
+import org.apache.tuscany.sca.assembly.xml.ComponentTypeDocumentProcessor;
+import org.apache.tuscany.sca.assembly.xml.ComponentTypeProcessor;
+import org.apache.tuscany.sca.assembly.xml.CompositeDocumentProcessor;
+import org.apache.tuscany.sca.assembly.xml.CompositeProcessor;
+import org.apache.tuscany.sca.assembly.xml.ConstrainingTypeDocumentProcessor;
+import org.apache.tuscany.sca.assembly.xml.ConstrainingTypeProcessor;
+import org.apache.tuscany.sca.binding.sca.xml.SCABindingProcessor;
+import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ContributionPostProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionPostProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleContributionPostProcessor;
+import org.apache.tuscany.sca.contribution.processor.ExtensiblePackageProcessor;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.PackageProcessor;
+import org.apache.tuscany.sca.contribution.processor.PackageProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.contribution.service.ContributionListenerExtensionPoint;
+import org.apache.tuscany.sca.contribution.service.ContributionRepository;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.service.ExtensibleContributionListener;
+import org.apache.tuscany.sca.contribution.service.TypeDescriber;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionMetadataProcessor;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionRepositoryImpl;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl;
+import org.apache.tuscany.sca.contribution.service.impl.PackageTypeDescriberImpl;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl;
+import org.apache.tuscany.sca.core.invocation.DefaultProxyFactoryExtensionPoint;
+import org.apache.tuscany.sca.core.invocation.ExtensibleWireProcessor;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.CompositeScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ConversationalScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.RequestScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.core.scope.ScopeRegistryImpl;
+import org.apache.tuscany.sca.core.scope.StatelessScopeContainerFactory;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.xml.SCADefinitionsDocumentProcessor;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+public class ReallySmallRuntimeBuilder {
+
+ public static ProxyFactory createProxyFactory(ExtensionPointRegistry registry,
+ InterfaceContractMapper mapper,
+ MessageFactory messageFactory) {
+
+ ProxyFactory proxyFactory = new DefaultProxyFactoryExtensionPoint(messageFactory, mapper);
+
+ // FIXME Pass these around differently as they are not extension points
+ registry.addExtensionPoint(proxyFactory);
+ registry.addExtensionPoint(mapper);
+
+ return proxyFactory;
+ }
+
+ public static CompositeActivator createCompositeActivator(ExtensionPointRegistry registry,
+ AssemblyFactory assemblyFactory,
+ SCABindingFactory scaBindingFactory,
+ InterfaceContractMapper mapper,
+ ProxyFactory proxyFactory,
+ ScopeRegistry scopeRegistry,
+ WorkScheduler workScheduler) {
+
+ // Create a wire post processor extension point
+ RuntimeWireProcessorExtensionPoint wireProcessors = registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class);
+ RuntimeWireProcessor wireProcessor = new ExtensibleWireProcessor(wireProcessors);
+
+ // Add the SCABindingProcessor extension
+ PolicyFactory policyFactory = registry.getExtensionPoint(PolicyFactory.class);
+ SCABindingProcessor scaBindingProcessor =
+ new SCABindingProcessor(assemblyFactory, policyFactory, scaBindingFactory);
+ StAXArtifactProcessorExtensionPoint processors =
+ registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ processors.addArtifactProcessor(scaBindingProcessor);
+
+ // Create a provider factory extension point
+ ProviderFactoryExtensionPoint providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ JavaInterfaceFactory javaInterfaceFactory = registry.getExtensionPoint(ModelFactoryExtensionPoint.class).getFactory(JavaInterfaceFactory.class);
+ RequestContextFactory requestContextFactory = registry.getExtensionPoint(ContextFactoryExtensionPoint.class).getFactory(RequestContextFactory.class);
+
+ // Create the composite activator
+ CompositeActivator compositeActivator =
+ new CompositeActivatorImpl(assemblyFactory, javaInterfaceFactory, scaBindingFactory, mapper, scopeRegistry, workScheduler,
+ wireProcessor, requestContextFactory, proxyFactory, providerFactories, processors);
+
+ return compositeActivator;
+ }
+
+ public static CompositeBuilder createCompositeBuilder(AssemblyFactory assemblyFactory, SCABindingFactory scaBindingFactory, InterfaceContractMapper interfaceContractMapper) {
+ return new CompositeBuilderImpl(assemblyFactory, scaBindingFactory, interfaceContractMapper, null);
+ }
+
+ /**
+ * Create the contribution service used by this domain.
+ *
+ * @throws ActivationException
+ */
+ public static ContributionService createContributionService(ClassLoader classLoader,
+ ExtensionPointRegistry registry,
+ ContributionFactory contributionFactory,
+ AssemblyFactory assemblyFactory,
+ PolicyFactory policyFactory,
+ InterfaceContractMapper mapper,
+ ModelResolver domainModelResolver)
+ throws ActivationException {
+
+ XMLInputFactory xmlFactory = registry.getExtensionPoint(XMLInputFactory.class);
+
+ // Create STAX artifact processor extension point
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ // Create and register STAX processors for SCA assembly XML
+ ExtensibleStAXArtifactProcessor staxProcessor =
+ new ExtensibleStAXArtifactProcessor(staxProcessors, xmlFactory, XMLOutputFactory.newInstance());
+ staxProcessors.addArtifactProcessor(new CompositeProcessor(contributionFactory, assemblyFactory, policyFactory, mapper, staxProcessor));
+ staxProcessors.addArtifactProcessor(new ComponentTypeProcessor(assemblyFactory, policyFactory, staxProcessor));
+ staxProcessors.addArtifactProcessor(new ConstrainingTypeProcessor(assemblyFactory, policyFactory, staxProcessor));
+
+ // Register STAX processors for Contribution Metadata
+ staxProcessors.addArtifactProcessor(new ContributionMetadataProcessor(assemblyFactory, contributionFactory, staxProcessor));
+
+ // Create URL artifact processor extension point
+ URLArtifactProcessorExtensionPoint documentProcessors = registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+
+ // Create and register document processors for SCA assembly XML
+ XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+ documentProcessors.addArtifactProcessor(new CompositeDocumentProcessor(staxProcessor, inputFactory));
+ documentProcessors.addArtifactProcessor(new ComponentTypeDocumentProcessor(staxProcessor, inputFactory));
+ documentProcessors.addArtifactProcessor(new ConstrainingTypeDocumentProcessor(staxProcessor, inputFactory));
+
+ // Create Model Resolver extension point
+ ModelResolverExtensionPoint modelResolvers = registry.getExtensionPoint(ModelResolverExtensionPoint.class);
+
+ // Create contribution package processor extension point
+ TypeDescriber describer = new PackageTypeDescriberImpl();
+ PackageProcessor packageProcessor = new ExtensiblePackageProcessor(registry.getExtensionPoint(PackageProcessorExtensionPoint.class), describer);
+
+ // Get the model factory extension point
+ ModelFactoryExtensionPoint modelFactories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+
+ //FIXME remove this
+ ContributionPostProcessor postProcessor = new ExtensibleContributionPostProcessor(registry.getExtensionPoint(ContributionPostProcessorExtensionPoint.class));
+
+ // Create contribution listener
+ ExtensibleContributionListener contributionListener = new ExtensibleContributionListener(registry.getExtensionPoint(ContributionListenerExtensionPoint.class));
+
+ // Create a contribution repository
+ ContributionRepository repository;
+ try {
+ repository = new ContributionRepositoryImpl("target");
+ } catch (IOException e) {
+ throw new ActivationException(e);
+ }
+
+ ExtensibleURLArtifactProcessor documentProcessor = new ExtensibleURLArtifactProcessor(documentProcessors);
+
+ ContributionService contributionService =
+ new ContributionServiceImpl(repository, packageProcessor, documentProcessor,
+ staxProcessor, contributionListener,
+ postProcessor, domainModelResolver, modelResolvers, modelFactories,
+ assemblyFactory, contributionFactory, xmlFactory);
+ return contributionService;
+ }
+
+ public static ScopeRegistry createScopeRegistry(ExtensionPointRegistry registry) {
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ ScopeContainerFactory[] factories =
+ new ScopeContainerFactory[] {new CompositeScopeContainerFactory(), new StatelessScopeContainerFactory(),
+ new RequestScopeContainerFactory(),
+ new ConversationalScopeContainerFactory(null),
+ // new HttpSessionScopeContainer(monitor)
+ };
+ for (ScopeContainerFactory f : factories) {
+ scopeRegistry.register(f);
+ }
+
+ //FIXME Pass the scope container differently as it's not an extension point
+ registry.addExtensionPoint(scopeRegistry);
+
+ return scopeRegistry;
+ }
+
+ public static SCADefinitionsDocumentProcessor createSCADefinitionsDocProcessor(ExtensionPointRegistry registry,
+ PolicyFactory policyFactory) {
+ XMLInputFactory xmlFactory = registry.getExtensionPoint(XMLInputFactory.class);
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ ExtensibleStAXArtifactProcessor staxProcessor =
+ new ExtensibleStAXArtifactProcessor(staxProcessors, xmlFactory, XMLOutputFactory.newInstance());
+ SCADefinitionsDocumentProcessor scaDocDefnProcessor = new SCADefinitionsDocumentProcessor(staxProcessors,
+ staxProcessor,
+ xmlFactory,
+ policyFactory);
+
+ return scaDocDefnProcessor;
+ }
+
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentListener.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentListener.java
new file mode 100644
index 0000000000..452f1a1ab1
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.host.embedded.management;
+
+import java.util.EventListener;
+
+public interface ComponentListener extends EventListener {
+
+ void componentStarted(String componentName);
+ void componentStopped(String componentName);
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentManager.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentManager.java
new file mode 100644
index 0000000000..57b6a6d746
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/ComponentManager.java
@@ -0,0 +1,43 @@
+/*
+ * 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.host.embedded.management;
+
+import java.util.Set;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+
+public interface ComponentManager {
+
+ Set<String> getComponentNames();
+
+ Component getComponent(String componentName);
+
+ boolean isComponentStarted(String componentName);
+
+ void startComponent(String componentName) throws ActivationException;
+
+ void stopComponent(String componentName) throws ActivationException;
+
+ void addComponentListener(ComponentListener listener);
+
+ void removeComponentListener(ComponentListener listener);
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentInfo.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentInfo.java
new file mode 100644
index 0000000000..1b835d1ba6
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentInfo.java
@@ -0,0 +1,32 @@
+/*
+ * 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.host.embedded.management.variation;
+
+public interface ComponentInfo {
+
+ public String getName();
+
+ public void setName(String name);
+
+ public boolean isStarted();
+
+ public void setStarted(boolean started);
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentListener.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentListener.java
new file mode 100644
index 0000000000..f117304a81
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentListener.java
@@ -0,0 +1,31 @@
+/*
+ * 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.host.embedded.management.variation;
+
+import java.util.EventListener;
+
+import org.apache.tuscany.sca.assembly.Component;
+
+public interface ComponentListener extends EventListener {
+
+ void componentStarted(Component component);
+ void componentStopped(Component component);
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManager.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManager.java
new file mode 100644
index 0000000000..399d30836f
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManager.java
@@ -0,0 +1,43 @@
+/*
+ * 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.host.embedded.management.variation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+
+public interface ComponentManager {
+
+ List<Component> getComponents();
+
+ Component getComponent(String componentName);
+
+ boolean isComponentStarted(Component component);
+
+ void startComponent(Component component) throws ActivationException;
+
+ void stopComponent(Component component) throws ActivationException;
+
+ void addComponentListener(ComponentListener listener);
+
+ void removeComponentListener(ComponentListener listener);
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManagerService.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManagerService.java
new file mode 100644
index 0000000000..547e4c13d2
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/ComponentManagerService.java
@@ -0,0 +1,36 @@
+/*
+ * 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.host.embedded.management.variation;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+
+public interface ComponentManagerService {
+
+ List<ComponentInfo> getComponentInfos();
+
+ ComponentInfo getComponentInfo(String componentName);
+
+ void startComponent(String componentName) throws ActivationException;
+
+ void stopComponent(String componentName) throws ActivationException;
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentInfoImpl.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentInfoImpl.java
new file mode 100644
index 0000000000..76b8c866fc
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentInfoImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.host.embedded.management.variation.impl;
+
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentInfo;
+
+public class ComponentInfoImpl implements ComponentInfo {
+
+ private String name;
+ private boolean started;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerImpl.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerImpl.java
new file mode 100644
index 0000000000..384122e1d3
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerImpl.java
@@ -0,0 +1,105 @@
+/*
+ * 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.host.embedded.management.variation.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.RuntimeComponentImpl;
+import org.apache.tuscany.sca.host.embedded.impl.EmbeddedSCADomain;
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentListener;
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentManager;
+
+public class ComponentManagerImpl implements ComponentManager {
+
+ protected List<ComponentListener> listeners = new CopyOnWriteArrayList<ComponentListener>();
+ protected EmbeddedSCADomain domain;
+
+ public ComponentManagerImpl(EmbeddedSCADomain domain) {
+ this.domain = domain;
+ }
+
+ public void addComponentListener(ComponentListener listener) {
+ this.listeners.add(listener);
+ }
+
+ public void removeComponentListener(ComponentListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ public Component getComponent(String componentName) {
+ for (Composite composite: domain.getDomainComposite().getIncludes()) {
+ for (Component component: composite.getComponents()) {
+ if (component.getName().equals(componentName)) {
+ return component;
+ }
+ }
+ }
+ return null;
+ }
+
+ public List<Component> getComponents() {
+ List<Component> components = new ArrayList<Component>();
+ for (Composite composite: domain.getDomainComposite().getIncludes()) {
+ components.addAll(composite.getComponents());
+ }
+ return components;
+ }
+
+ public void startComponent(Component component) throws ActivationException {
+ domain.getCompositeActivator().start(component);
+ notifyComponentStarted(component);
+ }
+
+ public void stopComponent(Component component) throws ActivationException {
+ domain.getCompositeActivator().stop(component);
+ notifyComponentStopped(component);
+ }
+
+ public void notifyComponentStarted(Component component) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStarted(component);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public void notifyComponentStopped(Component component) {
+ for (ComponentListener listener : listeners) {
+ try {
+ listener.componentStopped(component);
+ } catch (Exception e) {
+ e.printStackTrace(); // TODO: log
+ }
+ }
+ }
+
+ public boolean isComponentStarted(Component component) {
+ RuntimeComponentImpl runtimeComponent = (RuntimeComponentImpl)component;
+ return runtimeComponent.isStarted();
+ }
+
+}
diff --git a/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerServiceImpl.java b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerServiceImpl.java
new file mode 100644
index 0000000000..cb05c28841
--- /dev/null
+++ b/branches/sca-java-0.99/modules/host-embedded/src/main/java/org/apache/tuscany/sca/host/embedded/management/variation/impl/ComponentManagerServiceImpl.java
@@ -0,0 +1,66 @@
+/*
+ * 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.host.embedded.management.variation.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentInfo;
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentManager;
+import org.apache.tuscany.sca.host.embedded.management.variation.ComponentManagerService;
+
+public class ComponentManagerServiceImpl implements ComponentManagerService {
+
+ private ComponentManager componentManager;
+
+ public ComponentManagerServiceImpl(ComponentManager componentManager) {
+ this.componentManager = componentManager;
+ }
+
+ public List<ComponentInfo> getComponentInfos() {
+ List<ComponentInfo> componentInfos = new ArrayList<ComponentInfo>();
+ for (Component component: componentManager.getComponents()) {
+ ComponentInfo componentInfo = new ComponentInfoImpl();
+ componentInfo.setName(component.getName());
+ componentInfo.setStarted(componentManager.isComponentStarted(component));
+ componentInfos.add(componentInfo);
+ }
+ return componentInfos;
+ }
+
+ public ComponentInfo getComponentInfo(String componentName) {
+ Component component = componentManager.getComponent(componentName);
+ ComponentInfo componentInfo = new ComponentInfoImpl();
+ componentInfo.setName(component.getName());
+ componentInfo.setStarted(componentManager.isComponentStarted(component));
+ return componentInfo;
+ }
+
+ public void startComponent(String componentName) throws ActivationException {
+ componentManager.startComponent(componentManager.getComponent(componentName));
+ }
+
+ public void stopComponent(String componentName) throws ActivationException {
+ componentManager.stopComponent(componentManager.getComponent(componentName));
+ }
+
+}