summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl')
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java689
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/DomainRegistryImpl.java285
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointSerializerImpl.java198
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/LocalDomainRegistryFactory.java49
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParameterProcessor.java98
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParametersImpl.java121
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentImpl.java139
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentReferenceImpl.java66
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentServiceImpl.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java1285
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java840
-rw-r--r--sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/WSDLHelper.java514
12 files changed, 4324 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java
new file mode 100644
index 0000000000..c3cb51d8d1
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/CompositeActivatorImpl.java
@@ -0,0 +1,689 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.context.CompositeContext;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.scope.ScopeContainer;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.provider.EndpointReferenceAsyncProvider;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.provider.PolicyProvider;
+import org.apache.tuscany.sca.provider.PolicyProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.provider.RuntimeProvider;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.ActivationException;
+import org.apache.tuscany.sca.runtime.CompositeActivator;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CompositeActivatorImpl implements CompositeActivator {
+ final Logger logger = Logger.getLogger(CompositeActivatorImpl.class.getName());
+
+ private final ScopeRegistry scopeRegistry;
+ private final ProviderFactoryExtensionPoint providerFactories;
+ private Monitor monitor;
+
+ public CompositeActivatorImpl(ExtensionPointRegistry extensionPoints) {
+ UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
+ this.scopeRegistry = utilities.getUtility(ScopeRegistry.class);
+ this.providerFactories = extensionPoints.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+ this.monitor = utilities.getUtility(MonitorFactory.class).createMonitor();
+ }
+
+ //=========================================================================
+ // Activation
+ //=========================================================================
+
+ // Composite activation/deactivation
+
+ public void activate(CompositeContext compositeContext, Composite composite) throws ActivationException {
+ try {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Activating composite: " + composite.getName());
+ }
+ for (Component component : composite.getComponents()) {
+ activateComponent(compositeContext, component);
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ public void deactivate(Composite composite) throws ActivationException {
+ try {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Deactivating composite: " + composite.getName());
+ }
+ for (Component component : composite.getComponents()) {
+ deactivateComponent(component);
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ // Component activation/deactivation
+
+ public void activateComponent(CompositeContext compositeContext, Component component)
+ throws ActivationException {
+ try {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Activating component: " + component.getURI());
+ }
+
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ activate(compositeContext, (Composite) implementation);
+ } else if (implementation != null) {
+ addImplementationProvider((RuntimeComponent) component,
+ implementation);
+ addScopeContainer(component);
+ }
+
+ for (ComponentService service : component.getServices()) {
+ activate(compositeContext,
+ (RuntimeComponent) component, (RuntimeComponentService) service);
+ }
+
+ for (ComponentReference reference : component.getReferences()) {
+ activate(compositeContext,
+ (RuntimeComponent) component, (RuntimeComponentReference) reference);
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ public void deactivateComponent(Component component)
+ throws ActivationException {
+ try {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Deactivating component: " + component.getURI());
+ }
+ for (ComponentService service : component.getServices()) {
+ deactivate((RuntimeComponent) component,
+ (RuntimeComponentService) service);
+ }
+
+ for (ComponentReference reference : component.getReferences()) {
+ deactivate((RuntimeComponent) component,
+ (RuntimeComponentReference) reference);
+ }
+
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ deactivate((Composite) implementation);
+ } else if (implementation != null) {
+ removeImplementationProvider((RuntimeComponent) component);
+ removeScopeContainer(component);
+ }
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ // add/remove artifacts required to get the implementation going
+
+ private void addImplementationProvider(RuntimeComponent component, Implementation implementation) {
+ ImplementationProviderFactory providerFactory =
+ (ImplementationProviderFactory)providerFactories.getProviderFactory(implementation.getClass());
+ if (providerFactory != null) {
+ @SuppressWarnings("unchecked")
+ ImplementationProvider implementationProvider =
+ providerFactory.createImplementationProvider(component, implementation);
+ if (implementationProvider != null) {
+ component.setImplementationProvider(implementationProvider);
+ }
+ } else {
+ throw new IllegalStateException("Provider factory not found for class: " + implementation.getClass()
+ .getName());
+ }
+ for (PolicyProviderFactory f : providerFactories.getPolicyProviderFactories()) {
+ PolicyProvider policyProvider = f.createImplementationPolicyProvider(component);
+ if (policyProvider != null) {
+ component.addPolicyProvider(policyProvider);
+ }
+ }
+
+ }
+
+ private void removeImplementationProvider(RuntimeComponent component) {
+ component.setImplementationProvider(null);
+ component.getPolicyProviders().clear();
+ }
+
+ private void addScopeContainer(Component component) {
+ if (!(component instanceof ScopedRuntimeComponent)) {
+ return;
+ }
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ ScopeContainer scopeContainer = scopeRegistry.getScopeContainer(runtimeComponent);
+ runtimeComponent.setScopeContainer(scopeContainer);
+ }
+
+ private void removeScopeContainer(Component component) {
+ if (!(component instanceof ScopedRuntimeComponent)) {
+ return;
+ }
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ ScopeContainer scopeContainer = runtimeComponent.getScopeContainer();
+ runtimeComponent.setScopeContainer(null);
+ }
+
+
+ // Service activation/deactivation
+
+ public void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentService service) {
+ if (service.getService() == null) {
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("Skipping component service not defined in the component type: " + component.getURI()
+ + "#"
+ + service.getName());
+ }
+ return;
+ }
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Activating component service: " + component.getURI() + "#" + service.getName());
+ }
+
+ // Add a wire for each service Endpoint
+ for ( Endpoint endpoint : service.getEndpoints()){
+ RuntimeEndpoint ep = (RuntimeEndpoint) endpoint;
+ activate(compositeContext, ep);
+
+ // create the interface contract for the binding and service ends of the wire
+ // that are created as forward only contracts
+ // FIXME: [rfeng] We might need a better way to get the impl interface contract
+ Service targetService = service.getService();
+ if (targetService == null) {
+ targetService = service;
+ }
+ // endpoint.setInterfaceContract(targetService.getInterfaceContract().makeUnidirectional(false));
+ }
+ }
+
+ public void activate(CompositeContext compositeContext, RuntimeEndpoint ep) {
+ ep.bind(compositeContext);
+
+ // Check that the service binding interface is compatible with the
+ // service interface
+ ep.validateServiceInterfaceCompatibility();
+ }
+
+ public void deactivate(RuntimeComponent component, RuntimeComponentService service) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Deactivating component service: " + component.getURI() + "#" + service.getName());
+ }
+ for(Endpoint ep: service.getEndpoints()) {
+ if(ep instanceof RuntimeEndpoint) {
+ deactivate((RuntimeEndpoint) ep);
+ }
+ }
+ }
+
+ public void deactivate(RuntimeEndpoint ep) {
+ ep.unbind();
+ }
+
+ // Reference activation/deactivation
+
+ public void activate(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference reference) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Activating component reference: " + component.getURI() + "#" + reference.getName());
+ }
+
+ // set the parent component onto the reference. It's used at start time when the
+ // reference is asked to return it's runtime wires. If there are none the reference
+ // asks the component context to start the reference which creates the wires
+ reference.setComponent(component);
+ for(EndpointReference epr: reference.getEndpointReferences()) {
+ activate(compositeContext, (RuntimeEndpointReference) epr);
+ }
+
+ }
+
+ public void deactivate(RuntimeComponent component, RuntimeComponentReference reference) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Deactivating component reference: " + component.getURI() + "#" + reference.getName());
+ }
+ for(EndpointReference endpointReference: reference.getEndpointReferences()) {
+ deactivate((RuntimeEndpointReference)endpointReference);
+ }
+ }
+
+ public void activate(CompositeContext compositeContext, RuntimeEndpointReference epr) {
+ // create the wire
+ // null endpoint passed in here as the endpoint reference may
+ // not be resolved yet
+ epr.bind(compositeContext);
+
+ ComponentReference reference = epr.getReference();
+ InterfaceContract sourceContract = epr.getComponentTypeReferenceInterfaceContract();
+
+ // TODO - EPR - interface contract seems to be null in the implementation.web
+ // case. Not introspecting the CT properly?
+ if (sourceContract == null){
+ // TODO - Can't do this with move of matching to wire
+ // take the contract from the service to which the reference is connected
+ sourceContract = ((RuntimeEndpoint) epr.getTargetEndpoint()).getComponentTypeServiceInterfaceContract();
+ reference.setInterfaceContract(sourceContract);
+ }
+
+ // endpointReference.setInterfaceContract(sourceContract.makeUnidirectional(false));
+
+ // if the reference already has a binding we can check the reference binding interface
+ // and reference interfaces for compatibility. If we can't check now compatibility
+ // will be checked when the endpoint reference is resolved.
+ if (epr.getStatus() == EndpointReference.Status.RESOLVED_BINDING){
+ epr.validateReferenceInterfaceCompatibility();
+ }
+ }
+
+ public void deactivate(RuntimeEndpointReference endpointReference) {
+ endpointReference.unbind();
+ }
+
+ //=========================================================================
+ // Start
+ //=========================================================================
+
+ // Composite start/stop
+
+ public void start(CompositeContext compositeContext, Composite composite) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Starting composite: " + composite.getName());
+ }
+ for (Component component : composite.getComponents()) {
+ start(compositeContext, component);
+ }
+
+ for (Component component : composite.getComponents()) {
+ if (component instanceof ScopedRuntimeComponent) {
+ start(compositeContext, (ScopedRuntimeComponent)component);
+ }
+ }
+
+ // start reference last. In allowing references to start at "start" time
+ // as well as when they are first used (for late bound references) we need
+ // to make sure that all potential target services and component implementations
+ // are started first to take account of the default binding optimization case
+ for (Component component : composite.getComponents()) {
+ for (ComponentReference reference : component.getReferences()) {
+ start(compositeContext,
+ (RuntimeComponent)component,
+ (RuntimeComponentReference)reference);
+ }
+ }
+ }
+
+ public void stop(CompositeContext compositeContext, Composite composite) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Stopping composite: " + composite.getName());
+ }
+ for (final Component component : composite.getComponents()) {
+ stop(compositeContext, component);
+ }
+ }
+
+ // Component start/stop
+
+ public void start(CompositeContext compositeContext, Component component) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Starting component: " + component.getURI());
+ }
+ RuntimeComponent runtimeComponent = ((RuntimeComponent)component);
+ if(runtimeComponent.isStarted()) {
+ return;
+ }
+
+ compositeContext.bindComponent(runtimeComponent);
+ Implementation implementation = component.getImplementation();
+
+ List<RuntimeProvider> providers = new ArrayList<RuntimeProvider>();
+ try {
+
+ if (implementation instanceof Composite) {
+ try {
+ start(compositeContext, (Composite)implementation);
+ } catch (Throwable e) {
+ try {
+ stop(compositeContext, (Composite) implementation);
+ } catch (Throwable e1) {
+ Monitor.error(monitor, this, "core-messages", "StopException", e1);
+ }
+ rethrow(e);
+ }
+ } else {
+ for (PolicyProvider policyProvider : runtimeComponent.getPolicyProviders()) {
+ policyProvider.start();
+ providers.add(policyProvider);
+ }
+ ImplementationProvider implementationProvider = runtimeComponent.getImplementationProvider();
+ if (implementationProvider != null) {
+ implementationProvider.start();
+ providers.add(implementationProvider);
+ }
+ }
+
+ for (ComponentService service : component.getServices()) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Starting component service: " + component.getURI() + "#" + service.getName());
+ }
+ for (Endpoint endpoint : service.getEndpoints()) {
+ RuntimeEndpoint ep = (RuntimeEndpoint)endpoint;
+ startEndpoint(compositeContext, ep, providers);
+ }
+ }
+
+ // Reference start is done after all components have been started to make sure everything
+ // is up and running before we try and connect references to services
+
+ } catch (Throwable e) {
+ // any providers (binding, implementation, policy) that were started
+ // before the error occured are stopped here
+ for (int i = providers.size() - 1; i >= 0; i--) {
+ try {
+ providers.get(i).stop();
+ } catch (Throwable e1) {
+ Monitor.error(monitor, this, "core-messages", "StopException", e1);
+ }
+ }
+ rethrow(e);
+ } finally {
+ providers.clear();
+ }
+
+ // mark a successful start
+ runtimeComponent.setStarted(true);
+ }
+
+ private void rethrow(Throwable e) throws Error {
+ if(e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ } else if(e instanceof Error) {
+ throw (Error) e;
+ }
+ }
+
+ public void stop(CompositeContext compositeContext, Component component) {
+ if (!((RuntimeComponent)component).isStarted()) {
+ return;
+ }
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Stopping component: " + component.getURI());
+ }
+ for (ComponentService service : component.getServices()) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Stopping component service: " + component.getURI() + "#" + service.getName());
+ }
+ for (Endpoint endpoint : service.getEndpoints()) {
+ RuntimeEndpoint ep = (RuntimeEndpoint) endpoint;
+ stop(ep);
+ }
+ }
+ for (ComponentReference reference : component.getReferences()) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Stopping component reference: " + component.getURI() + "#" + reference.getName());
+ }
+
+ for (EndpointReference endpointReference : reference.getEndpointReferences()) {
+ RuntimeEndpointReference epr = (RuntimeEndpointReference) endpointReference;
+ stop(epr);
+ }
+ }
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ stop(compositeContext, (Composite)implementation);
+ } else {
+ final ImplementationProvider implementationProvider = ((RuntimeComponent)component).getImplementationProvider();
+ if (implementationProvider != null) {
+ try {
+ // Allow bindings to read properties. Requires PropertyPermission read in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ implementationProvider.stop();
+ return null;
+ }
+ });
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ for (PolicyProvider policyProvider : ((RuntimeComponent)component).getPolicyProviders()) {
+ try {
+ policyProvider.stop();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ }
+
+ if (component instanceof ScopedRuntimeComponent) {
+ ScopedRuntimeComponent runtimeComponent = (ScopedRuntimeComponent)component;
+ if (runtimeComponent.getScopeContainer() != null &&
+ runtimeComponent.getScopeContainer().getLifecycleState() != ScopeContainer.STOPPED) {
+ try {
+ runtimeComponent.getScopeContainer().stop();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ }
+
+ ((RuntimeComponent)component).setStarted(false);
+ }
+
+
+ // Scope container start/stop
+ // separate off from component start that all endpoints are
+ // registered before any @EagerInit takes place
+ public void start(CompositeContext compositeContext, ScopedRuntimeComponent scopedRuntimeComponent) {
+ if (scopedRuntimeComponent.getScopeContainer() != null) {
+ try {
+ scopedRuntimeComponent.getScopeContainer().start();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StartException", ex);
+ rethrow(ex);
+ }
+ }
+ }
+
+ // Service start/stop
+
+ public void start(CompositeContext compositeContext, RuntimeEndpoint ep) {
+ startEndpoint(compositeContext, ep, null);
+ }
+
+ private void startEndpoint(CompositeContext compositeContext, RuntimeEndpoint ep, final List<RuntimeProvider> providers) {
+ // FIXME: Should the policy providers be started before the endpoint is started?
+ for (PolicyProvider policyProvider : ep.getPolicyProviders()) {
+ policyProvider.start();
+ if (providers != null) {
+ try {
+ providers.add(policyProvider);
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StartException", ex);
+ rethrow(ex);
+ }
+ }
+ }
+
+ final ServiceBindingProvider bindingProvider = ep.getBindingProvider();
+ if (bindingProvider != null) {
+ try {
+ // bindingProvider.start();
+ // Allow bindings to add shutdown hooks. Requires RuntimePermission shutdownHooks in policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ bindingProvider.start();
+ if (providers != null) {
+ providers.add(bindingProvider);
+ }
+ return null;
+ }
+ });
+ compositeContext.getEndpointRegistry().addEndpoint(ep);
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StartException", ex);
+ rethrow(ex);
+ }
+ }
+ }
+
+ public void stop(RuntimeEndpoint ep) {
+ ep.getCompositeContext().getEndpointRegistry().removeEndpoint(ep);
+ final ServiceBindingProvider bindingProvider = ep.getBindingProvider();
+ if (bindingProvider != null) {
+ try {
+ // Allow bindings to read properties. Requires PropertyPermission read in security policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ bindingProvider.stop();
+ return null;
+ }
+ });
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ for (PolicyProvider policyProvider : ep.getPolicyProviders()) {
+ try {
+ policyProvider.stop();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ }
+
+
+ // Reference start/stop
+
+ public void start(CompositeContext compositeContext, RuntimeComponent component, RuntimeComponentReference reference) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Starting component reference: " + component.getURI() + "#" + reference.getName());
+ }
+
+ for (EndpointReference endpointReference : reference.getEndpointReferences()){
+ RuntimeEndpointReference epr = (RuntimeEndpointReference)endpointReference;
+
+ // If the reference is already resolved then start it now. This currently
+ // important for async references which have native async bindings as the
+ // reference provider has to register a response listener regardless of
+ // whether the reference has been used or not.
+ if (epr.getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED ||
+ epr.getStatus() == EndpointReference.Status.RESOLVED_BINDING){
+
+ // As we only care about starting references at build time in the
+ // async case at the moment check that the binding supports native async
+ // and that the reference is an async reference
+ ReferenceBindingProvider bindingProvider = epr.getBindingProvider();
+ if (bindingProvider instanceof EndpointReferenceAsyncProvider &&
+ ((EndpointReferenceAsyncProvider)bindingProvider).supportsNativeAsync() &&
+ epr.isAsyncInvocation()){
+ // it's resolved so start it now
+ try {
+ // The act of getting invocation chains starts the reference in the late binding case
+ // so just use that here
+ epr.getInvocationChains();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StartException", ex);
+ rethrow(ex);
+ }
+ }
+ }
+ }
+ }
+
+ public void stop(Component component, ComponentReference reference) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Stopping component reference: " + component.getURI() + "#" + reference.getName());
+ }
+ RuntimeComponentReference runtimeRef = ((RuntimeComponentReference)reference);
+ for ( EndpointReference endpointReference : runtimeRef.getEndpointReferences()){
+ RuntimeEndpointReference epr = (RuntimeEndpointReference) endpointReference;
+ stop(epr);
+ }
+ }
+
+ @Deprecated
+ public void start(CompositeContext compositeContext, RuntimeEndpointReference endpointReference) {
+ compositeContext.getEndpointRegistry().addEndpointReference(endpointReference);
+
+ // The act of getting invocation chains starts the reference in the late binding case
+ // so just use that here
+ endpointReference.getInvocationChains();
+ }
+
+ public void stop(RuntimeEndpointReference epr) {
+ if (epr.isStarted()) {
+ CompositeContext compositeContext = epr.getCompositeContext();
+ if (compositeContext == null) {
+ throw new IllegalStateException("The endpoint reference is not bound");
+ }
+ compositeContext.getEndpointRegistry().removeEndpointReference(epr);
+ ReferenceBindingProvider bindingProvider = epr.getBindingProvider();
+ if (bindingProvider != null) {
+ try {
+ bindingProvider.stop();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ for (PolicyProvider policyProvider : epr.getPolicyProviders()) {
+ try {
+ policyProvider.stop();
+ } catch (Throwable ex){
+ Monitor.error(monitor, this, "core-messages", "StopException", ex);
+ }
+ }
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/DomainRegistryImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/DomainRegistryImpl.java
new file mode 100644
index 0000000000..21e1e4cf38
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/DomainRegistryImpl.java
@@ -0,0 +1,285 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.LifeCycleListener;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.runtime.BaseDomainRegistry;
+import org.apache.tuscany.sca.runtime.ContributionDescription;
+import org.apache.tuscany.sca.runtime.ContributionListener;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.EndpointListener;
+import org.apache.tuscany.sca.runtime.RuntimeProperties;
+
+/**
+ * A DomainRegistry implementation that sees registrations from the same JVM
+ */
+public class DomainRegistryImpl extends BaseDomainRegistry implements DomainRegistry, LifeCycleListener {
+ private final Logger logger = Logger.getLogger(DomainRegistryImpl.class.getName());
+
+ private List<Endpoint> endpoints = new ArrayList<Endpoint>();
+ private Map<String, Map<String, Composite>> runningComposites = new HashMap<String, Map<String, Composite>>();
+ private Map<String, ContributionDescription> contributionDescriptions = new HashMap<String, ContributionDescription>();
+
+ protected boolean quietLogging;
+
+ public DomainRegistryImpl(ExtensionPointRegistry extensionPoints, String endpointRegistryURI, String domainURI) {
+ super(extensionPoints, null, endpointRegistryURI, domainURI);
+ Properties runtimeProps = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ quietLogging = Boolean.parseBoolean(runtimeProps.getProperty(RuntimeProperties.QUIET_LOGGING));
+ }
+
+ public synchronized void addEndpoint(Endpoint endpoint) {
+ endpoints.add(endpoint);
+ for (EndpointListener listener : listeners) {
+ listener.endpointAdded(endpoint);
+ }
+ if (logger.isLoggable(quietLogging ? Level.FINE : Level.INFO)) {
+ String uri = null;
+ Binding b = endpoint.getBinding();
+ if (b != null) {
+ uri = b.getURI();
+ if (uri != null && uri.startsWith("/")) {
+ uri = uri.substring(1);
+ }
+ }
+ String msg = "Add endpoint - " + (uri == null ? endpoint.getURI() : b.getType().getLocalPart()+" - " + uri);
+ if (quietLogging) {
+ logger.fine(msg);
+ } else {
+ logger.info(msg);
+ }
+ }
+ }
+
+ public List<Endpoint> findEndpoint(String uri) {
+ List<Endpoint> foundEndpoints = new ArrayList<Endpoint>();
+ for (Endpoint endpoint : endpoints) {
+ if (endpoint.matches(uri)) {
+ foundEndpoints.add(endpoint);
+ logger.fine("Found endpoint with matching service - " + endpoint);
+ }
+ // else the service name doesn't match
+ }
+ return foundEndpoints;
+ }
+
+ public synchronized void removeEndpoint(Endpoint endpoint) {
+ endpoints.remove(endpoint);
+ endpointRemoved(endpoint);
+ if (logger.isLoggable(quietLogging ? Level.FINE : Level.INFO)) {
+ String uri = null;
+ Binding b = endpoint.getBinding();
+ if (b != null) {
+ uri = b.getURI();
+ if (uri != null && uri.startsWith("/")) {
+ uri = uri.substring(1);
+ }
+ }
+ String msg = "Remove endpoint - " + (uri == null ? endpoint.getURI() : b.getType().getLocalPart()+" - "+uri);
+ if (quietLogging) {
+ logger.fine(msg);
+ } else {
+ logger.info(msg);
+ }
+ }
+ }
+
+ public synchronized List<Endpoint> getEndpoints() {
+ return endpoints;
+ }
+
+ public synchronized Endpoint getEndpoint(String uri) {
+ for (Endpoint ep : endpoints) {
+ String epURI =
+ ep.getComponent().getURI() + "#" + ep.getService().getName() + "/" + ep.getBinding().getName();
+ if (epURI.equals(uri)) {
+ return ep;
+ }
+ if (ep.getBinding().getName() == null || ep.getBinding().getName().equals(ep.getService().getName())) {
+ epURI = ep.getComponent().getURI() + "#" + ep.getService().getName();
+ if (epURI.equals(uri)) {
+ return ep;
+ }
+ }
+ }
+ return null;
+
+ }
+
+ public synchronized void updateEndpoint(String uri, Endpoint endpoint) {
+ Endpoint oldEndpoint = getEndpoint(uri);
+ if (oldEndpoint == null) {
+ throw new IllegalArgumentException("Endpoint is not found: " + uri);
+ }
+ endpoints.remove(oldEndpoint);
+ endpoints.add(endpoint);
+ for (EndpointListener listener : listeners) {
+ listener.endpointUpdated(oldEndpoint, endpoint);
+ }
+ }
+
+ public synchronized void start() {
+ }
+
+ public synchronized void stop() {
+ for (Iterator<Endpoint> i = endpoints.iterator(); i.hasNext();) {
+ Endpoint ep = i.next();
+ i.remove();
+ endpointRemoved(ep);
+ }
+ endpointreferences.clear();
+ listeners.clear();
+ }
+
+ public void addRunningComposite(String curi, Composite composite) {
+ Map<String, Composite> cs = runningComposites.get(curi);
+ if (cs == null) {
+ cs = new HashMap<String, Composite>();
+ runningComposites.put(curi, cs);
+ }
+ cs.put(composite.getURI(), composite);
+ }
+
+ public void removeRunningComposite(String curi, String compositeURI) {
+ Map<String, Composite> cs = runningComposites.get(curi);
+ if (cs != null) {
+ cs.remove(compositeURI);
+ }
+ }
+
+ public Composite getRunningComposite(String curi, String compositeURI) {
+ Map<String, Composite> cs = runningComposites.get(curi);
+ if (cs != null) {
+ return cs.get(compositeURI);
+ }
+ return null;
+ }
+
+ public Map<String, List<String>> getRunningCompositeURIs() {
+ Map<String, List<String>> compositeURIs = new HashMap<String, List<String>>();
+ for (String curi : runningComposites.keySet()) {
+ if (runningComposites.get(curi).size() > 0) {
+ List<String> uris = new ArrayList<String>();
+ compositeURIs.put(curi, uris);
+ for (String uri : runningComposites.get(curi).keySet()) {
+ uris.add(uri);
+ }
+ }
+ }
+ return compositeURIs;
+ }
+
+ public void installContribution(ContributionDescription cd) {
+ contributionDescriptions.put(cd.getURI(), cd);
+ for (ContributionListener listener : contributionlisteners) {
+ listener.contributionInstalled(cd.getURI());
+ }
+ }
+
+ public void uninstallContribution(String uri) {
+ // TUSCANY-4025 - iterate through this list in reverse
+ // in the expectation that a node listener
+ // will appear in the list before and other
+ // listener that appears in the list and which
+ // relies on the node still have the contribution
+ // information.
+ ListIterator<ContributionListener> listenerIterator = contributionlisteners.listIterator(contributionlisteners.size());
+ while (listenerIterator.hasPrevious()) {
+ ContributionListener listener = listenerIterator.previous();
+ listener.contributionRemoved(uri);
+ }
+ contributionDescriptions.remove(uri);
+ }
+
+ public List<String> getInstalledContributionURIs() {
+ return new ArrayList<String>(contributionDescriptions.keySet());
+ }
+
+ public ContributionDescription getInstalledContribution(String uri) {
+ return contributionDescriptions.get(uri);
+ }
+
+ @Override
+ public void updateInstalledContribution(ContributionDescription cd) {
+ contributionDescriptions.put(cd.getURI(), cd);
+ for (ContributionListener listener : contributionlisteners) {
+ listener.contributionUpdated(cd.getURI());
+ }
+ }
+
+ private static final String LOCAL_MEMBER_NAME = "LocalOnly";
+ @Override
+ public List<String> getNodeNames() {
+ return Arrays.asList(new String[]{LOCAL_MEMBER_NAME});
+ }
+
+ @Override
+ public String getLocalNodeName() {
+ return LOCAL_MEMBER_NAME;
+ }
+
+ @Override
+ public String getRunningNodeName(String contributionURI, String compositeURI) {
+ if (getRunningComposite(contributionURI, compositeURI) != null) {
+ return LOCAL_MEMBER_NAME;
+ }
+ return null;
+ }
+
+ @Override
+ public String remoteCommand(String memberName, Callable<String> command) {
+ // TODO or should it just ensure the member name is LocalOnly and the run the command locally?
+ throw new IllegalStateException("not supportted for " + LOCAL_MEMBER_NAME);
+ }
+
+ @Override
+ public String getContainingCompositesContributionURI(String componentName) {
+ for (Map<String, Composite> cs : runningComposites.values()) {
+ for (Composite c : cs.values()) {
+ if (c.getComponent(componentName) != null) {
+ return c.getContributionURI();
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isDistributed() {
+ return false;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointSerializerImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointSerializerImpl.java
new file mode 100644
index 0000000000..8cdb0363e9
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/EndpointSerializerImpl.java
@@ -0,0 +1,198 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.context.CompositeContext;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.definitions.Definitions;
+import org.apache.tuscany.sca.policy.BindingType;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.util.PolicyHelper;
+import org.apache.tuscany.sca.runtime.EndpointSerializer;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+public class EndpointSerializerImpl implements EndpointSerializer {
+ private ExtensionPointRegistry registry;
+ private XMLInputFactory inputFactory;
+ private XMLOutputFactory outputFactory;
+ private StAXArtifactProcessor<Endpoint> processor;
+ private StAXArtifactProcessor<EndpointReference> refProcessor;
+
+ public EndpointSerializerImpl(ExtensionPointRegistry registry) {
+ this.registry = registry;
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ inputFactory = factories.getFactory(XMLInputFactory.class);
+ outputFactory = factories.getFactory(XMLOutputFactory.class);
+ StAXArtifactProcessorExtensionPoint processors =
+ registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ processor = processors.getProcessor(Endpoint.class);
+ refProcessor = processors.getProcessor(EndpointReference.class);
+ }
+
+ public Endpoint readEndpoint(String xml) {
+ try {
+ //System.out.println("Read Endpoint string >> " + xml);
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(xml));
+ Endpoint result = processor.read(reader, new ProcessorContext(registry));
+ result.setRemote(true);
+ reader.close();
+ return result;
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public void resolveEndpoint(Endpoint endpoint) {
+ CompositeContext compositeContext = ((RuntimeEndpoint)endpoint).getCompositeContext();
+
+ if (compositeContext == null){
+ // will be null if this is the SCAClient
+ return;
+ }
+
+ Definitions systemDefinitions = compositeContext.getSystemDefinitions();
+ if (systemDefinitions != null){
+ // Find pre-resolved intents from the system definition
+ List<Intent> intents = new ArrayList<Intent>();
+
+ for (Intent intent : endpoint.getRequiredIntents()){
+ Intent resolvedIntent = PolicyHelper.getIntent(systemDefinitions, intent.getName());
+
+ if (resolvedIntent != null){
+ intents.add(resolvedIntent);
+ } else {
+ // look to see if this intent is provided by the binding
+ BindingType bindingType = systemDefinitions.getBindingType(endpoint.getBinding().getType());
+
+ if (bindingType != null){
+ for (Intent apIntent : bindingType.getAlwaysProvidedIntents()){
+ if (apIntent.getName().equals(intent.getName())){
+ resolvedIntent = apIntent;
+ break;
+ }
+ }
+
+ if (resolvedIntent == null){
+ for (Intent mpIntent : bindingType.getMayProvidedIntents()){
+ if (mpIntent.getName().equals(intent.getName())){
+ resolvedIntent = mpIntent;
+ break;
+ }
+ }
+ }
+ }
+
+ if (resolvedIntent != null){
+ intents.add(resolvedIntent);
+ } else {
+ throw new ServiceRuntimeException("Remote endpoint " +
+ endpoint +
+ " has intent " +
+ intent +
+ " that can't be found in the local system definitions in node " +
+ compositeContext.getNodeURI());
+ }
+ }
+ }
+
+ endpoint.getRequiredIntents().clear();
+ endpoint.getRequiredIntents().addAll(intents);
+
+ // Find pre-resolved policy sets from the system definition
+ List<PolicySet> policySets = new ArrayList<PolicySet>();
+
+ for (PolicySet policySet : endpoint.getPolicySets()){
+ PolicySet resolvedPolicySet = PolicyHelper.getPolicySet(systemDefinitions, policySet.getName());
+ if (resolvedPolicySet != null){
+ policySets.add(resolvedPolicySet);
+ } else {
+ throw new ServiceRuntimeException("Remote endpoint " +
+ endpoint +
+ " has policy set " +
+ policySet +
+ " that can't be found in the local system definitions in node " +
+ compositeContext.getNodeURI());
+ }
+ }
+
+ endpoint.getPolicySets().clear();
+ endpoint.getPolicySets().addAll(policySets);
+ }
+ }
+
+ public String write(Endpoint endpoint) {
+ StringWriter sw = new StringWriter();
+ try {
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(sw);
+ processor.write(endpoint, writer, new ProcessorContext(registry));
+ writer.flush();
+ writer.close();
+ String endpointString = sw.toString();
+ //System.out.println("Write Endpoint string >> " + endpointString);
+ return endpointString;
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public EndpointReference readEndpointReference(String xml) {
+ try {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(xml));
+ EndpointReference result = refProcessor.read(reader, new ProcessorContext(registry));
+ reader.close();
+ return result;
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public String write(EndpointReference endpointReference) {
+ StringWriter sw = new StringWriter();
+ try {
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(sw);
+ refProcessor.write(endpointReference, writer, new ProcessorContext(registry));
+ writer.flush();
+ writer.close();
+ return sw.toString();
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/LocalDomainRegistryFactory.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/LocalDomainRegistryFactory.java
new file mode 100644
index 0000000000..002eb774ef
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/LocalDomainRegistryFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core.assembly.impl;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.runtime.BaseDomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+
+/**
+ * The utility responsible for finding the endpoint regstry by the scheme and creating instances for the
+ * given domain
+ */
+public class LocalDomainRegistryFactory extends BaseDomainRegistryFactory {
+ private final static String[] schemes = new String[] {"local", "vm"};
+
+ /**
+ * @param extensionRegistry
+ */
+ public LocalDomainRegistryFactory(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ protected DomainRegistry createEndpointRegistry(String endpointRegistryURI, String domainURI) {
+ DomainRegistry domainRegistry =
+ new DomainRegistryImpl(registry, endpointRegistryURI, domainURI);
+ return domainRegistry;
+ }
+
+ public String[] getSupportedSchemes() {
+ return schemes;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParameterProcessor.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParameterProcessor.java
new file mode 100644
index 0000000000..4d6a98ca5f
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParameterProcessor.java
@@ -0,0 +1,98 @@
+/*
+ * 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.core.assembly.impl;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
+
+/**
+ * Artifact processor for reference parameters.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReferenceParameterProcessor implements StAXArtifactProcessor<ReferenceParameters> {
+ private static final QName REFERENCE_PARAMETERS =
+ new QName("http://tuscany.apache.org/xmlns/sca/1.1", "referenceParameters", "tuscany");
+
+ /**
+ * Constructs a new processor.
+ *
+ * @param modelFactories
+ */
+ public ReferenceParameterProcessor(FactoryExtensionPoint modelFactories) {
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#getArtifactType()
+ */
+ public QName getArtifactType() {
+ return REFERENCE_PARAMETERS;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#read(javax.xml.stream.XMLStreamReader, ProcessorContext)
+ */
+ public ReferenceParameters read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
+ ReferenceParameters parameters = new ReferenceParametersImpl();
+ parameters.setCallbackID(reader.getAttributeValue(null, "callbackID"));
+ return parameters;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor#write(java.lang.Object, javax.xml.stream.XMLStreamWriter, ProcessorContext)
+ */
+ public void write(ReferenceParameters model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException,
+ XMLStreamException {
+ writer.writeStartElement(REFERENCE_PARAMETERS.getPrefix(),
+ REFERENCE_PARAMETERS.getLocalPart(),
+ REFERENCE_PARAMETERS.getNamespaceURI());
+ writer.writeNamespace(REFERENCE_PARAMETERS.getPrefix(), REFERENCE_PARAMETERS.getNamespaceURI());
+
+ if (model.getCallbackID() != null) {
+ writer.writeAttribute("callbackID", model.getCallbackID().toString());
+ }
+ writer.writeEndElement();
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.contribution.processor.ArtifactProcessor#getModelType()
+ */
+ public Class<ReferenceParameters> getModelType() {
+ return ReferenceParameters.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.contribution.processor.ArtifactProcessor#resolve(java.lang.Object, org.apache.tuscany.sca.contribution.resolver.ModelResolver, ProcessorContext)
+ */
+ public void resolve(ReferenceParameters model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParametersImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParametersImpl.java
new file mode 100644
index 0000000000..7bd56271a5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/ReferenceParametersImpl.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.core.assembly.impl;
+
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.runtime.ReferenceParameters;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ReferenceParametersImpl implements ReferenceParameters {
+ private Object callbackID;
+ private EndpointReference callbackReference;
+ private Object callbackObjectID;
+
+ /**
+ * @return the callbackID
+ */
+ public Object getCallbackID() {
+ return callbackID;
+ }
+ /**
+ * @param callbackID the callbackID to set
+ */
+ public void setCallbackID(Object callbackID) {
+ this.callbackID = callbackID;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.runtime.ReferenceParameters#getCallbackReference()
+ */
+ public EndpointReference getCallbackReference() {
+ return callbackReference;
+ }
+ /**
+ * @see org.apache.tuscany.sca.runtime.ReferenceParameters#setCallback(java.lang.Object)
+ */
+ public void setCallbackReference(EndpointReference callback) {
+ this.callbackReference = callback;
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ /**
+ * @return the callbackObjectID
+ */
+ public Object getCallbackObjectID() {
+ return callbackObjectID;
+ }
+ /**
+ * @param callbackObjectID the callbackObjectID to set
+ */
+ public void setCallbackObjectID(Object callbackObjectID) {
+ this.callbackObjectID = callbackObjectID;
+ }
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((callbackID == null) ? 0 : callbackID.hashCode());
+ result = prime * result + ((callbackObjectID == null) ? 0 : callbackObjectID.hashCode());
+ result = prime * result + ((callbackReference == null) ? 0 : callbackReference.hashCode());
+ return result;
+ }
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ReferenceParametersImpl))
+ return false;
+ final ReferenceParametersImpl other = (ReferenceParametersImpl)obj;
+ if (callbackID == null) {
+ if (other.callbackID != null)
+ return false;
+ } else if (!callbackID.equals(other.callbackID))
+ return false;
+ if (callbackObjectID == null) {
+ if (other.callbackObjectID != null)
+ return false;
+ } else if (!callbackObjectID.equals(other.callbackObjectID))
+ return false;
+ if (callbackReference == null) {
+ if (other.callbackReference != null)
+ return false;
+ } else if (!callbackReference.equals(other.callbackReference))
+ return false;
+
+ return true;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentImpl.java
new file mode 100644
index 0000000000..a78cf6057e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentImpl.java
@@ -0,0 +1,139 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+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.impl.ComponentImpl;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
+import org.apache.tuscany.sca.core.scope.ScopeContainer;
+import org.apache.tuscany.sca.core.scope.ScopedRuntimeComponent;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.PolicyProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RuntimeComponentImpl extends ComponentImpl implements RuntimeComponent,
+ ScopedRuntimeComponent, ResolverExtension {
+ protected RuntimeComponentContext componentContext;
+ protected ImplementationProvider implementationProvider;
+ protected List<PolicyProvider> policyProviders = new ArrayList<PolicyProvider>();
+ protected ScopeContainer scopeContainer;
+ protected boolean started;
+ protected ModelResolver modelResolver;
+
+ /**
+ */
+ public RuntimeComponentImpl() {
+ super();
+ }
+
+ public ImplementationProvider getImplementationProvider() {
+ return implementationProvider;
+ }
+
+ public void setImplementationProvider(ImplementationProvider provider) {
+ this.implementationProvider = provider;
+ }
+
+ public ScopeContainer getScopeContainer() {
+ return scopeContainer;
+ }
+
+ public void setScopeContainer(ScopeContainer scopeContainer) {
+ this.scopeContainer = scopeContainer;
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public void setStarted(boolean started) {
+ this.started = started;
+ }
+
+ /**
+ * @return the componentContext
+ */
+ public RuntimeComponentContext getComponentContext() {
+ return componentContext;
+ }
+
+ /**
+ * @param componentContext the componentContext to set
+ */
+ public void setComponentContext(RuntimeComponentContext componentContext) {
+ this.componentContext = componentContext;
+ }
+
+ public void addPolicyProvider(PolicyProvider policyProvider) {
+ policyProviders.add(policyProvider);
+ }
+
+ public List<PolicyProvider> getPolicyProviders() {
+ return policyProviders;
+ }
+
+ public ModelResolver getModelResolver() {
+ return modelResolver;
+ }
+
+ public void setModelResolver(ModelResolver modelResolver) {
+ this.modelResolver = modelResolver;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+
+ @Override
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String serviceName) {
+ RuntimeComponentContext componentContext = null;
+
+ // TUSCANY-3904 Removed implementation.composite path
+
+ componentContext = getComponentContext();
+ if (serviceName != null) {
+ return componentContext.createSelfReference(businessInterface, serviceName);
+ } else {
+ return componentContext.createSelfReference(businessInterface);
+ }
+
+ }
+
+ // TUSCANY-3988
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeComponentImpl clone = (RuntimeComponentImpl)super.clone();
+ clone.policyProviders = new ArrayList<PolicyProvider>();
+ return clone;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentReferenceImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentReferenceImpl.java
new file mode 100644
index 0000000000..2eea60ccea
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentReferenceImpl.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.core.assembly.impl;
+
+import org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+
+/**
+ * Implementation of a Component Reference.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeComponentReferenceImpl extends ComponentReferenceImpl implements RuntimeComponentReference {
+
+ private RuntimeComponent component;
+
+ public RuntimeComponentReferenceImpl() {
+ super();
+ }
+
+ /**
+ * @return the component
+ */
+ public RuntimeComponent getComponent() {
+ return component;
+ }
+
+ /**
+ * @param component the component to set
+ */
+ public void setComponent(RuntimeComponent component) {
+ this.component = component;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.assembly.impl.ComponentReferenceImpl#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeComponentReferenceImpl ref = (RuntimeComponentReferenceImpl)super.clone();
+ return ref;
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentServiceImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentServiceImpl.java
new file mode 100644
index 0000000000..bc7e6df878
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeComponentServiceImpl.java
@@ -0,0 +1,40 @@
+/*
+ * 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.core.assembly.impl;
+
+import org.apache.tuscany.sca.assembly.impl.ComponentServiceImpl;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Implementation of a Component Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeComponentServiceImpl extends ComponentServiceImpl implements RuntimeComponentService {
+
+ public RuntimeComponentServiceImpl() {
+ super();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java
new file mode 100644
index 0000000000..09cbab76d1
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointImpl.java
@@ -0,0 +1,1285 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.wsdl.Definition;
+import javax.wsdl.WSDLException;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLWriter;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.CompositeReference;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.builder.BindingBuilder;
+import org.apache.tuscany.sca.assembly.builder.BuilderContext;
+import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint;
+import org.apache.tuscany.sca.assembly.impl.EndpointImpl;
+import org.apache.tuscany.sca.assembly.xml.InterfaceContractProcessor;
+import org.apache.tuscany.sca.context.CompositeContext;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistryLocator;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;
+import org.apache.tuscany.sca.core.invocation.AsyncResponseService;
+import org.apache.tuscany.sca.core.invocation.Constants;
+import org.apache.tuscany.sca.core.invocation.ExtensibleWireProcessor;
+import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
+import org.apache.tuscany.sca.core.invocation.RuntimeInvoker;
+import org.apache.tuscany.sca.core.invocation.impl.InvocationChainImpl;
+import org.apache.tuscany.sca.core.invocation.impl.PhaseManager;
+import org.apache.tuscany.sca.interfacedef.Compatibility;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InterceptorAsync;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.InvokerAsyncResponse;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.provider.BindingProviderFactory;
+import org.apache.tuscany.sca.provider.EndpointAsyncProvider;
+import org.apache.tuscany.sca.provider.EndpointProvider;
+import org.apache.tuscany.sca.provider.ImplementationAsyncProvider;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.OptimisingBindingProvider;
+import org.apache.tuscany.sca.provider.PolicyProvider;
+import org.apache.tuscany.sca.provider.PolicyProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.DomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.EndpointSerializer;
+import org.apache.tuscany.sca.runtime.ExtensibleDomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.apache.tuscany.sca.xsd.XSDefinition;
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaImport;
+import org.apache.ws.commons.schema.XmlSchemaInclude;
+import org.apache.ws.commons.schema.XmlSchemaObject;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Runtime model for Endpoint that supports java serialization
+ */
+public class RuntimeEndpointImpl extends EndpointImpl implements RuntimeEndpoint, Externalizable {
+ private static final long serialVersionUID = 1L;
+ private static final byte separator[] = {'_', 'X', '_'};
+
+ private transient CompositeContext compositeContext;
+ private transient RuntimeWireProcessor wireProcessor;
+ private transient ProviderFactoryExtensionPoint providerFactories;
+ private transient InterfaceContractMapper interfaceContractMapper;
+ private transient WorkScheduler workScheduler;
+ private transient PhaseManager phaseManager;
+ private transient MessageFactory messageFactory;
+ private transient RuntimeInvoker invoker;
+ private transient EndpointSerializer serializer;
+
+ private transient List<InvocationChain> chains;
+ private transient Map<Operation, InvocationChain> invocationChainMap =
+ new ConcurrentHashMap<Operation, InvocationChain>();
+ private transient InvocationChain bindingInvocationChain;
+
+ private transient ServiceBindingProvider bindingProvider;
+ private transient List<PolicyProvider> policyProviders;
+ private String xml;
+ private String interfaceContractXML;
+
+ protected InterfaceContract bindingInterfaceContract;
+ protected InterfaceContract serviceInterfaceContract;
+
+ private RuntimeEndpoint delegateEndpoint;
+
+ /**
+ * No-arg constructor for Java serialization
+ */
+ public RuntimeEndpointImpl() {
+ super(null);
+ }
+
+ public RuntimeEndpointImpl(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ protected void copyFrom(RuntimeEndpointImpl copy) {
+ this.xml = copy.xml;
+
+ this.component = copy.component;
+ this.service = copy.service;
+ this.interfaceContract = copy.interfaceContract;
+ this.serviceInterfaceContract = copy.serviceInterfaceContract;
+
+ this.binding = copy.binding;
+ this.bindingInterfaceContract = copy.interfaceContract;
+ this.bindingInvocationChain = copy.bindingInvocationChain;
+
+ this.callbackEndpointReferences = copy.callbackEndpointReferences;
+
+ this.requiredIntents = copy.requiredIntents;
+ this.policySets = copy.policySets;
+
+ this.uri = copy.uri;
+ this.remote = copy.remote;
+ this.unresolved = copy.unresolved;
+
+ this.chains = copy.chains;
+ this.invocationChainMap = copy.invocationChainMap;
+ this.bindingProvider = copy.bindingProvider;
+ this.policyProviders = copy.policyProviders;
+
+ if (this.compositeContext == null && copy.compositeContext != null) {
+ bind(copy.compositeContext);
+ }
+ }
+
+ public void bind(CompositeContext compositeContext) {
+ this.compositeContext = compositeContext;
+ bind(compositeContext.getExtensionPointRegistry(), compositeContext.getEndpointRegistry());
+ }
+
+ public void bind(ExtensionPointRegistry registry, DomainRegistry domainRegistry) {
+ if (compositeContext == null) {
+ compositeContext = new CompositeContext(registry, domainRegistry);
+ }
+
+ // if interfaceContractMapper is already initialized then all the rest will be too
+ if (interfaceContractMapper != null) {
+ return;
+ }
+ this.registry = registry;
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+ this.workScheduler = utilities.getUtility(WorkScheduler.class);
+ this.wireProcessor =
+ new ExtensibleWireProcessor(registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class));
+
+ this.messageFactory = registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(MessageFactory.class);
+ this.invoker = new RuntimeInvoker(registry, this);
+
+ this.phaseManager = utilities.getUtility(PhaseManager.class);
+ this.serializer = utilities.getUtility(EndpointSerializer.class);
+ this.providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+ this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class);
+ this.contractBuilder = builders.getContractBuilder();
+ }
+
+ public void unbind() {
+ compositeContext = null;
+ bindingInvocationChain = null;
+ chains = null;
+ bindingProvider = null;
+ policyProviders = null;
+ invocationChainMap.clear();
+ }
+
+ public synchronized List<InvocationChain> getInvocationChains() {
+ if (chains == null) {
+ initInvocationChains();
+ }
+ return chains;
+ }
+
+ public synchronized InvocationChain getBindingInvocationChain() {
+ if (bindingInvocationChain == null) {
+ bindingInvocationChain = new InvocationChainImpl(null, null, false, phaseManager, isAsyncInvocation());
+ initServiceBindingInvocationChains();
+ }
+
+ // Init the operation invocation chains now. We know they will
+ // be needed as well as the binding invocation chain and this
+ // makes the wire processors run
+ getInvocationChains();
+
+ return bindingInvocationChain;
+ }
+
+ /**
+ * A dummy invocation chain representing null as ConcurrentHashMap doesn't allow null values
+ */
+ private static final InvocationChain NULL_CHAIN = new InvocationChainImpl(null, null, false, null, false);
+
+ public InvocationChain getInvocationChain(Operation operation) {
+ InvocationChain cached = invocationChainMap.get(operation);
+ if (cached == null) {
+ for (InvocationChain chain : getInvocationChains()) {
+ Operation op = chain.getTargetOperation();
+
+ // We used to check compatibility here but this is now validated when the
+ // chain is created. As the chain operations are the real interface types
+ // they may be incompatible just because they are described in different
+ // IDLs
+ if (operation.getInterface().isRemotable()) {
+ if (operation.getName().equals(op.getName())) {
+ invocationChainMap.put(operation, chain);
+ return chain;
+ }
+ if (interfaceContractMapper.isCompatible(operation, op, Compatibility.SUBSET)) {
+ invocationChainMap.put(operation, chain);
+ return chain;
+ }
+ } else {
+ // [rfeng] We need to run the compatibility check for local operations as they
+ // can be overloaded
+ if (interfaceContractMapper.isCompatible(operation, op, Compatibility.SUBSET)) {
+ invocationChainMap.put(operation, chain);
+ return chain;
+ }
+ }
+ }
+ // Cache it with the NULL_CHAIN to avoid NPE
+ invocationChainMap.put(operation, NULL_CHAIN);
+ return null;
+ } else {
+ if (cached == NULL_CHAIN) {
+ cached = null;
+ }
+ return cached;
+ }
+ }
+
+ public Message invoke(Message msg) {
+ // Deal with async callback
+ // Ensure invocation chains are built...
+ getInvocationChains();
+ // async callback handling
+ if( this.isAsyncInvocation() && !this.getCallbackEndpointReferences().isEmpty() ) {
+ RuntimeEndpointReference asyncEPR = (RuntimeEndpointReference) this.getCallbackEndpointReferences().get(0);
+ // Place a link to the callback EPR into the message headers...
+ msg.getHeaders().put(Constants.ASYNC_CALLBACK, asyncEPR );
+ }
+ // end of async callback handling
+ return invoker.invokeBinding(msg);
+ }
+
+ public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
+ return invoker.invoke(operation, args);
+ }
+
+ public Message invoke(Operation operation, Message msg) {
+ return invoker.invoke(operation, msg);
+ }
+
+ public void invokeAsync(Message msg){
+ invoker.invokeBindingAsync(msg);
+ } // end method invokeAsync(Message)
+
+ public void invokeAsync(Operation operation, Message msg){
+ msg.setOperation(operation);
+ invoker.invokeAsync(msg);
+ } // end method invokeAsync(Operation, Message)
+
+ public void invokeAsyncResponse(Message msg){
+ resolve();
+ invoker.invokeAsyncResponse(msg);
+ }
+
+ /**
+ * Navigate the component/componentType inheritance chain to find the leaf contract
+ * @param contract
+ * @return
+ */
+ private Contract getLeafContract(Contract contract) {
+ Contract prev = null;
+ Contract current = contract;
+ while (current != null) {
+ prev = current;
+ if (current instanceof ComponentReference) {
+ current = ((ComponentReference)current).getReference();
+ } else if (current instanceof CompositeReference) {
+ current = ((CompositeReference)current).getPromotedReferences().get(0);
+ } else if (current instanceof ComponentService) {
+ current = ((ComponentService)current).getService();
+ } else if (current instanceof CompositeService) {
+ current = ((CompositeService)current).getPromotedService();
+ } else {
+ break;
+ }
+ if (current == null) {
+ return prev;
+ }
+ }
+ return current;
+ }
+
+ /**
+ * Initialize the invocation chains
+ */
+ private void initInvocationChains() {
+ chains = new ArrayList<InvocationChain>();
+ InterfaceContract sourceContract = getBindingInterfaceContract();
+
+ // It's the service wire
+ RuntimeComponentService service = (RuntimeComponentService)getService();
+ RuntimeComponent serviceComponent = (RuntimeComponent)getComponent();
+
+ //InterfaceContract targetContract = getInterfaceContract();
+ // TODO - EPR - why is this looking at the component types. The endpoint should have the right interface contract by this time
+ InterfaceContract targetContract = getComponentTypeServiceInterfaceContract();
+ // setInterfaceContract(targetContract);
+ validateServiceInterfaceCompatibility();
+ for (Operation operation : sourceContract.getInterface().getOperations()) {
+ Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
+ if (targetOperation == null) {
+ throw new ServiceRuntimeException("No matching operation for " + operation.getName()
+ + " is found in service "
+ + serviceComponent.getURI()
+ + "#"
+ + service.getName());
+ }
+ InvocationChain chain = new InvocationChainImpl(operation, targetOperation, false, phaseManager, isAsyncInvocation());
+ if (operation.isNonBlocking()) {
+ addNonBlockingInterceptor(chain);
+ }
+ addServiceBindingInterceptor(chain, operation);
+ addImplementationInterceptor(serviceComponent, service, chain, targetOperation);
+ chains.add(chain);
+
+ // Handle cases where the operation is an async server
+ if( targetOperation.isAsyncServer() ) {
+ createAsyncServerCallback();
+ } // end if
+ }
+
+ wireProcessor.process(this);
+
+ // If we have to support async and there is no binding chain
+ // then set the response path to point directly to the
+ // binding provided async response handler
+ if (isAsyncInvocation() &&
+ bindingInvocationChain == null){
+ // fix up the operation chain response path to point back to the
+ // binding provided async response handler
+ ServiceBindingProvider serviceBindingProvider = getBindingProvider();
+ if (serviceBindingProvider instanceof EndpointAsyncProvider){
+ EndpointAsyncProvider asyncEndpointProvider = (EndpointAsyncProvider)serviceBindingProvider;
+ InvokerAsyncResponse asyncResponseInvoker = asyncEndpointProvider.createAsyncResponseInvoker();
+
+ for (InvocationChain chain : getInvocationChains()){
+ Invoker invoker = chain.getHeadInvoker();
+ if (invoker instanceof InterceptorAsync){
+ ((InterceptorAsync)invoker).setPrevious(asyncResponseInvoker);
+ } else {
+ //TODO - throw error once the old async code is removed
+ } // end if
+ } // end for
+ } else {
+ // TODO - throw error once the old async code is removed
+ } // end if
+ } // end if
+
+ ServiceBindingProvider provider = getBindingProvider();
+ if ((provider != null) && (provider instanceof OptimisingBindingProvider)) {
+ //TODO - remove this comment once optimisation codepath is tested
+ ((OptimisingBindingProvider)provider).optimiseBinding( this );
+ } // end if
+
+ } // end method initInvocationChains
+
+ /**
+ * Creates the async callback for this Endpoint, if it does not already exist
+ * and stores it into the Endpoint
+ */
+ public void createAsyncServerCallback( ) {
+ // No need to create a callback if the Binding supports async natively...
+ if( hasNativeAsyncBinding(this) ) return;
+
+ // Check to see if the callback already exists
+ if( asyncCallbackExists( this ) ) return;
+
+ RuntimeEndpointReference asyncEPR = createAsyncEPR( this );
+
+ // Store the new callback EPR into the Endpoint
+ this.getCallbackEndpointReferences().add(asyncEPR);
+
+ // Also store the callback EPR into the DomainRegistry
+ DomainRegistry epReg = getEndpointRegistry( registry );
+ if( epReg != null ) epReg.addEndpointReference(asyncEPR);
+ } // end method createAsyncServerCallback
+
+ public RuntimeEndpointReference getAsyncServerCallback() {
+
+ return (RuntimeEndpointReference) this.getCallbackEndpointReferences().get(0);
+ } // end method getAsyncServerCallback
+
+
+ /**
+ * Indicates if a given endpoint has a Binding that supports native async invocation
+ * @param endpoint - the endpoint
+ * @return - true if the endpoint has a binding that supports native async, false otherwise
+ */
+ private boolean hasNativeAsyncBinding(RuntimeEndpoint endpoint) {
+ ServiceBindingProvider provider = endpoint.getBindingProvider();
+ if( provider instanceof EndpointAsyncProvider ) {
+ EndpointAsyncProvider asyncProvider = (EndpointAsyncProvider) provider;
+ if( asyncProvider.supportsNativeAsync() ) return true;
+ } // end if
+ return false;
+ } // end method hasNativeAsyncBinding
+
+ /**
+ * Creates the Endpoint object for the async callback
+ * @param endpoint - the endpoint which has the async server operations
+ * @return the EndpointReference object representing the callback
+ */
+ private RuntimeEndpointReference createAsyncEPR( RuntimeEndpoint endpoint ){
+ CompositeContext compositeContext = endpoint.getCompositeContext();
+ RuntimeAssemblyFactory assemblyFactory = getAssemblyFactory( compositeContext );
+ RuntimeEndpointReference epr = (RuntimeEndpointReference)assemblyFactory.createEndpointReference();
+ epr.bind( compositeContext );
+
+ // Create pseudo-component
+ epr.setComponent(component);
+
+ // Create pseudo-reference
+ ComponentReference reference = assemblyFactory.createComponentReference();
+ ExtensionPointRegistry registry = compositeContext.getExtensionPointRegistry();
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ JavaInterfaceFactory javaInterfaceFactory = (JavaInterfaceFactory)modelFactories.getFactory(JavaInterfaceFactory.class);
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ try {
+ interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(AsyncResponseService.class));
+ } catch (InvalidInterfaceException e1) {
+ // Nothing to do here - will not happen
+ } // end try
+ reference.setInterfaceContract(interfaceContract);
+ String referenceName = endpoint.getService().getName() + "_asyncCallback";
+ reference.setName(referenceName);
+ reference.setForCallback(true);
+ // Add in "implementation" reference (really a dummy, but with correct interface)
+ Reference implReference = assemblyFactory.createReference();
+ implReference.setInterfaceContract(interfaceContract);
+ implReference.setName(referenceName);
+ implReference.setForCallback(true);
+
+ reference.setReference(implReference);
+ // Set the created ComponentReference into the EPR
+ epr.setReference(reference);
+
+ // Create a binding
+ Binding binding = createMatchingBinding( endpoint.getBinding(), (RuntimeComponent)endpoint.getComponent(), reference, registry );
+ epr.setBinding(binding);
+
+ // Need to establish policies here (binding has some...)
+ epr.getRequiredIntents().addAll( endpoint.getRequiredIntents() );
+ epr.getPolicySets().addAll( endpoint.getPolicySets() );
+
+ // Attach a dummy endpoint to the epr
+ RuntimeEndpoint ep = (RuntimeEndpoint)assemblyFactory.createEndpoint();
+ ep.setUnresolved(false);
+ epr.setTargetEndpoint(ep);
+ //epr.setStatus(EndpointReference.Status.RESOLVED_BINDING);
+ epr.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
+ epr.setUnresolved(false);
+
+ // Set the URI for the EPR
+ String eprURI = endpoint.getComponent().getName() + "#reference-binding(" + referenceName + "/" + referenceName + ")";
+ epr.setURI(eprURI);
+
+ return epr;
+ } // end method RuntimeEndpointReference
+
+ private boolean asyncCallbackExists( RuntimeEndpoint endpoint ) {
+ if( endpoint.getCallbackEndpointReferences().isEmpty() ) return false;
+ return true;
+ } // end method asyncCallbackExists
+
+ /**
+ * Create a matching binding to a supplied binding
+ * - the matching binding has the same binding type, but is for the supplied component and service
+ * @param matchBinding - the binding to match
+ * @param component - the component
+ * @param service - the service
+ * @param registry - registry for extensions
+ * @return - the matching binding, or null if it could not be created
+ */
+ @SuppressWarnings("unchecked")
+ private Binding createMatchingBinding( Binding matchBinding, RuntimeComponent component,
+ ComponentReference reference, ExtensionPointRegistry registry ) {
+ // Since there is no simple way to obtain a Factory for a binding where the type is not known ahead of
+ // time, the process followed here is to generate the <binding.xxx/> XML element from the binding type QName
+ // and then read the XML using the processor for that XML...
+ QName bindingName = matchBinding.getType();
+ String bindingXML = "<ns1:" + bindingName.getLocalPart() + " xmlns:ns1='" + bindingName.getNamespaceURI() + "'/>";
+
+ StAXArtifactProcessorExtensionPoint processors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(bindingName);
+
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ ValidatingXMLInputFactory inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class);
+ StreamSource source = new StreamSource( new StringReader(bindingXML) );
+
+ ProcessorContext context = new ProcessorContext();
+ try {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(source);
+ reader.next();
+ Binding newBinding = (Binding) processor.read(reader, context );
+ newBinding.setName(reference.getName());
+
+ // Create a URI address for the callback based on the Component_Name/Reference_Name pattern
+ //String callbackURI = "/" + component.getName() + "/" + reference.getName();
+ //newBinding.setURI(callbackURI);
+
+ BuilderExtensionPoint builders = registry.getExtensionPoint(BuilderExtensionPoint.class);
+ BindingBuilder builder = builders.getBindingBuilder(newBinding.getType());
+ if (builder != null) {
+ org.apache.tuscany.sca.assembly.builder.BuilderContext builderContext = new BuilderContext(registry);
+ builder.build(component, reference, newBinding, builderContext, true);
+ } // end if
+
+ return newBinding;
+ } catch (ContributionReadException e) {
+ e.printStackTrace();
+ } catch (XMLStreamException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ } // end method createMatchingBinding
+
+ /**
+ * Gets a RuntimeAssemblyFactory from the CompositeContext
+ * @param compositeContext
+ * @return the RuntimeAssemblyFactory
+ */
+ private RuntimeAssemblyFactory getAssemblyFactory( CompositeContext compositeContext ) {
+ ExtensionPointRegistry registry = compositeContext.getExtensionPointRegistry();
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ return (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class);
+ } // end method RuntimeAssemblyFactory
+
+ /**
+ * Check that endpoint has compatible interface at the component and binding ends.
+ * The user can specify the interfaces at both ends so there is a danger that they won't be compatible.
+ */
+ public void validateServiceInterfaceCompatibility() {
+
+ InterfaceContract serviceContract = getComponentServiceInterfaceContract();
+ InterfaceContract bindingContract = getBindingInterfaceContract();
+
+ if ((serviceContract != bindingContract) &&
+ (serviceContract != null) && (bindingContract != null)) {
+
+ boolean bindingHasCallback = bindingContract.getCallbackInterface() != null;
+
+ try {
+
+ // Use the normalized contract if the interface types are different or if
+ // a normalized contract has been previously generate, for example, by virtue
+ // of finding a JAXWS annotation on a Java class that references a WSDL file
+ if (serviceContract.getClass() != bindingContract.getClass() ||
+ serviceContract.getNormalizedWSDLContract() != null ||
+ bindingContract.getNormalizedWSDLContract() != null) {
+ interfaceContractMapper.checkCompatibility(getGeneratedWSDLContract(serviceContract),
+ getGeneratedWSDLContract(bindingContract),
+ Compatibility.SUBSET,
+ !bindingHasCallback, // ignore callbacks if binding doesn't have one
+ false);
+ } else {
+ interfaceContractMapper.checkCompatibility(serviceContract,
+ bindingContract,
+ Compatibility.SUBSET,
+ !bindingHasCallback, // ignore callbacks if binding doesn't have one
+ false);
+ }
+ } catch (Exception ex){
+ throw new ServiceRuntimeException("Component " +
+ this.getComponent().getName() +
+ " Service " +
+ getService().getName() +
+ " interface is incompatible with the interface of the service binding - " +
+ getBinding().getName() +
+ " - " +
+ ex.getMessage() +
+ " - [" + this.toString() + "]");
+ }
+ }
+
+ }
+
+ private void initServiceBindingInvocationChains() {
+
+ // add the binding interceptors to the service binding wire
+ ServiceBindingProvider provider = getBindingProvider();
+ if ((provider != null) && (provider instanceof EndpointProvider)) {
+ ((EndpointProvider)provider).configure();
+ }
+
+ // add the policy interceptors to the service binding wire
+ List<PolicyProvider> pps = getPolicyProviders();
+ if (pps != null) {
+ for (PolicyProvider p : pps) {
+ Interceptor interceptor = p.createBindingInterceptor();
+ if (interceptor != null) {
+ bindingInvocationChain.addInterceptor(interceptor);
+ } // end if
+ } // end for
+ } // end if
+
+ // This is strategically placed before the RuntimeInvoker is added to the end of the
+ // binding chain as the RuntimeInvoker doesn't need to take part in the response
+ // processing and doesn't implement InvokerAsyncResponse
+ ServiceBindingProvider serviceBindingProvider = getBindingProvider();
+ if (isAsyncInvocation() &&
+ serviceBindingProvider instanceof EndpointAsyncProvider &&
+ ((EndpointAsyncProvider)serviceBindingProvider).supportsNativeAsync()){
+ // fix up the invocation chains to point back to the
+ // binding chain so that async response messages
+ // are processed correctly
+ for (InvocationChain chain : getInvocationChains()){
+ Invoker invoker = chain.getHeadInvoker();
+ ((InterceptorAsync)invoker).setPrevious((InvokerAsyncResponse)bindingInvocationChain.getTailInvoker());
+ } // end for
+
+ // fix up the binding chain response path to point back to the
+ // binding provided async response handler
+ EndpointAsyncProvider asyncEndpointProvider = (EndpointAsyncProvider)serviceBindingProvider;
+ InvokerAsyncResponse asyncResponseInvoker = asyncEndpointProvider.createAsyncResponseInvoker();
+ ((InterceptorAsync)bindingInvocationChain.getHeadInvoker()).setPrevious(asyncResponseInvoker);
+ } // end if
+
+ // Add the runtime invoker to the end of the binding chain.
+ // It mediates between the binding chain and selects the
+ // correct invocation chain based on the operation that's
+ // been selected
+ bindingInvocationChain.addInvoker(invoker);
+
+ } // end method initServiceBindingInvocationChains
+
+ /**
+ * Add the interceptor for a binding
+ *
+ * @param reference
+ * @param binding
+ * @param chain
+ * @param operation
+ */
+ private void addServiceBindingInterceptor(InvocationChain chain, Operation operation) {
+ List<PolicyProvider> pps = getPolicyProviders();
+ if (pps != null) {
+ for (PolicyProvider p : pps) {
+ Interceptor interceptor = p.createInterceptor(operation);
+ if (interceptor != null) {
+ chain.addInterceptor(interceptor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a non-blocking interceptor if the service binding needs it
+ *
+ * @param service
+ * @param binding
+ * @param chain
+ */
+ private void addNonBlockingInterceptor(InvocationChain chain) {
+ ServiceBindingProvider provider = getBindingProvider();
+ if (provider != null) {
+ if (!provider.supportsOneWayInvocation()) {
+ chain.addInterceptor(Phase.SERVICE, new NonBlockingInterceptor(workScheduler));
+ }
+ }
+ }
+
+ /**
+ * Add the interceptor for a component implementation
+ *
+ * @param component
+ * @param service
+ * @param chain
+ * @param operation
+ */
+ private void addImplementationInterceptor(Component component,
+ ComponentService service,
+ InvocationChain chain,
+ Operation operation) {
+
+ if (service.getService() instanceof CompositeService) {
+ CompositeService compositeService = (CompositeService)service.getService();
+ component = getPromotedComponent(compositeService);
+ service = getPromotedComponentService(compositeService);
+ }
+
+ ImplementationProvider provider = ((RuntimeComponent)component).getImplementationProvider();
+
+ if (provider != null) {
+ Invoker invoker = null;
+ RuntimeComponentService runtimeService = (RuntimeComponentService)service;
+ if (runtimeService.getName().endsWith("_asyncCallback")){
+ if (provider instanceof ImplementationAsyncProvider){
+ invoker = (Invoker)((ImplementationAsyncProvider)provider).createAsyncResponseInvoker(operation);
+ } else {
+ // TODO - This should be an error but taking account of the
+ // existing non-native async support
+ invoker = provider.createInvoker((RuntimeComponentService)service, operation);
+/*
+ throw new ServiceRuntimeException("Component " +
+ this.getComponent().getName() +
+ " Service " +
+ getService().getName() +
+ " implementation provider doesn't implement ImplementationAsyncProvider but the implementation uses a " +
+ "refrence interface with the asyncInvocation intent set" +
+ " - [" + this.toString() + "]");
+*/
+ }
+ } else if (isAsyncInvocation() &&
+ provider instanceof ImplementationAsyncProvider){
+ invoker = (Invoker)((ImplementationAsyncProvider)provider).createAsyncInvoker((RuntimeComponentService)service, operation);
+ } else {
+ invoker = provider.createInvoker((RuntimeComponentService)service, operation);
+ }
+ chain.addInvoker(invoker);
+ }
+
+ List<PolicyProvider> pps = ((RuntimeComponent)component).getPolicyProviders();
+ if (pps != null) {
+ for (PolicyProvider p : pps) {
+ Interceptor interceptor = p.createInterceptor(operation);
+ if (interceptor != null) {
+ chain.addInterceptor(interceptor);
+ }
+ }
+ }
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeEndpointImpl copy = (RuntimeEndpointImpl)super.clone();
+ copy.invoker = new RuntimeInvoker(registry, copy);
+ return copy;
+ }
+
+ /**
+ * Follow a service promotion chain down to the inner most (non composite)
+ * component service.
+ *
+ * @param topCompositeService
+ * @return
+ */
+ public ComponentService getPromotedComponentService(CompositeService compositeService) {
+ ComponentService componentService = compositeService.getPromotedService();
+ if (componentService != null) {
+ Service service = componentService.getService();
+ if (componentService.getName() != null && service instanceof CompositeService) {
+
+ // Continue to follow the service promotion chain
+ return getPromotedComponentService((CompositeService)service);
+
+ } else {
+
+ // Found a non-composite service
+ return componentService;
+ }
+ } else {
+
+ // No promoted service
+ return null;
+ }
+ }
+
+ /**
+ * Follow a service promotion chain down to the innermost (non-composite) component.
+ *
+ * @param compositeService
+ * @return
+ */
+ public Component getPromotedComponent(CompositeService compositeService) {
+ ComponentService componentService = compositeService.getPromotedService();
+ if (componentService != null) {
+ Service service = componentService.getService();
+ if (componentService.getName() != null && service instanceof CompositeService) {
+
+ // Continue to follow the service promotion chain
+ return getPromotedComponent((CompositeService)service);
+
+ } else {
+
+ // Found a non-composite service
+ return compositeService.getPromotedComponent();
+ }
+ } else {
+
+ // No promoted service
+ return null;
+ }
+ }
+
+ public synchronized ServiceBindingProvider getBindingProvider() {
+ resolve();
+ if (bindingProvider == null) {
+ BindingProviderFactory factory =
+ (BindingProviderFactory)providerFactories.getProviderFactory(getBinding().getClass());
+ if (factory == null) {
+ throw new ServiceRuntimeException("No provider factory is registered for binding " + getBinding()
+ .getType());
+ }
+ this.bindingProvider = factory.createServiceBindingProvider(this);
+ }
+ return bindingProvider;
+ }
+
+ public synchronized List<PolicyProvider> getPolicyProviders() {
+ resolve();
+ if (policyProviders == null) {
+ policyProviders = new ArrayList<PolicyProvider>();
+ for (PolicyProviderFactory factory : providerFactories.getPolicyProviderFactories()) {
+ PolicyProvider provider = factory.createServicePolicyProvider(this);
+ if (provider != null) {
+ policyProviders.add(provider);
+ }
+ }
+ }
+ return policyProviders;
+ }
+
+ public void setBindingProvider(ServiceBindingProvider provider) {
+ this.bindingProvider = provider;
+ }
+
+ public Contract getContract() {
+ return getService();
+ }
+
+ public CompositeContext getCompositeContext() {
+ return compositeContext;
+ }
+
+ @Override
+ protected void reset() {
+ super.reset();
+ this.xml = null;
+ }
+
+ @Override
+ protected synchronized void resolve() {
+ if (xml != null && component == null) {
+ // TUSCANY-3958 - when an endpoint arrives at the remote side of the
+ // domain registry it's composite context is set, but to
+ // a default that's not that useful. We can tell because it
+ // doesn't set the system definitions
+ if (compositeContext == null ||
+ compositeContext.getSystemDefinitions() == null) {
+ compositeContext = CompositeContext.getCurrentCompositeContext();
+ if (compositeContext != null) {
+ bind(compositeContext);
+ }
+ } // end if
+ if (serializer != null) {
+ RuntimeEndpointImpl ep = (RuntimeEndpointImpl)serializer.readEndpoint(xml);
+ copyFrom(ep);
+ serializer.resolveEndpoint(this);
+ } else {
+ // In this case, we assume that we're running on a detached (non Tuscany) thread and
+ // as a result we need to connect back to the Tuscany environment...
+ ExtensionPointRegistry registry = ExtensionPointRegistryLocator.getExtensionPointRegistry();
+ if( registry != null ) {
+ this.registry = registry;
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+ this.serializer = utilities.getUtility(EndpointSerializer.class);
+ RuntimeEndpointImpl ep = (RuntimeEndpointImpl)serializer.readEndpoint(xml);
+ // Find the actual Endpoint in the DomainRegistry
+ ep = findActualEP( ep, registry );
+ if( ep != null ){
+ copyFrom( ep );
+ } // end if
+ } // end if
+ } // end if
+ setNormalizedWSDLContract();
+ } // end if
+ super.resolve();
+ } // end method resolve
+
+ /**
+ * Find the actual Endpoint in the DomainRegistry which corresponds to the configuration described
+ * in a deserialized Endpoint
+ * @param ep The deserialized endpoint
+ * @param registry - the main extension point Registry
+ * @return the corresponding Endpoint from the DomainRegistry, or null if no match can be found
+ */
+ private RuntimeEndpointImpl findActualEP(RuntimeEndpointImpl ep,
+ ExtensionPointRegistry registry) {
+ DomainRegistry domainRegistry = getEndpointRegistry( registry );
+
+ if( domainRegistry == null ) return null;
+
+ for( Endpoint endpoint : domainRegistry.findEndpoint(ep.getURI()) ) {
+ // TODO: For the present, simply return the first matching endpoint
+ return (RuntimeEndpointImpl) endpoint;
+ } // end for
+
+ return null;
+ } // end method findActualEP
+
+ /**
+ * Get the DomainRegistry
+ * @param registry - the ExtensionPoint registry
+ * @return the DomainRegistry - will be null if the DomainRegistry cannot be found
+ */
+ private DomainRegistry getEndpointRegistry( ExtensionPointRegistry registry) {
+ DomainRegistryFactory domainRegistryFactory = ExtensibleDomainRegistryFactory.getInstance(registry);
+
+ if( domainRegistryFactory == null ) return null;
+
+ // TODO: For the moment, just use the first (and only!) DomainRegistry...
+ DomainRegistry domainRegistry = (DomainRegistry) domainRegistryFactory.getEndpointRegistries().toArray()[0];
+
+ return domainRegistry;
+ } // end method
+
+ public InterfaceContract getBindingInterfaceContract() {
+ resolve();
+ if (bindingInterfaceContract != null) {
+ return bindingInterfaceContract;
+ }
+ bindingInterfaceContract = getBindingProvider().getBindingInterfaceContract();
+ if (bindingInterfaceContract == null) {
+ bindingInterfaceContract = getComponentServiceInterfaceContract();
+ }
+ if (bindingInterfaceContract == null) {
+ bindingInterfaceContract = getComponentTypeServiceInterfaceContract();
+ }
+ return bindingInterfaceContract;
+ }
+
+ public InterfaceContract getComponentTypeServiceInterfaceContract() {
+ resolve();
+ if (serviceInterfaceContract != null) {
+ return serviceInterfaceContract;
+ }
+ if (service == null) {
+ return getComponentServiceInterfaceContract();
+ }
+ serviceInterfaceContract = getLeafContract(service).getInterfaceContract();
+ if (serviceInterfaceContract == null) {
+ serviceInterfaceContract = getComponentServiceInterfaceContract();
+ }
+ return serviceInterfaceContract;
+ }
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ this.uri = in.readUTF();
+ this.xml = in.readUTF();
+ this.interfaceContractXML = in.readUTF();
+/*
+ this.wsdlCallback = in.readUTF();
+*/
+
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeUTF(getURI());
+ if (serializer == null && xml != null) {
+ out.writeUTF(xml);
+ } else {
+ if (serializer != null) {
+ out.writeUTF(serializer.write(this));
+ } else {
+ throw new IllegalStateException("No serializer is configured");
+ }
+ }
+
+ if (interfaceContractXML == null) {
+ interfaceContractXML = getXMLFromTuscanyInterfaceContract();
+ }
+ out.writeUTF(interfaceContractXML);
+ }
+
+ public String getAsXML() {
+ if (xml == null) {
+ this.xml = serializer.write(this);
+ }
+ return xml;
+ }
+
+ private String getXMLFromTuscanyInterfaceContract() throws IOException{
+ String interfaceContract = null;
+ try {
+ InterfaceContractProcessor processor = new InterfaceContractProcessor(registry);
+ ProcessorContext context = new ProcessorContext();
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class);
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bos);
+ processor.write(getComponentServiceInterfaceContract(), writer, context);
+ writer.close();
+ interfaceContract = bos.toString();
+ } catch (Exception ex){
+ throw new IOException(ex);
+ }
+ //System.out.println("Generated IC XML: " + interfaceContract);
+ return interfaceContract;
+ }
+
+ private InterfaceContract getTuscanyInterfaceContractFromXML() {
+ InterfaceContract interfaceContract = null;
+ //System.out.println("Reading IC XML: " + interfaceContractXML);
+ if (interfaceContractXML != null && interfaceContractXML.length() > 0){
+ try {
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ InterfaceContractProcessor processor = new InterfaceContractProcessor(registry);
+ ProcessorContext context = new ProcessorContext();
+ ByteArrayInputStream bis = new ByteArrayInputStream(interfaceContractXML.getBytes());
+ XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class);
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(bis);
+ interfaceContract = processor.read(reader, context);
+ } catch (Exception ex){
+ new ServiceRuntimeException(ex);
+ }
+ }
+ return interfaceContract;
+ }
+
+ private String getWsdl() {
+ InterfaceContract ic = getComponentServiceInterfaceContract();
+ if (ic == null || ic.getInterface() == null || !ic.getInterface().isRemotable()) {
+ return "";
+ }
+
+ WSDLInterfaceContract wsdlIC = null;
+ try {
+ wsdlIC = (WSDLInterfaceContract)getGeneratedWSDLContract(ic);
+ } catch (Exception ex){
+ // ignore WSDL generation errors as the service interface may have
+ // types that can't be converted to XML easily
+ return "";
+ }
+
+ if (wsdlIC == null) {
+ return "";
+ }
+
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+
+ try {
+ // write out a flattened WSDL along with XSD
+ WSDLInterface wsdl = (WSDLInterface)wsdlIC.getInterface();
+ WSDLDefinition wsdlDefinition = wsdl.getWsdlDefinition();
+ writeWSDL(outStream, wsdlDefinition);
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+
+ String wsdlString = outStream.toString();
+
+ return wsdlString;
+ }
+
+ private String getWsdlCallback() {
+ InterfaceContract ic = getComponentServiceInterfaceContract();
+ if (ic == null || ic.getCallbackInterface() == null || !ic.getCallbackInterface().isRemotable()) {
+ return "";
+ }
+
+ WSDLInterfaceContract wsdlIC = null;
+ try {
+ wsdlIC = (WSDLInterfaceContract)getGeneratedWSDLContract(ic);
+ } catch (Exception ex){
+ // ignore WSDL generation errors as the service interface may have
+ // types that can't be converted to XML easily
+ return "";
+ }
+
+ if (wsdlIC == null) {
+ return "";
+ }
+
+ ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+
+ try {
+ // write out a flattened Callback WSDL along with XSD
+ WSDLInterface wsdl = (WSDLInterface)wsdlIC.getCallbackInterface();
+ WSDLDefinition wsdlDefinition = wsdl.getWsdlDefinition();
+ writeWSDL(outStream, wsdlDefinition);
+ } catch (Exception e){
+ throw new RuntimeException(e);
+ }
+
+ String wsdlString = outStream.toString();
+
+ return wsdlString;
+ }
+
+ /**
+ * Write the WSDL followed by all it's XSD
+ *
+ * @param outStream
+ * @param wsdlDefinition
+ * @throws IOException
+ * @throws WSDLException
+ */
+ private void writeWSDL(OutputStream outStream, WSDLDefinition wsdlDefinition) throws IOException, WSDLException {
+ Definition definition = wsdlDefinition.getDefinition();
+ WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
+ String baseURI = null;
+ if (wsdlDefinition.getLocation() != null) {
+ baseURI = wsdlDefinition.getLocation().toString();
+ } else {
+ baseURI = "generated.wsdl";
+ }
+ outStream.write(baseURI.getBytes());
+ outStream.write(separator);
+ writer.writeWSDL(definition, outStream);
+ for (WSDLDefinition importedWSDLDefintion : wsdlDefinition.getImportedDefinitions()){
+ outStream.write(separator);
+ baseURI = importedWSDLDefintion.getLocation().toString();
+ outStream.write(baseURI.getBytes());
+ outStream.write(separator);
+ writer.writeWSDL(importedWSDLDefintion.getDefinition(), outStream);
+ }
+/* Exclude the XSD for the time being to see if we can get comparison working
+ * with the operation signatures but ignoring parameter types
+ for (XSDefinition xsdDefinition : wsdlDefinition.getXmlSchemas()){
+ // we store a reference to the schema schema. We don't need to write that out.
+ if (!xsdDefinition.getNamespace().equals("http://www.w3.org/2001/XMLSchema") &&
+ xsdDefinition.getSchema() != null){
+ writeSchema(outStream, xsdDefinition.getSchema());
+ }
+ }
+*/
+ }
+
+ /**
+ * Write an XSD
+ *
+ * @param outStream
+ * @param schema
+ * @throws IOException
+ */
+ private void writeSchema(OutputStream outStream, XmlSchema schema) throws IOException {
+ // TODO - this doesn't write schema in the non-namespace namespace
+ if (schema != null &&
+/*
+ schema.getTargetNamespace() != null &&
+ !schema.getTargetNamespace().equals("http://www.w3.org/2001/XMLSchema") &&
+*/
+ schema.getNamespaceContext() != null){
+ outStream.write(separator);
+ String baseURI = schema.getSourceURI();
+ outStream.write(baseURI.getBytes());
+ outStream.write(separator);
+ schema.write(outStream);
+
+ for (Iterator<?> i = schema.getIncludes().getIterator(); i.hasNext();) {
+ XmlSchemaObject obj = (XmlSchemaObject)i.next();
+ XmlSchema ext = null;
+ if (obj instanceof XmlSchemaInclude) {
+ ext = ((XmlSchemaInclude)obj).getSchema();
+ }
+ if (obj instanceof XmlSchemaImport) {
+ ext = ((XmlSchemaImport)obj).getSchema();
+ }
+ writeSchema(outStream, ext);
+ }
+ }
+ }
+
+ private void setNormalizedWSDLContract() {
+ if (interfaceContractXML == null || interfaceContractXML.length() < 1) {
+ return;
+ }
+ InterfaceContract ic = getComponentServiceInterfaceContract();
+ if (ic != null) {
+/*
+ ic.setNormalizedWSDLContract(WSDLHelper.createWSDLInterfaceContract(registry, wsdl, wsdlCallback));
+*/
+ ic.setNormalizedWSDLContract(getTuscanyInterfaceContractFromXML());
+ }
+ }
+
+ public InterfaceContract getGeneratedWSDLContract(InterfaceContract interfaceContract) {
+
+ if ( interfaceContract.getNormalizedWSDLContract() == null){
+ if (getComponentServiceInterfaceContract() instanceof JavaInterfaceContract){
+ if (contractBuilder == null){
+ throw new ServiceRuntimeException("Contract builder not found while calculating WSDL contract for " + this.toString());
+ }
+ contractBuilder.build(interfaceContract, null);
+ }
+ }
+
+ return interfaceContract.getNormalizedWSDLContract();
+ }
+
+ @Override
+ public RuntimeEndpoint getDelegateEndpoint() {
+ return delegateEndpoint;
+ }
+
+ @Override
+ public void setDelegateEndpoint(RuntimeEndpoint delegateEndpoint) {
+ this.delegateEndpoint = delegateEndpoint;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java
new file mode 100644
index 0000000000..cfc997b261
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/RuntimeEndpointReferenceImpl.java
@@ -0,0 +1,840 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.CompositeReference;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.assembly.builder.BindingBuilder;
+import org.apache.tuscany.sca.assembly.builder.BuilderContext;
+import org.apache.tuscany.sca.assembly.builder.BuilderExtensionPoint;
+import org.apache.tuscany.sca.assembly.impl.EndpointReferenceImpl;
+import org.apache.tuscany.sca.context.CompositeContext;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistryLocator;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;
+import org.apache.tuscany.sca.core.invocation.AsyncResponseService;
+import org.apache.tuscany.sca.core.invocation.ExtensibleWireProcessor;
+import org.apache.tuscany.sca.core.invocation.NonBlockingInterceptor;
+import org.apache.tuscany.sca.core.invocation.RuntimeInvoker;
+import org.apache.tuscany.sca.core.invocation.impl.InvocationChainImpl;
+import org.apache.tuscany.sca.core.invocation.impl.PhaseManager;
+import org.apache.tuscany.sca.interfacedef.Compatibility;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InterceptorAsync;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.InvokerAsyncResponse;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.provider.BindingProviderFactory;
+import org.apache.tuscany.sca.provider.EndpointReferenceProvider;
+import org.apache.tuscany.sca.provider.ImplementationAsyncProvider;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.PolicyProvider;
+import org.apache.tuscany.sca.provider.PolicyProviderFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.runtime.DomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.EndpointReferenceBinder;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.EndpointSerializer;
+import org.apache.tuscany.sca.runtime.ExtensibleDomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+import org.apache.tuscany.sca.work.WorkScheduler;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * Runtime model for Endpoint that supports java serialization
+ */
+public class RuntimeEndpointReferenceImpl extends EndpointReferenceImpl implements RuntimeEndpointReference, Externalizable {
+ private transient CompositeContext compositeContext;
+ private transient RuntimeWireProcessor wireProcessor;
+ private transient InterfaceContractMapper interfaceContractMapper;
+ private transient WorkScheduler workScheduler;
+ private transient PhaseManager phaseManager;
+ private transient MessageFactory messageFactory;
+ private transient RuntimeInvoker invoker;
+ private transient DomainRegistry domainRegistry;
+
+ private transient List<InvocationChain> chains;
+ private transient Map<Operation, InvocationChain> invocationChainMap =
+ new ConcurrentHashMap<Operation, InvocationChain>();
+ private transient InvocationChain bindingInvocationChain;
+
+ private transient EndpointReferenceBinder eprBinder;
+ private transient ReferenceBindingProvider bindingProvider;
+ private transient ProviderFactoryExtensionPoint providerFactories;
+ private transient List<PolicyProvider> policyProviders;
+ private transient EndpointSerializer serializer;
+
+ protected InterfaceContract bindingInterfaceContract;
+ protected InterfaceContract referenceInterfaceContract;
+
+ //protected InterfaceContract generatedReferenceWSDLInterfaceContract;
+
+ private String xml;
+
+ private boolean started;
+
+ private RuntimeEndpointReference delegateEndpointReference;
+ private boolean bindingURIaltered;
+
+ /**
+ * No-arg constructor for Java serilization
+ */
+ public RuntimeEndpointReferenceImpl() {
+ super(null);
+ }
+
+ public RuntimeEndpointReferenceImpl(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ protected void copyFrom(RuntimeEndpointReferenceImpl copy) {
+ this.xml = copy.xml;
+
+ this.component = copy.component;
+ this.reference = copy.reference;
+ this.interfaceContract = copy.interfaceContract;
+ this.referenceInterfaceContract = copy.referenceInterfaceContract;
+ this.callbackEndpoint = copy.callbackEndpoint;
+ this.targetEndpoint = copy.targetEndpoint;
+
+ this.binding = copy.binding;
+ this.bindingInterfaceContract = copy.interfaceContract;
+ this.bindingInvocationChain = copy.bindingInvocationChain;
+
+ this.requiredIntents = copy.requiredIntents;
+ this.policySets = copy.policySets;
+
+ this.uri = copy.uri;
+ this.unresolved = copy.unresolved;
+ this.status = copy.status;
+
+ this.chains = copy.chains;
+ this.invocationChainMap = copy.invocationChainMap;
+ this.bindingProvider = copy.bindingProvider;
+ this.policyProviders = copy.policyProviders;
+
+ if (this.compositeContext == null && copy.compositeContext != null) {
+ bind(copy.compositeContext);
+ }
+ }
+
+ public void bind(CompositeContext compositeContext) {
+ this.compositeContext = compositeContext;
+ bind(compositeContext.getExtensionPointRegistry(), compositeContext.getEndpointRegistry());
+ }
+
+ public void bind(ExtensionPointRegistry registry, DomainRegistry domainRegistry) {
+ if (compositeContext == null) {
+ compositeContext = new CompositeContext(registry, domainRegistry);
+ }
+ this.registry = registry;
+ this.domainRegistry = domainRegistry;
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.eprBinder = utilities.getUtility(EndpointReferenceBinder.class);
+ this.interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class);
+ this.workScheduler = utilities.getUtility(WorkScheduler.class);
+ this.wireProcessor =
+ new ExtensibleWireProcessor(registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class));
+
+ this.messageFactory = registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(MessageFactory.class);
+ this.invoker = new RuntimeInvoker(registry, this);
+
+ this.phaseManager = utilities.getUtility(PhaseManager.class);
+ this.serializer = utilities.getUtility(EndpointSerializer.class);
+ this.providerFactories = registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ this.builders = registry.getExtensionPoint(BuilderExtensionPoint.class);
+ this.contractBuilder = builders.getContractBuilder();
+ }
+
+ public synchronized List<InvocationChain> getInvocationChains() {
+ if (chains == null) {
+ initInvocationChains();
+ }
+ return chains;
+ }
+
+ public synchronized InvocationChain getBindingInvocationChain() {
+ if (bindingInvocationChain == null) {
+ bindingInvocationChain = new InvocationChainImpl(null, null, true, phaseManager, isAsyncInvocation());
+ initReferenceBindingInvocationChains();
+ }
+ return bindingInvocationChain;
+ }
+
+ public InvocationChain getInvocationChain(Operation operation) {
+ InvocationChain cached = invocationChainMap.get(operation);
+ if (cached == null) {
+ for (InvocationChain chain : getInvocationChains()) {
+ Operation op = chain.getSourceOperation();
+
+ // We used to check compatibility here but this is now validated when the
+ // chain is created. As the chain operations are the real interface types
+ // they may be incompatible just because they are described in different
+ // IDLs
+ if (operation.getName().equals(op.getName())) {
+ invocationChainMap.put(operation, chain);
+ return chain;
+ }
+ }
+ invocationChainMap.put(operation, null);
+ return null;
+ } else {
+ return cached;
+ }
+ }
+
+ public Message invoke(Message msg) {
+ return invoker.invoke(msg);
+ }
+
+ public Object invoke(Operation operation, Object[] args) throws InvocationTargetException {
+ return invoker.invoke(operation, args);
+ }
+
+ public Message invoke(Operation operation, Message msg) {
+ return invoker.invoke(operation, msg);
+ }
+
+ public void invokeAsync(Operation operation, Message msg){
+ msg.setOperation(operation);
+ invoker.invokeAsync(msg);
+ }
+
+ public void invokeAsync(Message msg){
+ invoker.invokeAsync(msg);
+ }
+
+ public void invokeAsyncResponse(Message msg){
+ // If there is a Binding Chain, invoke it first...
+ InvocationChain chain = this.getBindingInvocationChain();
+ if( chain != null ) {
+ Invoker tailInvoker = chain.getTailInvoker();
+ if (tailInvoker != null) {
+ ((InvokerAsyncResponse)tailInvoker).invokeAsyncResponse(msg);
+ } // end if
+ } // end if
+
+ chain = this.getInvocationChain(msg.getOperation());
+ Invoker tailInvoker = chain.getTailInvoker();
+ ((InvokerAsyncResponse)tailInvoker).invokeAsyncResponse(msg);
+ } // end method invokeAsyncResponse
+
+ /**
+ * Navigate the component/componentType inheritence chain to find the leaf contract
+ * @param contract
+ * @return
+ */
+ private Contract getLeafContract(Contract contract) {
+ Contract prev = null;
+ Contract current = contract;
+ while (current != null) {
+ prev = current;
+ if (current instanceof ComponentReference) {
+ current = ((ComponentReference)current).getReference();
+ } else if (current instanceof CompositeReference) {
+ current = ((CompositeReference)current).getPromotedReferences().get(0);
+ } else if (current instanceof ComponentService) {
+ current = ((ComponentService)current).getService();
+ } else if (current instanceof CompositeService) {
+ current = ((CompositeService)current).getPromotedService();
+ } else {
+ break;
+ }
+ if (current == null) {
+ return prev;
+ }
+ }
+ return current;
+ }
+
+ /**
+ * Initialize the invocation chains
+ */
+ private void initInvocationChains() {
+ InterfaceContract sourceContract = getComponentTypeReferenceInterfaceContract();
+ // TODO - EPR why is this looking at the component types. The endpoint reference should have the right interface contract by this time
+ //InterfaceContract sourceContract = getLeafInterfaceContract(endpointReference);
+
+ // It's the reference wire
+ resolveEndpointReference();
+
+ InterfaceContract targetContract = getBindingInterfaceContract();
+ // TODO - EPR why is this looking at the component types. The endpoint should have the right interface contract by this time
+ //InterfaceContract targetContract = getLeafInterfaceContract(endpoint);
+
+ if (sourceContract == null && targetContract != null) {
+ // TODO: until the web component introspection is brought up
+ try {
+ sourceContract = (InterfaceContract)targetContract.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ validateReferenceInterfaceCompatibility();
+
+ List<InvocationChain> chainList = new ArrayList<InvocationChain>();
+ if(sourceContract != null && targetContract != null) {
+ RuntimeComponentReference reference = (RuntimeComponentReference)getReference();
+ for (Operation operation : sourceContract.getInterface().getOperations()) {
+ Operation targetOperation = interfaceContractMapper.map(targetContract.getInterface(), operation);
+ if (targetOperation == null) {
+ throw new ServiceRuntimeException("No matching operation for " + operation.getName()
+ + " is found in reference "
+ + getComponent().getURI()
+ + "#"
+ + reference.getName());
+ }
+ InvocationChain chain = new InvocationChainImpl(operation, targetOperation, true, phaseManager, isAsyncInvocation());
+ if (operation.isNonBlocking()) {
+ addNonBlockingInterceptor(chain);
+ }
+ chainList.add(chain);
+ addReferenceBindingInterceptor(chain, operation);
+ }
+ }
+
+ // Set the chains until it's fully populated. If we initialize too early, any exception could
+ // leave this endpoint reference in a wrong state with an empty chain.
+ chains = chainList;
+ wireProcessor.process(this);
+
+ // reset the binding uri altered flag
+ bindingURIaltered = false;
+
+ if (isAsyncInvocation()){
+ // Fix up all of the operation chain response paths to point back to the implementation provided
+ // async response handler
+ //ImplementationProvider implementationProvider = ((RuntimeComponent)getComponent()).getImplementationProvider();
+ RuntimeComponentReference theReference = (RuntimeComponentReference)this.getReference();
+ RuntimeComponent theComponent = theReference.getComponent();
+ ImplementationProvider implementationProvider = theComponent.getImplementationProvider();
+ if (implementationProvider instanceof ImplementationAsyncProvider){
+ for (InvocationChain chain : getInvocationChains()){
+ InvokerAsyncResponse asyncResponseInvoker = ((ImplementationAsyncProvider)implementationProvider).createAsyncResponseInvoker(chain.getSourceOperation());
+ if (chain.getHeadInvoker() instanceof InterceptorAsync){
+ ((InterceptorAsync)chain.getHeadInvoker()).setPrevious(asyncResponseInvoker);
+ } else {
+ //TODO - throw error once the old async code is removed
+ } // end if
+ } // end for
+ } // end if
+ } // end if
+ } // end method initInvocationChains
+
+ /**
+ * Check that endpoint reference has compatible interface at the component and binding ends.
+ * The user can specify the interfaces at both ends so there is a danger that they won't be compatible.
+ * There is checking in the activator but of course endpoint references may not have a binding assigned
+ * until final resolution.
+ */
+ public void validateReferenceInterfaceCompatibility() {
+
+ InterfaceContract referenceContract = getComponentReferenceInterfaceContract();
+ InterfaceContract bindingContract = getBindingInterfaceContract();
+
+ if ((referenceContract != null) &&
+ (bindingContract != null)){
+
+ boolean bindingHasCallback = bindingContract.getCallbackInterface() != null;
+
+ try {
+ // Use the normalized contract if the interface types are different or if
+ // a normalized contract has been previously generate, for example, by virtue
+ // of finding a JAXWS annotation on a Java class that references a WSDL file
+ if (referenceContract.getClass() != bindingContract.getClass() ||
+ referenceContract.getNormalizedWSDLContract() != null ||
+ bindingContract.getNormalizedWSDLContract() != null) {
+ interfaceContractMapper.checkCompatibility(getGeneratedWSDLContract(referenceContract),
+ getGeneratedWSDLContract(bindingContract),
+ Compatibility.SUBSET,
+ !bindingHasCallback, // ignore callbacks if binding doesn't have one
+ false);
+ } else {
+ interfaceContractMapper.checkCompatibility(referenceContract,
+ bindingContract,
+ Compatibility.SUBSET,
+ !bindingHasCallback, // ignore callbacks if binding doesn't have one
+ false);
+ }
+ } catch (Exception ex){
+ throw new ServiceRuntimeException("Component " +
+ this.getComponent().getName() +
+ " Reference " +
+ getReference().getName() +
+ " interface is incompatible with the interface of the reference binding " +
+ getBinding().getName() +
+ " - " +
+ ex.getMessage() +
+ " - [" + this.toString() + "]");
+ }
+ }
+ }
+
+ /**
+ * This code used to be in the activator but has moved here as
+ * the endpoint reference may not now be resolved until the wire
+ * is first used
+ */
+ private void resolveEndpointReference() {
+ resolve();
+
+ eprBinder.bindRunTime(domainRegistry, this);
+
+ // start the binding provider
+ final ReferenceBindingProvider bindingProvider = getBindingProvider();
+
+ if (bindingProvider != null) {
+ // Allow bindings to add shutdown hooks. Requires RuntimePermission shutdownHooks in policy.
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ bindingProvider.start();
+ return null;
+ }
+ });
+ }
+ for (PolicyProvider policyProvider : getPolicyProviders()) {
+ policyProvider.start();
+ }
+
+ started = true;
+
+ Contract ref = getReference();
+ String refName = ref.getName();
+ if (!refName.startsWith("$self$.") && !refName.startsWith("$sca.client$.") && !ref.isForCallback())
+ compositeContext.getEndpointRegistry().addEndpointReference(this);
+
+ // InterfaceContract bindingContract = getBindingInterfaceContract();
+ // endpoint.setInterfaceContract(bindingContract);
+ }
+
+ private void initReferenceBindingInvocationChains() {
+
+ // add the binding interceptors to the reference binding wire
+ ReferenceBindingProvider provider = getBindingProvider();
+ if ((provider != null) && (provider instanceof EndpointReferenceProvider)) {
+ ((EndpointReferenceProvider)provider).configure();
+ }
+
+ // add the policy interceptors to the service binding wire
+ // find out which policies are active
+ for (PolicyProvider p : getPolicyProviders()) {
+ Interceptor interceptor = p.createBindingInterceptor();
+ if (interceptor != null) {
+ bindingInvocationChain.addInterceptor(interceptor);
+ }
+ }
+ }
+
+ public void rebuild() {
+ // TODO - can we use the idea of setTarget to rebuild the wire?
+ // used at the moment by binding.sca when it resets the
+ // source interface contract for local wires
+ this.chains = null;
+ invocationChainMap.clear();
+
+ if (getStatus() == EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED){
+ setStatus(EndpointReference.Status.NOT_CONFIGURED);
+ }
+
+ // TODO - cheating here as I fixed the RuntimeComponentService code
+ // to call this when it resets the interface contract
+ //endpointReference.setInterfaceContract(epr.getInterfaceContract());
+ }
+
+ /**
+ * Add the interceptor for a reference binding
+ *
+ * @param reference
+ * @param binding
+ * @param chain
+ * @param operation
+ */
+ private void addReferenceBindingInterceptor(InvocationChain chain, Operation operation) {
+ ReferenceBindingProvider provider = getBindingProvider();
+ if (provider != null) {
+ Invoker invoker = provider.createInvoker(operation);
+ if (invoker != null) {
+ chain.addInvoker(invoker);
+ }
+ }
+ List<PolicyProvider> pps = getPolicyProviders();
+ if (pps != null) {
+ for (PolicyProvider p : pps) {
+ Interceptor interceptor = p.createInterceptor(operation);
+ if (interceptor != null) {
+ chain.addInterceptor(interceptor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a non-blocking interceptor if the reference binding needs it
+ *
+ * @param reference
+ * @param binding
+ * @param chain
+ */
+ private void addNonBlockingInterceptor(InvocationChain chain) {
+ ReferenceBindingProvider provider = getBindingProvider();
+ if (provider != null) {
+ boolean supportsOneWayInvocation = provider.supportsOneWayInvocation();
+ if (!supportsOneWayInvocation) {
+ chain.addInterceptor(Phase.REFERENCE, new NonBlockingInterceptor(workScheduler));
+ }
+ }
+ }
+
+ /**
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ RuntimeEndpointReferenceImpl copy = (RuntimeEndpointReferenceImpl)super.clone();
+ copy.invoker = new RuntimeInvoker(registry, copy);
+ return copy;
+ }
+
+ public boolean isOutOfDate() {
+ resolve();
+ return bindingURIaltered || eprBinder.isOutOfDate(domainRegistry, this);
+ }
+
+ public synchronized ReferenceBindingProvider getBindingProvider() {
+ resolve();
+ // For the case that binding.sca is implemented by another binding
+ if (binding == null) {
+ return null;
+ }
+ if (bindingProvider == null) {
+ BindingProviderFactory factory =
+ (BindingProviderFactory)providerFactories.getProviderFactory(getBinding().getClass());
+ if (factory == null) {
+ throw new ServiceRuntimeException("No provider factory is registered for binding " + getBinding()
+ .getType());
+ }
+ this.bindingProvider = factory.createReferenceBindingProvider(this);
+ }
+ return bindingProvider;
+ }
+
+ public void setBindingProvider(ReferenceBindingProvider bindingProvider) {
+ this.bindingProvider = bindingProvider;
+ }
+
+ public synchronized List<PolicyProvider> getPolicyProviders() {
+ resolve();
+ if (policyProviders == null) {
+ policyProviders = new ArrayList<PolicyProvider>();
+ for (PolicyProviderFactory factory : providerFactories.getPolicyProviderFactories()) {
+ PolicyProvider provider = factory.createReferencePolicyProvider(this);
+ if (provider != null) {
+ policyProviders.add(provider);
+ }
+ }
+ }
+ return policyProviders;
+ }
+
+ public void unbind() {
+ bindingInvocationChain = null;
+ chains = null;
+ bindingProvider = null;
+ policyProviders = null;
+ invocationChainMap.clear();
+ }
+
+ public Contract getContract() {
+ return getReference();
+ }
+
+ public CompositeContext getCompositeContext() {
+ return compositeContext;
+ }
+
+ public InterfaceContract getBindingInterfaceContract() {
+ resolve();
+ if (bindingInterfaceContract != null) {
+ return bindingInterfaceContract;
+ }
+ ReferenceBindingProvider provider = getBindingProvider();
+ if (provider != null) {
+ bindingInterfaceContract = provider.getBindingInterfaceContract();
+ }
+ if (bindingInterfaceContract == null) {
+ bindingInterfaceContract = getComponentReferenceInterfaceContract();
+ }
+ if (bindingInterfaceContract == null) {
+ bindingInterfaceContract = getComponentTypeReferenceInterfaceContract();
+ }
+ return bindingInterfaceContract;
+ }
+
+ public InterfaceContract getComponentTypeReferenceInterfaceContract() {
+ resolve();
+ if (referenceInterfaceContract != null) {
+ return referenceInterfaceContract;
+ }
+ if (reference == null) {
+ return getComponentReferenceInterfaceContract();
+ }
+ referenceInterfaceContract = getLeafContract(reference).getInterfaceContract();
+ if (referenceInterfaceContract == null) {
+ referenceInterfaceContract = getComponentReferenceInterfaceContract();
+ }
+ return referenceInterfaceContract;
+ }
+
+ @Override
+ protected synchronized void resolve() {
+ if (xml != null && component == null) {
+ if (compositeContext == null) {
+ compositeContext = CompositeContext.getCurrentCompositeContext();
+ if (compositeContext != null) {
+ bind(compositeContext);
+ }
+ }
+ if (serializer != null) {
+ RuntimeEndpointReferenceImpl epr = (RuntimeEndpointReferenceImpl)serializer.readEndpointReference(xml);
+ copyFrom(epr);
+ } else {
+ // In this case, we assume that we're running on a detached (non Tuscany) thread and
+ // as a result we need to connect back to the Tuscany environment...
+ ExtensionPointRegistry registry = ExtensionPointRegistryLocator.getExtensionPointRegistry();
+ if( registry != null ) {
+ this.registry = registry;
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ this.serializer = utilities.getUtility(EndpointSerializer.class);
+ RuntimeEndpointReferenceImpl epr = (RuntimeEndpointReferenceImpl)serializer.readEndpointReference(xml);
+ // Find the actual Endpoint in the DomainRegistry
+ epr = findActualEPR( epr, registry );
+ if( epr != null ){
+ copyFrom( epr );
+ } // end if
+ } // end if
+ } // end if
+ }
+ super.resolve();
+ } // end method resolve
+
+ /**
+ * Find the actual EndpointReference in the DomainRegistry which corresponds to the configuration described
+ * in a deserialized EndpointReference
+ * @param ep The deserialized endpointReference
+ * @param registry - the main extension point Registry
+ * @return the corresponding EndpointReference from the DomainRegistry, or null if no match can be found
+ */
+ private RuntimeEndpointReferenceImpl findActualEPR(RuntimeEndpointReferenceImpl epr,
+ ExtensionPointRegistry registry) {
+ // Get the DomainRegistry
+ DomainRegistryFactory domainRegistryFactory = ExtensibleDomainRegistryFactory.getInstance(registry);
+ if( domainRegistryFactory == null ) return null;
+
+ // TODO: For the moment, just use the first (and only!) DomainRegistry...
+ DomainRegistry domainRegistry = (DomainRegistry) domainRegistryFactory.getEndpointRegistries().toArray()[0];
+ if( domainRegistry == null ) return null;
+
+ for( EndpointReference epReference : domainRegistry.getEndpointReferences() ) {
+ // TODO: For the present, simply return the first matching endpointReference
+ if( epReference.getURI().equals(epr.getURI()) ) {
+ return (RuntimeEndpointReferenceImpl) epReference;
+ } // end if
+ } // end for
+
+ return null;
+ } // end method findActualEPR
+
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ this.uri = in.readUTF();
+ this.xml = in.readUTF();
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeUTF(getURI());
+ if (serializer == null && xml != null) {
+ out.writeUTF(xml);
+ } else {
+ if (serializer != null) {
+ out.writeUTF(serializer.write(this));
+ } else {
+ throw new IllegalStateException("No serializer is configured");
+ }
+ }
+ }
+
+ public boolean isStarted() {
+ return started;
+ }
+
+ public InterfaceContract getGeneratedWSDLContract(InterfaceContract interfaceContract) {
+
+ if ( interfaceContract.getNormalizedWSDLContract() == null){
+ if (getComponentReferenceInterfaceContract() instanceof JavaInterfaceContract){
+ if (contractBuilder == null){
+ throw new ServiceRuntimeException("Contract builder not found while calculating WSDL contract for " + this.toString());
+ }
+ contractBuilder.build(interfaceContract, null);
+ }
+ }
+
+ return interfaceContract.getNormalizedWSDLContract();
+ }
+
+ public void createAsyncCallbackEndpoint(){
+ CompositeContext compositeContext = getCompositeContext();
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ RuntimeAssemblyFactory assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class);
+
+ RuntimeEndpoint endpoint = (RuntimeEndpoint)assemblyFactory.createEndpoint();
+ endpoint.bind(compositeContext);
+ endpoint.setComponent(getComponent());
+
+ // Create pseudo-service
+ ComponentService service = assemblyFactory.createComponentService();
+ JavaInterfaceFactory javaInterfaceFactory =
+ (JavaInterfaceFactory)modelFactories.getFactory(JavaInterfaceFactory.class);
+ JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
+ try {
+ interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(AsyncResponseService.class));
+ } catch (InvalidInterfaceException e1) {
+ // Nothing to do here - will not happen
+ } // end try
+
+ service.setInterfaceContract(interfaceContract);
+
+ String serviceName = getReference().getName() + "_asyncCallback";
+ service.setName(serviceName);
+ service.getEndpoints().add(endpoint);
+ service.setForCallback(true);
+ endpoint.setService(service);
+
+ // Set pseudo-service onto the component
+ getComponent().getServices().add(service);
+
+ // if the reference has a WSDL contract reset the response endpoint to be WSDL also
+ InterfaceContract referenceInterfaceContract = getComponentTypeReferenceInterfaceContract();
+ if (referenceInterfaceContract instanceof WSDLInterfaceContract){
+ WSDLInterfaceContract wsdlInterfaceContract = (WSDLInterfaceContract)endpoint.getGeneratedWSDLContract(interfaceContract);
+ service.setInterfaceContract(wsdlInterfaceContract);
+ }
+
+ // Create a binding
+ // Mike had to go via the XML but I don't remember why
+ Binding binding = null;
+ try {
+ binding = (Binding)getBinding().clone();
+ } catch (Exception ex){
+ //
+ }
+ String callbackURI = "/" + component.getName() + "/" + service.getName();
+ binding.setURI(callbackURI);
+
+ BuilderExtensionPoint builders = registry.getExtensionPoint(BuilderExtensionPoint.class);
+ BindingBuilder builder = builders.getBindingBuilder(binding.getType());
+ if (builder != null) {
+ org.apache.tuscany.sca.assembly.builder.BuilderContext builderContext = new BuilderContext(registry);
+ builder.build(component, service, binding, builderContext, true);
+ } // end if
+
+ endpoint.setBinding(binding);
+
+ // Need to establish policies here (binding has some...)
+ endpoint.getRequiredIntents().addAll(getRequiredIntents());
+ endpoint.getPolicySets().addAll(getPolicySets());
+ String epURI = getComponent().getName() + "#service-binding(" + serviceName + "/" + serviceName + ")";
+ endpoint.setURI(epURI);
+ endpoint.setUnresolved(false);
+
+ setCallbackEndpoint(endpoint);
+ }
+
+ @Override
+ public RuntimeEndpointReference getDelegateEndpointReference() {
+ return delegateEndpointReference;
+ }
+
+ @Override
+ public void setDelegateEndpointReference(RuntimeEndpointReference delegateEndpointReference) {
+ this.delegateEndpointReference = delegateEndpointReference;
+ }
+
+ /**
+ * Gets the async response invoker for an asynchronous invocation.
+ */
+ public InvokerAsyncResponse getAsyncResponseInvoker(Operation op) {
+ InvocationChain chain = getInvocationChain(op);
+ Invoker headInvoker = chain.getHeadInvoker();
+ if( headInvoker instanceof InterceptorAsync ) {
+ InvokerAsyncResponse responseInvoker = ((InterceptorAsync)headInvoker).getPrevious();
+ return responseInvoker;
+ }
+ return null;
+ }
+
+ public void setBindingURI(String uri) {
+ binding.setURI(uri);
+ bindingURIaltered = true;
+ BindingBuilder builder = builders.getBindingBuilder(binding.getType());
+ if (builder != null) {
+ BuilderContext builderContext = new BuilderContext(null, null, null);
+ builder.build(component, reference, binding, builderContext, true);
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/WSDLHelper.java b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/WSDLHelper.java
new file mode 100644
index 0000000000..c677b99b93
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/core/src/main/java/org/apache/tuscany/sca/core/assembly/impl/WSDLHelper.java
@@ -0,0 +1,514 @@
+/*
+ * 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.core.assembly.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.wsdl.Definition;
+import javax.wsdl.PortType;
+import javax.wsdl.Types;
+import javax.wsdl.WSDLException;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.UnknownExtensibilityElement;
+import javax.wsdl.extensions.schema.Schema;
+import javax.wsdl.xml.WSDLLocator;
+import javax.wsdl.xml.WSDLReader;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.xsd.XSDFactory;
+import org.apache.tuscany.sca.xsd.XSDefinition;
+import org.apache.tuscany.sca.xsd.xml.XSDModelResolver;
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+public class WSDLHelper {
+
+ /**
+ * This creates a WSDLInterfaceContract from a WSDL document
+ * TODO: Presently this writes the wsdl string to a temporary file which is then used by the Tuscany contribution
+ * code to turn the wsdl into the correctly populated Tuscany model objects. There must/should be a way to have
+ * that happen without needing the external file but i've not been able to find the correct configuration to
+ * get that to happen with all the schema objects created correctly.
+ */
+/*
+ public static WSDLInterfaceContract createWSDLInterfaceContractViaFile(ExtensionPointRegistry registry, String wsdl) {
+ File wsdlFile = null;
+ try {
+
+ wsdlFile = writeToFile(wsdl);
+ System.out.println("wsdl: " + wsdlFile);
+
+ FactoryExtensionPoint fep = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ URLArtifactProcessorExtensionPoint apep = registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+ ExtensibleURLArtifactProcessor aproc = new ExtensibleURLArtifactProcessor(apep);
+ ProcessorContext ctx = new ProcessorContext();
+
+ ContributionFactory cf = fep.getFactory(ContributionFactory.class);
+ final Contribution c = cf.createContribution();
+ c.setURI("temp");
+ c.setLocation(wsdlFile.toURI().toURL().toString());
+ c.setModelResolver(new ExtensibleModelResolver(c, registry.getExtensionPoint(ModelResolverExtensionPoint.class), fep));
+
+ WSDLDefinition wd = aproc.read(null, new URI("temp.wsdl"), wsdlFile.toURI().toURL(), ctx, WSDLDefinition.class);
+ c.getModelResolver().addModel(wd, ctx);
+ c.getModelResolver().resolveModel(WSDLDefinition.class, wd, ctx);
+ PortType pt = (PortType)wd.getDefinition().getAllPortTypes().values().iterator().next();
+
+ WSDLFactory wsdlFactory = registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(WSDLFactory.class);
+ WSDLInterface nwi = wsdlFactory.createWSDLInterface(pt, wd, c.getModelResolver(), null);
+ nwi.setWsdlDefinition(wd);
+ WSDLInterfaceContract wsdlIC = wsdlFactory.createWSDLInterfaceContract();
+ wsdlIC.setInterface(nwi);
+
+ wsdlFile.delete();
+
+ return wsdlIC;
+
+// } catch (InvalidWSDLException e) {
+// //* TODO: Also, this doesn't seem to work reliably and sometimes the schema objects don't get built correctly
+// //* org.apache.tuscany.sca.interfacedef.wsdl.impl.InvalidWSDLException: Element cannot be resolved: {http://sample/}sayHello
+// //* at org.apache.tuscany.sca.interfacedef.wsdl.impl.WSDLOperationIntrospectorImpl$WSDLPart.<init>(WSDLOperationIntrospectorImpl.java:276)
+// //* It seems like it works ok for me with IBM JDK but not with a Sun one
+// // I'm still trying to track this down but committing like this to see if anyone has any ideas
+// e.printStackTrace();
+// return null;
+
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (wsdlFile != null) {
+ wsdlFile.delete();
+ }
+ }
+ }
+
+ private static File writeToFile(String wsdl) throws FileNotFoundException, IOException {
+ File f = File.createTempFile("endpoint", ".wsdl");
+ Writer out = new OutputStreamWriter(new FileOutputStream(f));
+ try {
+ out.write(wsdl);
+ }
+ finally {
+ out.close();
+ }
+ return f;
+ }
+*/
+
+ /*
+ * A rework of the above code that
+ *
+ * 1 - doesn't use a intermediate file
+ * 2 - doesn't use the Tuscany contribution code
+ * 3 - takes care of imports/includes
+ * 4 - takes care of call and callback interfaces
+ *
+ * Re. point 1 - In theory it's neater but the Tuscany processors/resolvers don't know how to do this
+ * so there is quite a bit of code here. I don't really like it but we can sleep on it
+ * and look at how to integrate it into the runtime or even take a different approach to
+ * moving the interface about
+ */
+ public static WSDLInterfaceContract createWSDLInterfaceContract(ExtensionPointRegistry registry, String wsdl, String wsdlCallback) {
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory wsdlFactory = modelFactories.getFactory(org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory.class);
+
+ WSDLInterfaceContract wsdlInterfaceContract = wsdlFactory.createWSDLInterfaceContract();
+ wsdlInterfaceContract.setInterface(createWSDLInterface(registry, wsdl));
+ if (wsdlCallback != null && wsdlCallback.length() > 0){
+ wsdlInterfaceContract.setCallbackInterface(createWSDLInterface(registry, wsdlCallback));
+ }
+
+ return wsdlInterfaceContract;
+ }
+
+ /**
+ * Read a single WSDL interface and it's associated XSD from a string
+ *
+ * @param registry
+ * @param wsdl
+ * @return
+ */
+ public static WSDLInterface createWSDLInterface(ExtensionPointRegistry registry, String wsdl) {
+ try {
+ // Read all the WSDL and XSD in from the wsdl string. The WSDL and XSD appear sequentially in
+ // the following format:
+ //
+ // filename
+ // _X_
+ // wsdl xml
+ // _X_
+ // xsd xml
+ // _X_
+ // xsd xml
+ //
+ // So we need to read each WSDL and XSD separately and then fix up the includes/imports as appropriate
+ String xmlArray[] = wsdl.split("_X_");
+
+ String topWSDLLocation = null;
+ Map<String, XMLString> xmlMap = new HashMap<String, XMLString>();
+
+ for (int i = 0; i < xmlArray.length; i = i + 2){
+ String location = xmlArray[i];
+ String xml = xmlArray[i+1];
+ // strip the file name out of the location
+ location = location.substring(location.lastIndexOf("/") + 1);
+
+ if (location.endsWith(".wsdl")){
+ xmlMap.put(location,
+ new WSDLInfo(xmlArray[i],
+ xml));
+
+ if (topWSDLLocation == null){
+ topWSDLLocation = location;
+ }
+ } else {
+ xmlMap.put(location,
+ new XSDInfo(xmlArray[i],
+ xml));
+ }
+ }
+
+ FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory wsdlFactory = modelFactories.getFactory(org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory.class);
+ XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class);
+ XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
+ schemaCollection.setSchemaResolver(new XSDURIResolverImpl(xmlMap));
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ final org.apache.tuscany.sca.contribution.Contribution contribution = contributionFactory.createContribution();
+ ProcessorContext processorContext = new ProcessorContext();
+
+ ExtensibleModelResolver extensibleResolver = new ExtensibleModelResolver(contribution, registry.getExtensionPoint(ModelResolverExtensionPoint.class), modelFactories);
+ ModelResolver wsdlResolver = (ModelResolver)extensibleResolver.getModelResolverInstance(WSDLDefinition.class);
+ XSDModelResolver xsdResolver = (XSDModelResolver)extensibleResolver.getModelResolverInstance(XSDefinition.class);
+ contribution.setURI("temp");
+ contribution.setLocation(topWSDLLocation);
+ contribution.setModelResolver(extensibleResolver);
+
+ // read
+ for (XMLString xmlString : xmlMap.values()){
+ if (xmlString instanceof WSDLInfo){
+ WSDLReader reader;
+ try {
+ reader = AccessController.doPrivileged(new PrivilegedExceptionAction<WSDLReader>() {
+ public WSDLReader run() throws WSDLException {
+ return javax.wsdl.factory.WSDLFactory.newInstance().newWSDLReader();
+ }
+ });
+ } catch (PrivilegedActionException e){
+ throw (WSDLException)e.getException();
+ }
+ reader.setFeature("javax.wsdl.verbose", false);
+ reader.setFeature("javax.wsdl.importDocuments", true);
+ final WSDLLocatorImpl locator = new WSDLLocatorImpl(xmlString.getBaseURI(), xmlMap);
+ final WSDLReader freader = reader;
+ Definition readDefinition;
+ try {
+ readDefinition = AccessController.doPrivileged(new PrivilegedExceptionAction<Definition>() {
+ public Definition run() throws WSDLException {
+ return freader.readWSDL(locator);
+ }
+ });
+ } catch (PrivilegedActionException e){
+ throw (WSDLException)e.getException();
+ }
+
+ WSDLDefinition wsdlDefinition = wsdlFactory.createWSDLDefinition();
+ wsdlDefinition.setDefinition(readDefinition);
+ wsdlDefinition.setLocation(new URI(xmlString.getBaseURI()));
+
+ ((WSDLInfo)xmlString).setWsdlDefintion(wsdlDefinition);
+ wsdlResolver.addModel(wsdlDefinition, processorContext);
+
+ } else {
+ InputStream inputStream = new ByteArrayInputStream(xmlString.getXmlString().getBytes());
+ InputSource inputSource = new InputSource(inputStream);
+ inputSource.setSystemId(xmlString.getBaseURI());
+ XmlSchema schema = schemaCollection.read(inputSource, null);
+ inputStream.close();
+
+ XSDefinition xsdDefinition = xsdFactory.createXSDefinition();
+ xsdDefinition.setSchema(schema);
+
+ ((XSDInfo)xmlString).setXsdDefinition(xsdDefinition);
+ xsdResolver.addModel(xsdDefinition, processorContext);
+ }
+ }
+
+ // resolve
+ for (XMLString xmlString : xmlMap.values()){
+ if (xmlString instanceof WSDLInfo){
+ WSDLDefinition wsdlDefinition = ((WSDLInfo)xmlString).getWsdlDefintion();
+
+ // link to imports
+ for (Map.Entry<String, List<javax.wsdl.Import>> entry :
+ ((Map<String, List<javax.wsdl.Import>>)wsdlDefinition.getDefinition().getImports()).entrySet()) {
+ for (javax.wsdl.Import imp : entry.getValue()) {
+ String wsdlName = imp.getDefinition().getDocumentBaseURI();
+ WSDLInfo wsdlInfo = (WSDLInfo)xmlMap.get(getFilenameWithoutPath(wsdlName));
+ wsdlDefinition.getImportedDefinitions().add(wsdlInfo.getWsdlDefintion());
+ }
+ }
+
+ // extract any in-line types in the Tuscany model
+ Types types = wsdlDefinition.getDefinition().getTypes();
+ if ( types != null){
+/* read XSD from WSDL rather than from registry
+ for (int i=0; i < types.getExtensibilityElements().size(); i++){
+
+ String schemaName = xmlString.getBaseURI() + "#" + i++;
+ XSDInfo xsdInfo = (XSDInfo)xmlMap.get(getFilenameWithoutPath(schemaName));
+ if (xsdInfo != null){
+ wsdlDefinition.getXmlSchemas().add(xsdInfo.getXsdDefinition());
+ }
+*/
+ int index = 0;
+ for (Object ext : types.getExtensibilityElements()) {
+ ExtensibilityElement extElement = (ExtensibilityElement)ext;
+ Element element = null;
+ if (extElement instanceof Schema) {
+ element = ((Schema)extElement).getElement();
+ }
+ if (element != null) {
+ XSDefinition xsDefinition = xsdFactory.createXSDefinition();
+ xsDefinition.setUnresolved(true);
+ xsDefinition.setNamespace(element.getAttribute("targetNamespace"));
+ xsDefinition.setDocument(element.getOwnerDocument());
+ XmlSchema schema = schemaCollection.read(element, null);
+ xsDefinition.setSchema(schema);
+ xsDefinition.setLocation(URI.create(xmlString.getBaseURI() + "#" + index));
+ wsdlDefinition.getXmlSchemas().add(xsDefinition);
+ index++;
+ }
+ }
+ }
+ } else {
+ // TODO
+ }
+ }
+
+ WSDLInfo topWSDL = (WSDLInfo)xmlMap.get(topWSDLLocation);
+ WSDLDefinition topWSDLDefinition = topWSDL.getWsdlDefintion();
+
+ PortType portType = (PortType)topWSDLDefinition.getDefinition().getAllPortTypes().values().iterator().next();
+ WSDLInterface readWSDLInterface = wsdlFactory.createWSDLInterface(portType, topWSDLDefinition, extensibleResolver, null);
+
+ return readWSDLInterface;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /*
+ * WSDL is provided in the following string form:
+ *
+ * _X_
+ * the_original_path_to_a_wsdl_file
+ * _X_
+ * the WSDL XML
+ * _X_
+ * the_original_path_to_a_related_xsd_file
+ * _X_
+ * the XSD XML
+ * etc.
+ *
+ * This structure, and the classes that specialize it, represent this format in memory
+ */
+ private static class XMLString {
+ private String baseURI;
+ private String xmlString;
+
+ public XMLString(String baseURI, String xmlString){
+ this.baseURI = baseURI;
+ this.xmlString = xmlString;
+ }
+
+ public String getBaseURI() {
+ return baseURI;
+ }
+
+ public String getXmlString() {
+ return xmlString;
+ }
+ }
+
+ private static class XSDInfo extends XMLString {
+
+ XSDefinition xsdDefinition;
+
+ public XSDInfo(String baseURI, String xmlString) {
+ super(baseURI, xmlString);
+ }
+
+ public void setXsdDefinition(XSDefinition xsdDefinition) {
+ this.xsdDefinition = xsdDefinition;
+ }
+
+ public XSDefinition getXsdDefinition() {
+ return xsdDefinition;
+ }
+ }
+
+ private static class WSDLInfo extends XMLString {
+
+ WSDLDefinition wsdlDefintion;
+
+ public WSDLInfo(String baseURI, String xmlString) {
+ super(baseURI, xmlString);
+ }
+
+ public void setWsdlDefintion(WSDLDefinition wsdlDefintion) {
+ this.wsdlDefintion = wsdlDefintion;
+ }
+
+ public WSDLDefinition getWsdlDefintion() {
+ return wsdlDefintion;
+ }
+ }
+
+ /*
+ * A WSDL locator used to find WSDL in memory based on the map
+ * of all WSDL/XSD that have been read from the input string
+ */
+ private static class WSDLLocatorImpl implements WSDLLocator {
+ private Map<String, XMLString> xmlMap;
+ private String baseURI;
+ private String latestImportURI;
+
+ public WSDLLocatorImpl(String baseURI, Map<String, XMLString> xmlMap) {
+ this.baseURI = baseURI;
+ this.xmlMap = xmlMap;
+ }
+
+ public void close() {
+/*
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+*/
+ }
+
+ public InputSource getBaseInputSource() {
+ return getInputSource(getFilenameWithoutPath(baseURI), xmlMap);
+ }
+
+ public String getBaseURI() {
+ return baseURI;
+ }
+
+ public InputSource getImportInputSource(String parentLocation, String importLocation) {
+ latestImportURI = importLocation;
+ return getInputSource(getFilenameWithoutPath(importLocation), xmlMap);
+ }
+
+ public String getLatestImportURI() {
+ return latestImportURI;
+ }
+ }
+
+ /*
+ * A local URIResolver used to find XSD in memory based on the map
+ * of all WSDL/XSD that have been read from the input string
+ */
+ private static class XSDURIResolverImpl extends DefaultURIResolver {
+
+ private Map<String, XMLString> xmlMap;
+
+ public XSDURIResolverImpl(Map<String, XMLString> xmlMap) {
+ this.xmlMap = xmlMap;
+ }
+
+ @Override
+ protected URL getURL(URL contextURL, String spec) throws IOException {
+ return super.getURL(contextURL, spec);
+ }
+ @Override
+ public InputSource resolveEntity(String namespace,
+ String schemaLocation,
+ String baseUri) {
+ return getInputSource(getFilenameWithoutPath(schemaLocation), xmlMap);
+ }
+ }
+
+ /*
+ * Retrieve the input source for the given URI
+ */
+ private static InputSource getInputSource(String uri, Map<String, XMLString> xmlMap){
+ String xmlString = xmlMap.get(uri).getXmlString();
+ InputStream inputStream = new ByteArrayInputStream(xmlString.getBytes());
+ InputSource inputSource = new InputSource(inputStream);
+ inputSource.setSystemId(uri);
+ return inputSource;
+ }
+
+ /*
+ * Remove path from filename so that XSD/WSDL data can be found in memory
+ * rather than on the remote file system
+ */
+ private static String getFilenameWithoutPath(String filename){
+ // work out what the file name is that is being imported
+ // XSDs imports are written out by Tuscany with an relative web address such as
+ // /services/AccountService?xsd=wsdl-serialize.xsd
+ // for the time being just string the file name off the end. We are making
+ // assumption that the interface doesn't involve two files with the same
+ // name in different locations
+ int xsdIndex = filename.lastIndexOf("?xsd=");
+ int wsdlIndex = filename.lastIndexOf("/");
+ if ( xsdIndex >= 0){
+ return filename.substring(xsdIndex + 5);
+ } else {
+ return filename.substring(wsdlIndex + 1);
+ }
+ // What happens with generated WSDL?
+ }
+}