diff options
Diffstat (limited to 'java/sca/modules')
35 files changed, 3425 insertions, 506 deletions
diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilder.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilder.java new file mode 100644 index 0000000000..7bac630d5b --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilder.java @@ -0,0 +1,42 @@ +/* + * 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.assembly.builder; + +import org.apache.tuscany.sca.assembly.AbstractContract; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A builder that handles any build-time configuration needed by bindings. + * + * @version $Rev$ $Date$ + */ +public interface BindingBuilder { + + /** + * Configure a binding. + * + * @param component The component for the binding's service or reference + * @param contract The binding's service or reference + */ + void build(Component component, AbstractContract contract, Binding binding, Monitor monitor); + +} diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilderExtension.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilderExtension.java new file mode 100644 index 0000000000..37ad8af0b3 --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/BindingBuilderExtension.java @@ -0,0 +1,44 @@ +/* + * 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.assembly.builder; + +/** + * An extension that can be implemented by bindings to provide a binding builder. + * + * @version $Rev$ $Date$ + */ +public interface BindingBuilderExtension { + + /** + * Returns the binding builder. + * + * @return the binding builder + */ + BindingBuilder getBuilder(); + + /** + * Sets the binding builder. + * + * @param builder the binding builder + */ + void setBuilder(BindingBuilder builder); + +} + diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/BaseConfigurationBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/BaseConfigurationBuilderImpl.java index 885a5769fb..571088f88d 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/BaseConfigurationBuilderImpl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/BaseConfigurationBuilderImpl.java @@ -825,7 +825,7 @@ public abstract class BaseConfigurationBuilderImpl { newComponentService.setName("$promoted$." + compositeService.getName()); promotedComponent.getServices().add(newComponentService); newComponentService.setService(promotedService.getService()); - newComponentService.getBindings().addAll(compositeService.getBindings()); + newComponentService.getBindings().addAll(compositeService.getBindings()); newComponentService.setInterfaceContract(compositeService.getInterfaceContract()); if (compositeService.getInterfaceContract() != null && compositeService .getInterfaceContract().getCallbackInterface() != null) { @@ -891,7 +891,7 @@ public abstract class BaseConfigurationBuilderImpl { newComponentService.setName("$promoted$." + componentService.getName()); promotedComponent.getServices().add(newComponentService); newComponentService.setService(promotedService.getService()); - newComponentService.getBindings() + newComponentService.getBindings() .addAll(componentService.getBindings()); newComponentService.setInterfaceContract(componentService .getInterfaceContract()); @@ -952,7 +952,7 @@ public abstract class BaseConfigurationBuilderImpl { * @param compositeService * @return */ - private static Component getPromotedComponent(CompositeService compositeService) { + protected static Component getPromotedComponent(CompositeService compositeService) { ComponentService componentService = compositeService.getPromotedService(); if (componentService != null) { Service service = componentService.getService(); diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java index 69f52e0378..5b0268dcbc 100644 --- a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeBuilderImpl.java @@ -27,6 +27,7 @@ import org.apache.tuscany.sca.assembly.EndpointFactory; import org.apache.tuscany.sca.assembly.SCABindingFactory; import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.definitions.SCADefinitions; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.monitor.Monitor; @@ -48,6 +49,8 @@ public class CompositeBuilderImpl implements CompositeBuilder { private CompositeBuilder compositeServiceConfigurationBuilder; private CompositeBuilder compositePromotionBuilder; private CompositeBuilder compositePolicyBuilder; + private CompositeBuilder compositeServiceBindingBuilder; + private CompositeBuilder compositeReferenceBindingBuilder; /** * Constructs a new composite builder. @@ -97,6 +100,8 @@ public class CompositeBuilderImpl implements CompositeBuilder { compositeServiceConfigurationBuilder = new CompositeServiceConfigurationBuilderImpl(assemblyFactory, scaBindingFactory, interfaceContractMapper, policyDefinitions, monitor); compositePromotionBuilder = new CompositePromotionBuilderImpl(assemblyFactory, endpointFactory, interfaceContractMapper, monitor); compositePolicyBuilder = new CompositePolicyBuilderImpl(assemblyFactory, endpointFactory, interfaceContractMapper, monitor); + compositeServiceBindingBuilder = new CompositeServiceBindingBuilderImpl(monitor); + compositeReferenceBindingBuilder = new CompositeReferenceBindingBuilderImpl(monitor); } public void build(Composite composite) throws CompositeBuilderException { @@ -115,6 +120,9 @@ public class CompositeBuilderImpl implements CompositeBuilder { // Compute the policies across the model hierarchy compositePolicyBuilder.build(composite); + + // Build service binding-related information + compositeServiceBindingBuilder.build(composite); // Wire the components componentWireBuilder.build(composite); @@ -124,6 +132,9 @@ public class CompositeBuilderImpl implements CompositeBuilder { // Wire the composite references compositeReferenceWireBuilder.build(composite); + + // Build reference binding-related information + compositeReferenceBindingBuilder.build(composite); // Fuse nested composites //FIXME do this later diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceBindingBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceBindingBuilderImpl.java new file mode 100644 index 0000000000..90144ce49e --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeReferenceBindingBuilderImpl.java @@ -0,0 +1,72 @@ +/* + * 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.assembly.builder.impl; + + +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.Composite; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A composite builder that performs any additional building steps that + * reference bindings may need. Used for WSDL generation. + * + * @version $Rev$ $Date$ + */ +public class CompositeReferenceBindingBuilderImpl implements CompositeBuilder { + private Monitor monitor; + + public CompositeReferenceBindingBuilderImpl(Monitor monitor) { + this.monitor = monitor; + } + + public void build(Composite composite) throws CompositeBuilderException { + buildReferenceBindings(composite); + } + + private void buildReferenceBindings(Composite composite) { + + // build bindings recursively + for (Component component : composite.getComponents()) { + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + buildReferenceBindings((Composite)implementation); + } + } + + // find all the component reference bindings + for (Component component : composite.getComponents()) { + for (ComponentReference componentReference : component.getReferences()) { + for (Binding binding : componentReference.getBindings()) { + if (binding instanceof BindingBuilderExtension) { + ((BindingBuilderExtension)binding).getBuilder().build(component, componentReference, binding, monitor); + } + } + } + } + } + +} diff --git a/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeServiceBindingBuilderImpl.java b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeServiceBindingBuilderImpl.java new file mode 100644 index 0000000000..f5508b4ba1 --- /dev/null +++ b/java/sca/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/builder/impl/CompositeServiceBindingBuilderImpl.java @@ -0,0 +1,84 @@ +/* + * 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.assembly.builder.impl; + + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilder; +import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A composite builder that performs any additional building steps that + * service bindings may need. Used for WSDL generation. + * + * @version $Rev$ $Date$ + */ +public class CompositeServiceBindingBuilderImpl implements CompositeBuilder { + private Monitor monitor; + + public CompositeServiceBindingBuilderImpl(Monitor monitor) { + this.monitor = monitor; + } + + public void build(Composite composite) throws CompositeBuilderException { + buildServiceBindings(composite); + } + + private void buildServiceBindings(Composite composite) { + + // build bindings recursively + for (Component component : composite.getComponents()) { + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + buildServiceBindings((Composite)implementation); + } + } + + // find all the component service bindings + for (Component component : composite.getComponents()) { + for (ComponentService componentService : component.getServices()) { + for (Binding binding : componentService.getBindings()) { + if (binding instanceof BindingBuilderExtension) { + ((BindingBuilderExtension)binding).getBuilder().build(component, componentService, binding, monitor); + } + } + } + } + + // find all the composite service bindings + for (Service service : composite.getServices()) { + for (Binding binding : service.getBindings()) { + if (binding instanceof BindingBuilderExtension) { + Component component = BaseConfigurationBuilderImpl.getPromotedComponent((CompositeService)service); + ((BindingBuilderExtension)binding).getBuilder().build(component, service, binding, monitor); + } + } + } + } + +} diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java index 024009095e..47359c3484 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCABindingProviderFactory.java @@ -23,12 +23,7 @@ import java.util.List; import java.util.Map; import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; -import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; import org.apache.tuscany.sca.core.ExtensionPointRegistry; -import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; -import org.apache.tuscany.sca.host.http.ServletHost; -import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; -import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.policy.util.PolicyHandlerDefinitionsLoader; import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; import org.apache.tuscany.sca.provider.BindingProviderFactory; @@ -45,33 +40,26 @@ import org.apache.tuscany.sca.runtime.RuntimeComponentService; */ public class Axis2SCABindingProviderFactory implements BindingProviderFactory<DistributedSCABinding> { - private ModelFactoryExtensionPoint modelFactories; - private ServletHost servletHost; + private ExtensionPointRegistry extensionPoints; private Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassnames = null; - private DataBindingExtensionPoint dataBindings; public Axis2SCABindingProviderFactory(ExtensionPointRegistry extensionPoints) { - ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); - servletHost = servletHosts.getServletHosts().get(0); - modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + this.extensionPoints = extensionPoints; policyHandlerClassnames = PolicyHandlerDefinitionsLoader.loadPolicyHandlerClassnames(); - dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); } public ReferenceBindingProvider createReferenceBindingProvider(RuntimeComponent component, RuntimeComponentReference reference, DistributedSCABinding binding) { return new Axis2SCAReferenceBindingProvider(component, reference, binding, - servletHost, modelFactories, - policyHandlerClassnames, dataBindings); + extensionPoints, policyHandlerClassnames); } public ServiceBindingProvider createServiceBindingProvider(RuntimeComponent component, RuntimeComponentService service, DistributedSCABinding binding) { return new Axis2SCAServiceBindingProvider(component, service, binding, - servletHost, modelFactories, - policyHandlerClassnames, dataBindings); + extensionPoints, policyHandlerClassnames); } public Class<DistributedSCABinding> getModelType() { diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java index ce8e19e618..93ad1d30e5 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAReferenceBindingProvider.java @@ -1,197 +1,186 @@ -/*
- * 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.binding.sca.axis2.impl;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import org.apache.axiom.om.OMElement;
-import org.apache.tuscany.sca.assembly.Binding;
-import org.apache.tuscany.sca.assembly.SCABinding;
-import org.apache.tuscany.sca.binding.sca.DistributedSCABinding;
-import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory;
-import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
-import org.apache.tuscany.sca.binding.ws.axis2.Axis2ReferenceBindingProvider;
-import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
-import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
-import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
-import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl;
-import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
-import org.apache.tuscany.sca.host.http.ServletHost;
-import org.apache.tuscany.sca.interfacedef.InterfaceContract;
-import org.apache.tuscany.sca.interfacedef.Operation;
-import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
-import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
-import org.apache.tuscany.sca.interfacedef.wsdl.java2wsdl.Java2WSDLHelper;
-import org.apache.tuscany.sca.invocation.Invoker;
-import org.apache.tuscany.sca.invocation.MessageFactory;
-import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple;
-import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
-import org.apache.tuscany.sca.runtime.EndpointReference;
-import org.apache.tuscany.sca.runtime.RuntimeComponent;
-import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
-import org.apache.tuscany.sca.xsd.XSDFactory;
-
-/**
- * The reference binding provider for the remote sca binding implementation. Relies on the
- * binding-ws-axis implementation for sending messages to remote services to this provider
- * just uses the ws-axis provider.
- *
- * @version $Rev: 563772 $ $Date: 2007-08-08 07:50:49 +0100 (Wed, 08 Aug 2007) $
- */
-public class Axis2SCAReferenceBindingProvider implements ReferenceBindingProvider {
-
- private static final Logger logger = Logger.getLogger(Axis2SCAReferenceBindingProvider.class.getName());
-
- private RuntimeComponent component;
- private RuntimeComponentReference reference;
- private SCABinding binding;
- private Axis2ReferenceBindingProvider axisReferenceBindingProvider;
- private WebServiceBinding wsBinding;
-
- private EndpointReference serviceEPR = null;
- private EndpointReference callbackEPR = null;
-
- public Axis2SCAReferenceBindingProvider(RuntimeComponent component,
- RuntimeComponentReference reference,
- DistributedSCABinding binding,
- ServletHost servletHost,
- ModelFactoryExtensionPoint modelFactories,
- Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassnames,
- DataBindingExtensionPoint dataBindings) {
-
- WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class);
- XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class);
-
- this.component = component;
- this.reference = reference;
- this.binding = binding.getSCABinding();
- wsBinding = modelFactories.getFactory(WebServiceBindingFactory.class).createWebServiceBinding();
-
- // Turn the java interface contract into a WSDL interface contract
- InterfaceContract contract = reference.getInterfaceContract();
- if ((contract instanceof JavaInterfaceContract)) {
- ModelResolver resolver = component instanceof ResolverExtension ?
- ((ResolverExtension)component).getModelResolver() : null;
- contract = Java2WSDLHelper.createWSDLInterfaceContract(
- (JavaInterfaceContract)contract, resolver, dataBindings, wsdlFactory, xsdFactory);
- }
-
- // Set to use the Axiom data binding
- contract.getInterface().resetDataBinding(OMElement.class.getName());
-
- wsBinding.setBindingInterfaceContract(contract);
- wsBinding.setName(this.binding.getName());
-
- axisReferenceBindingProvider = new Axis2ReferenceBindingProvider(component,
- reference,
- wsBinding,
- servletHost,
- modelFactories,
- policyHandlerClassnames,
- dataBindings);
- }
-
- public InterfaceContract getBindingInterfaceContract() {
- return wsBinding.getBindingInterfaceContract();
- }
-
- public boolean supportsOneWayInvocation() {
- return false;
- }
-
- public Invoker createInvoker(Operation operation) {
- return new Axis2SCABindingInvoker(this, axisReferenceBindingProvider.createInvoker(operation));
- }
-
- /**
- * Uses the distributed domain service discovery feature to locate remote
- * service endpoints
- *
- * @return An EPR for the target service that this reference refers to
- */
- public EndpointReference getServiceEndpoint(){
-
- if (serviceEPR == null){
- String endpointURL = null;
-
- if (binding.getURI() != null) {
- // check if the binding URI is already resolved if it is use is if not
- try {
- URI uri = new URI(binding.getURI());
- if (uri.isAbsolute()) {
- endpointURL = binding.getURI();
- }
- } catch(Exception ex) {
- // do nothing
- }
- }
-
- serviceEPR = new EndpointReferenceImpl(endpointURL);
- }
-
- return serviceEPR;
- }
-
-
- /**
- * Retrieves the URI of the callback service (that this reference has created)
- * returns null if there is no callback service for the sca binding
- *
- * @return the callback endpoint
- */
- public EndpointReference getCallbackEndpoint(){
- if (callbackEPR == null) {
- if (reference.getCallbackService() != null) {
- for (Binding callbackBinding : reference.getCallbackService().getBindings()) {
- if (callbackBinding instanceof SCABinding) {
- callbackEPR = new EndpointReferenceImpl(reference.getName() + "/" + callbackBinding.getName());
- continue;
- }
- }
- }
- }
- return callbackEPR;
- }
-
-
- public SCABinding getSCABinding () {
- return binding;
- }
-
- public RuntimeComponent getComponent () {
- return component;
- }
-
- public RuntimeComponentReference getComponentReference () {
- return reference;
- }
-
- public void start() {
- axisReferenceBindingProvider.start();
- }
-
- public void stop() {
- axisReferenceBindingProvider.stop();
- }
-
-}
+/* + * 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.binding.sca.axis2.impl; + +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.apache.axiom.om.OMElement; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; +import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.axis2.Axis2ReferenceBindingProvider; +import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.runtime.EndpointReference; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; + +/** + * The reference binding provider for the remote sca binding implementation. Relies on the + * binding-ws-axis implementation for sending messages to remote services to this provider + * just uses the ws-axis provider. + * + * @version $Rev: 563772 $ $Date: 2007-08-08 07:50:49 +0100 (Wed, 08 Aug 2007) $ + */ +public class Axis2SCAReferenceBindingProvider implements ReferenceBindingProvider { + + private static final Logger logger = Logger.getLogger(Axis2SCAReferenceBindingProvider.class.getName()); + + private RuntimeComponent component; + private RuntimeComponentReference reference; + private SCABinding binding; + private Axis2ReferenceBindingProvider axisReferenceBindingProvider; + private WebServiceBinding wsBinding; + + private EndpointReference serviceEPR = null; + private EndpointReference callbackEPR = null; + + public Axis2SCAReferenceBindingProvider(RuntimeComponent component, + RuntimeComponentReference reference, + DistributedSCABinding binding, + ExtensionPointRegistry extensionPoints, + Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassnames) { + + ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); + ServletHost servletHost = servletHosts.getServletHosts().get(0); + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + DataBindingExtensionPoint dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); + + this.component = component; + this.reference = reference; + this.binding = binding.getSCABinding(); + wsBinding = modelFactories.getFactory(WebServiceBindingFactory.class).createWebServiceBinding(); + wsBinding.setName(this.binding.getName()); + + // Turn the java interface contract into a WSDL interface contract + BindingWSDLGenerator.generateWSDL(component, reference, wsBinding, extensionPoints, null); + + // Set to use the Axiom data binding + InterfaceContract contract = wsBinding.getBindingInterfaceContract(); + contract.getInterface().resetDataBinding(OMElement.class.getName()); + + axisReferenceBindingProvider = new Axis2ReferenceBindingProvider(component, + reference, + wsBinding, + servletHost, + modelFactories, + policyHandlerClassnames, + dataBindings); + } + + public InterfaceContract getBindingInterfaceContract() { + return wsBinding.getBindingInterfaceContract(); + } + + public boolean supportsOneWayInvocation() { + return false; + } + + public Invoker createInvoker(Operation operation) { + return new Axis2SCABindingInvoker(this, axisReferenceBindingProvider.createInvoker(operation)); + } + + /** + * Uses the distributed domain service discovery feature to locate remote + * service endpoints + * + * @return An EPR for the target service that this reference refers to + */ + public EndpointReference getServiceEndpoint(){ + + if (serviceEPR == null){ + String endpointURL = null; + + if (binding.getURI() != null) { + // check if the binding URI is already resolved if it is use is if not + try { + URI uri = new URI(binding.getURI()); + if (uri.isAbsolute()) { + endpointURL = binding.getURI(); + } + } catch(Exception ex) { + // do nothing + } + } + + serviceEPR = new EndpointReferenceImpl(endpointURL); + } + + return serviceEPR; + } + + + /** + * Retrieves the URI of the callback service (that this reference has created) + * returns null if there is no callback service for the sca binding + * + * @return the callback endpoint + */ + public EndpointReference getCallbackEndpoint(){ + if (callbackEPR == null) { + if (reference.getCallbackService() != null) { + for (Binding callbackBinding : reference.getCallbackService().getBindings()) { + if (callbackBinding instanceof SCABinding) { + callbackEPR = new EndpointReferenceImpl(reference.getName() + "/" + callbackBinding.getName()); + continue; + } + } + } + } + return callbackEPR; + } + + + public SCABinding getSCABinding () { + return binding; + } + + public RuntimeComponent getComponent () { + return component; + } + + public RuntimeComponentReference getComponentReference () { + return reference; + } + + public void start() { + axisReferenceBindingProvider.start(); + } + + public void stop() { + axisReferenceBindingProvider.stop(); + } + +} diff --git a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java index 14f209d245..0ecbf60395 100644 --- a/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java +++ b/java/sca/modules/binding-sca-axis2/src/main/java/org/apache/tuscany/sca/binding/sca/axis2/impl/Axis2SCAServiceBindingProvider.java @@ -1,136 +1,123 @@ -/*
- * 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.binding.sca.axis2.impl;
-
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import org.apache.axiom.om.OMElement;
-import org.apache.tuscany.sca.assembly.SCABinding;
-import org.apache.tuscany.sca.binding.sca.DistributedSCABinding;
-import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory;
-import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
-import org.apache.tuscany.sca.binding.ws.axis2.Axis2ServiceProvider;
-import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
-import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
-import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
-import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
-import org.apache.tuscany.sca.host.http.ServletHost;
-import org.apache.tuscany.sca.interfacedef.InterfaceContract;
-import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
-import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
-import org.apache.tuscany.sca.interfacedef.wsdl.java2wsdl.Java2WSDLHelper;
-import org.apache.tuscany.sca.invocation.MessageFactory;
-import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple;
-import org.apache.tuscany.sca.provider.ServiceBindingProvider;
-import org.apache.tuscany.sca.runtime.RuntimeComponent;
-import org.apache.tuscany.sca.runtime.RuntimeComponentService;
-import org.apache.tuscany.sca.xsd.XSDFactory;
-
-/**
- * The service binding provider for the remote sca binding implementation. Relies on the
- * binding-ws-axis implementation for providing a remote message endpoint for this service
- *
- * @version $Rev: 563772 $ $Date: 2007-08-08 07:50:49 +0100 (Wed, 08 Aug 2007) $
- */
-public class Axis2SCAServiceBindingProvider implements ServiceBindingProvider {
-
- private static final Logger logger = Logger.getLogger(Axis2SCAServiceBindingProvider.class.getName());
-
- private SCABinding binding;
- private Axis2ServiceProvider axisProvider;
- private WebServiceBinding wsBinding;
-
- private boolean started = false;
-
-
- public Axis2SCAServiceBindingProvider(RuntimeComponent component,
- RuntimeComponentService service,
- DistributedSCABinding binding,
- ServletHost servletHost,
- ModelFactoryExtensionPoint modelFactories,
- Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassnames,
- DataBindingExtensionPoint dataBindings) {
-
- MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class);
- WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class);
- XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class);
-
- this.binding = binding.getSCABinding();
- wsBinding = modelFactories.getFactory(WebServiceBindingFactory.class).createWebServiceBinding();
-
- // Turn the java interface contract into a WSDL interface contract
- InterfaceContract contract = service.getInterfaceContract();
- if ((contract instanceof JavaInterfaceContract)) {
- ModelResolver resolver = component instanceof ResolverExtension ?
- ((ResolverExtension)component).getModelResolver() : null;
- contract = Java2WSDLHelper.createWSDLInterfaceContract(
- (JavaInterfaceContract)contract, resolver, dataBindings, wsdlFactory, xsdFactory);
- }
-
- // Set to use the Axiom data binding
- contract.getInterface().resetDataBinding(OMElement.class.getName());
-
- wsBinding.setBindingInterfaceContract(contract);
- wsBinding.setName(this.binding.getName());
- wsBinding.setURI(this.binding.getURI());
-
- axisProvider = new Axis2SCAServiceProvider(component,
- service,
- this.binding,
- wsBinding,
- servletHost,
- messageFactory,
- policyHandlerClassnames);
-
- this.binding.setURI(wsBinding.getURI());
-
- }
-
- public InterfaceContract getBindingInterfaceContract() {
- return wsBinding.getBindingInterfaceContract();
- }
-
- public boolean supportsOneWayInvocation() {
- return false;
- }
-
- public void start() {
- if (started) {
- return;
- } else {
- started = true;
- }
-
- axisProvider.start();
- }
-
- public void stop() {
- if (!started) {
- return;
- } else {
- started = false;
- }
-
- axisProvider.stop();
- }
-
-}
+/* + * 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.binding.sca.axis2.impl; + +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.apache.axiom.om.OMElement; +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.binding.sca.DistributedSCABinding; +import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.axis2.Axis2ServiceProvider; +import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.host.http.ServletHostExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * The service binding provider for the remote sca binding implementation. Relies on the + * binding-ws-axis implementation for providing a remote message endpoint for this service + * + * @version $Rev: 563772 $ $Date: 2007-08-08 07:50:49 +0100 (Wed, 08 Aug 2007) $ + */ +public class Axis2SCAServiceBindingProvider implements ServiceBindingProvider { + + private static final Logger logger = Logger.getLogger(Axis2SCAServiceBindingProvider.class.getName()); + + private SCABinding binding; + private Axis2ServiceProvider axisProvider; + private WebServiceBinding wsBinding; + + private boolean started = false; + + + public Axis2SCAServiceBindingProvider(RuntimeComponent component, + RuntimeComponentService service, + DistributedSCABinding binding, + ExtensionPointRegistry extensionPoints, + Map<ClassLoader, List<PolicyHandlerTuple>> policyHandlerClassnames) { + + ServletHostExtensionPoint servletHosts = extensionPoints.getExtensionPoint(ServletHostExtensionPoint.class); + ServletHost servletHost = servletHosts.getServletHosts().get(0); + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); + DataBindingExtensionPoint dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); + + this.binding = binding.getSCABinding(); + wsBinding = modelFactories.getFactory(WebServiceBindingFactory.class).createWebServiceBinding(); + wsBinding.setName(this.binding.getName()); + wsBinding.setURI(this.binding.getURI()); + + // Turn the java interface contract into a WSDL interface contract + BindingWSDLGenerator.generateWSDL(component, service, wsBinding, extensionPoints, null); + + // Set to use the Axiom data binding + InterfaceContract contract = wsBinding.getBindingInterfaceContract(); + contract.getInterface().resetDataBinding(OMElement.class.getName()); + + axisProvider = new Axis2SCAServiceProvider(component, + service, + this.binding, + wsBinding, + servletHost, + messageFactory, + policyHandlerClassnames); + } + + public InterfaceContract getBindingInterfaceContract() { + return wsBinding.getBindingInterfaceContract(); + } + + public boolean supportsOneWayInvocation() { + return false; + } + + public void start() { + if (started) { + return; + } else { + started = true; + } + + axisProvider.start(); + } + + public void stop() { + if (!started) { + return; + } else { + started = false; + } + + axisProvider.stop(); + } + +} diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java index 6ce40b5eca..d4e3f47e6d 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java @@ -24,22 +24,17 @@ import java.util.Map; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; -import org.apache.tuscany.sca.contribution.resolver.ModelResolver; -import org.apache.tuscany.sca.contribution.resolver.ResolverExtension; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; -import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory; -import org.apache.tuscany.sca.interfacedef.wsdl.java2wsdl.Java2WSDLHelper; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.MessageFactory; import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; import org.apache.tuscany.sca.provider.ReferenceBindingProvider; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; -import org.apache.tuscany.sca.xsd.XSDFactory; +import org.osoa.sca.ServiceRuntimeException; public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { @@ -55,50 +50,15 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { DataBindingExtensionPoint dataBindings) { MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); - WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class); - XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class); this.wsBinding = wsBinding; - InterfaceContract contract = wsBinding.getBindingInterfaceContract(); - if (contract == null) { - contract = reference.getInterfaceContract().makeUnidirectional(false); - if (contract instanceof JavaInterfaceContract) { - ModelResolver resolver = component instanceof ResolverExtension ? - ((ResolverExtension)component).getModelResolver() : null; - contract = Java2WSDLHelper.createWSDLInterfaceContract( - (JavaInterfaceContract)contract, - Axis2ServiceBindingProvider.requiresSOAP12(wsBinding), - resolver, - dataBindings, - wsdlFactory, - xsdFactory); - } - wsBinding.setBindingInterfaceContract(contract); - } - - // TODO - fix up the conversational flag and operation sequences in case the contract has come from WSDL - // as we don't yet support requires="conversational" or sca:endConversation annotations - // in WSDL interface descriptions (see section 1.5.4 of the Assembly Specification V1.0) - if ( reference.getInterfaceContract().getInterface() != null && contract.getInterface() != null) { - contract.getInterface().setConversational(reference.getInterfaceContract().getInterface().isConversational()); - - for (Operation operation : contract.getInterface().getOperations()){ - Operation referenceOperation = null; - - for (Operation tmpOp : reference.getInterfaceContract().getInterface().getOperations()){ - if ( operation.getName().equals(tmpOp.getName())) { - referenceOperation = tmpOp; - break; - } - } - - if (referenceOperation != null ){ - operation.setConversationSequence(referenceOperation.getConversationSequence()); - } - } + // A WSDL document should always be present in the binding + if (wsBinding.getWSDLDocument() == null) { + throw new ServiceRuntimeException("No WSDL document for " + component.getName() + "/" + reference.getName()); } // Set to use the Axiom data binding + InterfaceContract contract = wsBinding.getBindingInterfaceContract(); if (contract.getInterface() != null) { contract.getInterface().resetDataBinding(OMElement.class.getName()); } diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java index 9afd1283c1..e35972ea00 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java @@ -26,23 +26,15 @@ import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; -import org.apache.tuscany.sca.contribution.resolver.ModelResolver; -import org.apache.tuscany.sca.contribution.resolver.ResolverExtension; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.interfacedef.InterfaceContract; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; -import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory; -import org.apache.tuscany.sca.interfacedef.wsdl.java2wsdl.Java2WSDLHelper; import org.apache.tuscany.sca.invocation.MessageFactory; -import org.apache.tuscany.sca.policy.Intent; -import org.apache.tuscany.sca.policy.IntentAttachPoint; import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; import org.apache.tuscany.sca.provider.ServiceBindingProvider; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentService; -import org.apache.tuscany.sca.xsd.XSDFactory; +import org.osoa.sca.ServiceRuntimeException; public class Axis2ServiceBindingProvider implements ServiceBindingProvider { @@ -58,58 +50,15 @@ public class Axis2ServiceBindingProvider implements ServiceBindingProvider { DataBindingExtensionPoint dataBindings) { MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); - WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class); - XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class); this.wsBinding = wsBinding; - InterfaceContract contract = wsBinding.getBindingInterfaceContract(); - if (contract == null) { - contract = service.getInterfaceContract().makeUnidirectional(false); - if (contract instanceof JavaInterfaceContract) { - ModelResolver resolver = component instanceof ResolverExtension ? - ((ResolverExtension)component).getModelResolver() : null; - contract = Java2WSDLHelper.createWSDLInterfaceContract( - (JavaInterfaceContract)contract, - requiresSOAP12(wsBinding), - resolver, - dataBindings, - wsdlFactory, - xsdFactory); - } else { - try { - //TUSCANY-2316 Cloning the Interface Contract to avoid overriding data biding information - contract = (InterfaceContract) contract.clone(); - } catch (Exception e) { - //ignore - } - } - wsBinding.setBindingInterfaceContract(contract); - } - - // TODO - fix up the conversational flag and operation sequences in case the contract has come from WSDL - // as we don't yet support requires="conversational" or sca:endConversation annotations - // in WSDL interface descriptions (see section 1.5.4 of the Assembly Specification V1.0) - if (service.getInterfaceContract().getInterface() != null ) { - contract.getInterface().setConversational(service.getInterfaceContract().getInterface().isConversational()); - - for (Operation operation : contract.getInterface().getOperations()){ - Operation serviceOperation = null; - - for (Operation tmpOp : service.getInterfaceContract().getInterface().getOperations()){ - if ( operation.getName().equals(tmpOp.getName())) { - serviceOperation = tmpOp; - break; - } - } - - if (serviceOperation != null ){ - operation.setConversationSequence(serviceOperation.getConversationSequence()); - } - } + // A WSDL document should always be present in the binding + if (wsBinding.getWSDLDocument() == null) { + throw new ServiceRuntimeException("No WSDL document for " + component.getName() + "/" + service.getName()); } - // Set to use the Axiom data binding + InterfaceContract contract = wsBinding.getBindingInterfaceContract(); contract.getInterface().resetDataBinding(OMElement.class.getName()); axisProvider = new Axis2ServiceProvider(component, service, wsBinding, servletHost, messageFactory, policyHandlerClassnames); @@ -131,17 +80,4 @@ public class Axis2ServiceBindingProvider implements ServiceBindingProvider { return true; } - private static final QName SOAP12_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0", "soap.1_2"); - - protected static boolean requiresSOAP12(WebServiceBinding wsBinding) { - if (wsBinding instanceof IntentAttachPoint) { - List<Intent> intents = ((IntentAttachPoint)wsBinding).getRequiredIntents(); - for (Intent intent : intents) { - if (SOAP12_INTENT.equals(intent.getName())) { - return true; - } - } - } - return false; - } } diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java index 5835ea78fe..bfc805803e 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceClient.java @@ -116,16 +116,6 @@ public class Axis2ServiceClient { this.contract = contract; this.wsBinding = wsBinding; this.policyHandlerClassnames = policyHandlerClassnames; - Definition definition = wsBinding.getWSDLDocument(); - if (definition != null) { - // Can happen if a self-reference. Reuse the service's WSDL configuration. - // In theory this is just a useful optimization but in practice I found - // it was needed to make the JUnit test for the helloworld-ws-service-jms - // sample run. - } else { - definition = Axis2WSDLHelper.configureWSDLDefinition(wsBinding, component, contract, servletHost); - wsBinding.setWSDLDocument(definition); - } } protected void start() { diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java index 1bfd20e937..de6f7c2c21 100644 --- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java +++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java @@ -141,6 +141,8 @@ public class Axis2ServiceProvider { public static final QName QNAME_WSA_REFERENCE_PARAMETERS = new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.EPR_REFERENCE_PARAMETERS); + private static final QName TRANSPORT_JMS_QUALIFIED_INTENT = + new QName("http://www.osoa.org/xmlns/sca/1.0", "transport.jms"); private static final String DEFAULT_QUEUE_CONNECTION_FACTORY = "TuscanyQueueConnectionFactory"; //Schema element names @@ -194,39 +196,66 @@ public class Axis2ServiceProvider { configContext.setContextRoot(servletHost.getContextPath()); - /* - // Look at all the Web Service bindings of the SCA service to see if any - // of them have an existing generated WSDL definitions document. If found, - // use it for this binding as well. If not found, generate a new document. - Definition definition = null; - for (Binding binding : contract.getBindings()) { - if (binding instanceof WebServiceBinding) { - definition = ((WebServiceBinding)binding).getWSDLDocument(); - if (definition != null) { - wsBinding.setWSDLDocument(definition); - break; - } - } + // Update port addresses with runtime information, and create a + // map from endpoint URIs to WSDL ports that eliminates duplicate + // ports for the same endpoint. + for (Object port : wsBinding.getService().getPorts().values()) { + String portAddress = getPortAddress((Port)port); + String endpointURI = computeEndpointURI(portAddress, servletHost); + setPortAddress((Port)port, endpointURI); + urlMap.put(endpointURI, (Port)port); } - */ - // The above code is disabled temporarily. Instead, we only look - // for a WSDL definitions document in this binding and don't - // attempt to share the same document across multiple bindings. - Definition definition = wsBinding.getWSDLDocument(); + } - // generate a WSDL definitions document if needed - if (definition == null) { - definition = Axis2WSDLHelper.configureWSDLDefinition(wsBinding, component, contract, servletHost); - wsBinding.setWSDLDocument(definition); + private String computeEndpointURI(String uri, ServletHost servletHost) { + + if (uri == null) { + return null; } - // The generated WSDL document maps ports to endpoint URLs. Create a - // reverse map that eliminates duplicate ports for the same endpoint. - for (Object port : wsBinding.getService().getPorts().values()) { - urlMap.put(getPortAddress((Port)port), (Port)port); + // pull out the binding intents to see what sort of transport is required + PolicySet transportJmsPolicySet = AxisPolicyHelper.getPolicySet(wsBinding, TRANSPORT_JMS_QUALIFIED_INTENT); + if (transportJmsPolicySet != null){ + if (!uri.startsWith("jms:/")) { + uri = "jms:" + uri; + } + + // construct the rest of the URI based on the policy. All the details are put + // into the URI here rather than being place directly into the Axis configuration + // as the Axis JMS sender relies on parsing the target URI + Axis2ConfigParamPolicy axis2ConfigParamPolicy = null; + for ( Object policy : transportJmsPolicySet.getPolicies() ) { + if ( policy instanceof Axis2ConfigParamPolicy ) { + axis2ConfigParamPolicy = (Axis2ConfigParamPolicy)policy; + Iterator paramIterator = axis2ConfigParamPolicy.getParamElements().get(DEFAULT_QUEUE_CONNECTION_FACTORY).getChildElements(); + + if (paramIterator.hasNext()){ + StringBuffer uriParams = new StringBuffer("?"); + + while (paramIterator.hasNext()){ + OMElement parameter = (OMElement)paramIterator.next(); + uriParams.append(parameter.getAttributeValue(new QName("","name"))); + uriParams.append("="); + uriParams.append(parameter.getText()); + + if (paramIterator.hasNext()){ + uriParams.append("&"); + } + } + + uri = uri + uriParams; + } + } + } + } else { + if (!uri.startsWith("jms:")) { + uri = servletHost.getURLMapping(uri).toString(); + } } + + return uri; } - + public void start() { try { diff --git a/java/sca/modules/binding-ws-wsdlgen/LICENSE b/java/sca/modules/binding-ws-wsdlgen/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/LICENSE @@ -0,0 +1,205 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. + + + diff --git a/java/sca/modules/binding-ws-wsdlgen/NOTICE b/java/sca/modules/binding-ws-wsdlgen/NOTICE new file mode 100644 index 0000000000..fdfa0e9faa --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/NOTICE @@ -0,0 +1,6 @@ +${pom.name} +Copyright (c) 2005 - 2008 The Apache Software Foundation + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + diff --git a/java/sca/modules/binding-ws-wsdlgen/pom.xml b/java/sca/modules/binding-ws-wsdlgen/pom.xml new file mode 100644 index 0000000000..a06039d1b4 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/pom.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<project> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-modules</artifactId> + <version>1.4-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-binding-ws-wsdlgen</artifactId> + <name>Apache Tuscany SCA Web Service binding WSDL Generator</name> + + <dependencies> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-binding-ws</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-interface-wsdl</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-interface-wsdl-xml</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-interface-java</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-interface-java-jaxws</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-xsd</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-xsd-xml</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-databinding</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-policy-security-ws</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-core-databinding</artifactId> + <version>1.4-SNAPSHOT</version> + <scope>test</scope> + </dependency> + + </dependencies> + + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + + <configuration> + <instructions> + <Bundle-Version>${tuscany.version}</Bundle-Version> + <Bundle-SymbolicName>org.apache.tuscany.sca.binding.ws.wsdlgen</Bundle-SymbolicName> + <Bundle-Description>${pom.name}</Bundle-Description> + <Export-Package>org.apache.tuscany.sca.binding.ws.wsdlgen*</Export-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java new file mode 100644 index 0000000000..8981d030ea --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGenerator.java @@ -0,0 +1,353 @@ +/* + * 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.binding.ws.wsdlgen; + +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.wsdl.Definition; +import javax.wsdl.PortType; +import javax.wsdl.WSDLException; +import javax.wsdl.xml.WSDLWriter; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.AbstractContract; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ResolverExtension; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +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.interfacedef.wsdl.impl.InvalidWSDLException; +import org.apache.tuscany.sca.interfacedef.wsdl.impl.WSDLInterfaceIntrospectorImpl; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentAttachPoint; +import org.apache.tuscany.sca.xsd.XSDFactory; + +/** + * @version $Rev$ $Date$ + */ +public class BindingWSDLGenerator { + private static final Logger logger = Logger.getLogger(BindingWSDLGenerator.class.getName()); + private static final QName SOAP12_INTENT = new QName("http://www.osoa.org/xmlns/sca/1.0", "soap.1_2"); + + public static boolean printWSDL; // external code sets this to print generated WSDL + + private BindingWSDLGenerator() { + // this class has static methods only and cannot be instantiated + } + + /** + * Log a warning message. + * @param problem + */ + private static void logWarning(Problem problem) { + Logger problemLogger = Logger.getLogger(problem.getSourceClassName(), problem.getBundleName()); + if (problemLogger != null){ + problemLogger.logp(Level.WARNING, problem.getSourceClassName(), null, problem.getMessageId(), problem.getMessageParams()); + } else { + logger.severe("Can't get logger " + problem.getSourceClassName()+ " with bundle " + problem.getBundleName()); + } + } + + /** + * Report a warning. + * @param message + * @param binding + * @param parameters + */ + private static void warning(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) { + Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.WARNING, wsBinding, message, (Object[])messageParameters); + if (monitor != null) { + monitor.problem(problem); + } else { + logWarning(problem); + } + } + + /** + * Report an error. + * @param message + * @param binding + * @param parameters + */ + private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) { + Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, (Object[])messageParameters); + if (monitor != null) { + monitor.problem(problem); + } else { + throw new WSDLGenerationException(problem.toString(), null, problem); + } + } + + /** + * Report an exception error. + * @param message + * @param binding + * @param exception + */ + private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, Exception ex) { + Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, ex); + if (monitor != null) { + monitor.problem(problem); + } else { + throw new WSDLGenerationException(problem.toString(), ex, problem); + } + } + + /** + * Report a fatal error. + * @param message + * @param binding + * @param exception + */ + private static void fatal(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) { + Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR,wsBinding, message, (Object[])messageParameters); + throw new WSDLGenerationException(problem.toString(), null, problem); + } + + /** + * Report a fatal exception error. + * @param message + * @param binding + * @param exception + */ + private static void fatal(Monitor monitor, String message, WebServiceBinding wsBinding, Exception ex) { + Problem problem = new ProblemImpl(BindingWSDLGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, ex); + throw new WSDLGenerationException(problem.toString(), ex, problem); + } + + /** + * This method can be called from the binding builder or from the runtime. + * Report problems and exceptions in the most appropriate way for both + * of these cases. + */ + public static void generateWSDL(Component component, + AbstractContract contract, + WebServiceBinding wsBinding, + ExtensionPointRegistry extensionPoints, + Monitor monitor) { + try { + createWSDLDocument(component, contract, wsBinding, extensionPoints, monitor); + } catch (WSDLGenerationException ex) { + if (ex.getProblem() != null) { + warning(monitor, "WsdlGenProblem", wsBinding, component.getName(), contract.getName()); + if (monitor != null) { + monitor.problem(ex.getProblem()); + } else { + throw ex; + } + } else if (ex.getCause() instanceof Exception) { + warning(monitor, "WsdlGenException", wsBinding, component.getName(), contract.getName()); + error(monitor, "UnexpectedException", wsBinding, (Exception)ex.getCause()); + } else { // should never happen + throw new IllegalStateException(ex); + } + } catch (RuntimeException ex) { + warning(monitor, "WsdlGenException", wsBinding, component.getName(), contract.getName()); + error(monitor, "UnexpectedException", wsBinding, ex); + } + } + + private static void createWSDLDocument(Component component, + AbstractContract contract, + WebServiceBinding wsBinding, + ExtensionPointRegistry extensionPoints, + Monitor monitor) { + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); + DataBindingExtensionPoint dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); + WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class); + XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class); + System.out.println("$$createWSDLDocument: wsBinding " + wsBinding); + + if (contract.getInterfaceContract() == null) { + // can happen if incorrect component service name + fatal(monitor, "MissingInterfaceContract", wsBinding, component.getName(), contract.getName()); + } + + InterfaceContract icontract = wsBinding.getBindingInterfaceContract(); + if (icontract == null) { + System.out.println("$$null bindingInterfaceContract: wsBinding " + wsBinding); + icontract = contract.getInterfaceContract().makeUnidirectional(false); + if (icontract instanceof JavaInterfaceContract) { + ModelResolver resolver = component instanceof ResolverExtension ? + ((ResolverExtension)component).getModelResolver() : null; + System.out.println("$$calling createWSDLInterfaceContract(): wsBinding " + wsBinding); + icontract = createWSDLInterfaceContract( + (JavaInterfaceContract)icontract, + requiresSOAP12(wsBinding), + resolver, + dataBindings, + wsdlFactory, + xsdFactory, + monitor); + System.out.println("$$returned from createWSDLInterfaceContract(): wsBinding " + wsBinding); + } else { + try { + //TUSCANY-2316 Cloning the Interface Contract to avoid overriding data binding information + icontract = (InterfaceContract)icontract.clone(); + } catch (Exception e) { + //ignore + } + } + System.out.println("$$calling setBindingInterfaceContract(): wsBinding " + wsBinding); + System.out.println("$$icontract: " + icontract); + if (icontract.getInterface() instanceof WSDLInterface) { + System.out.println("$$wsdlDefinition: " + ((WSDLInterface)icontract.getInterface()).getWsdlDefinition()); + } + wsBinding.setBindingInterfaceContract(icontract); + } + + // TODO - fix up the conversational flag and operation sequences in case the contract has come from WSDL + // as we don't yet support requires="conversational" or sca:endConversation annotations + // in WSDL interface descriptions (see section 1.5.4 of the Assembly Specification V1.0) + if (contract.getInterfaceContract().getInterface() != null ) { + icontract.getInterface().setConversational(contract.getInterfaceContract().getInterface().isConversational()); + + for (Operation operation : icontract.getInterface().getOperations()){ + Operation serviceOperation = null; + + for (Operation tmpOp : contract.getInterfaceContract().getInterface().getOperations()){ + if (operation.getName().equals(tmpOp.getName())) { + serviceOperation = tmpOp; + break; + } + } + + if (serviceOperation != null ){ + operation.setConversationSequence(serviceOperation.getConversationSequence()); + } + } + } + + /* + // Look at all the Web Service bindings of the SCA service to see if any + // of them have an existing generated WSDL definitions document. If found, + // use it for this binding as well. If not found, generate a new document. + Definition definition = null; + for (Binding binding : contract.getBindings()) { + if (binding instanceof WebServiceBinding) { + definition = ((WebServiceBinding)binding).getWSDLDocument(); + if (definition != null) { + wsBinding.setWSDLDocument(definition); + break; + } + } + } + */ + // The above code is currently not used. Instead, we only look + // for a WSDL definitions document in this binding and don't + // attempt to share the same document across multiple bindings. + + // generate a WSDL definitions document if needed + Definition definition = wsBinding.getWSDLDocument(); + if (definition == null) { + definition = WSDLServiceGenerator.configureWSDLDefinition(wsBinding, component, contract, monitor); + wsBinding.setWSDLDocument(definition); + } + } + + protected static boolean requiresSOAP12(WebServiceBinding wsBinding) { + if (wsBinding instanceof IntentAttachPoint) { + List<Intent> intents = ((IntentAttachPoint)wsBinding).getRequiredIntents(); + for (Intent intent : intents) { + if (SOAP12_INTENT.equals(intent.getName())) { + return true; + } + } + } + return false; + } + + /** + * Create a WSDLInterfaceContract from a JavaInterfaceContract + */ + protected static WSDLInterfaceContract createWSDLInterfaceContract(JavaInterfaceContract contract, + boolean requiresSOAP12, + ModelResolver resolver, + DataBindingExtensionPoint dataBindings, + WSDLFactory wsdlFactory, + XSDFactory xsdFactory, + Monitor monitor) { + + WSDLInterfaceContract wsdlContract = wsdlFactory.createWSDLInterfaceContract(); + WSDLInterface wsdlInterface = wsdlFactory.createWSDLInterface(); + wsdlContract.setInterface(wsdlInterface); + + WSDLDefinition wsdlDefinition = wsdlFactory.createWSDLDefinition(); + JavaInterface iface = (JavaInterface)contract.getInterface(); + + Definition def = null; + try { + Interface2WSDLGenerator wsdlGenerator = + new Interface2WSDLGenerator(requiresSOAP12, resolver, dataBindings, xsdFactory, monitor); + def = wsdlGenerator.generate(iface, wsdlDefinition); + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + + // for debugging + if (printWSDL) { + try { + System.out.println("Generated WSDL for Java interface " + iface.getName() + " class " + iface.getJavaClass().getName()); + WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter(); + writer.writeWSDL(def, System.out); + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + wsdlDefinition.setDefinition(def); + wsdlInterface.setWsdlDefinition(wsdlDefinition); + wsdlInterface.setRemotable(true); + wsdlInterface.setConversational(contract.getInterface().isConversational()); + wsdlInterface.setUnresolved(false); + wsdlInterface.setRemotable(true); + PortType portType = (PortType)def.getAllPortTypes().values().iterator().next(); + wsdlInterface.setPortType(portType); + + try { + for (Operation op : iface.getOperations()) { + javax.wsdl.Operation wsdlOp = portType.getOperation(op.getName(), null, null); + wsdlInterface.getOperations().add(WSDLInterfaceIntrospectorImpl.getOperation( + wsdlOp, wsdlDefinition, resolver, xsdFactory)); + } + } catch (InvalidWSDLException e) { + throw new WSDLGenerationException(e); + } + + return wsdlContract; + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java new file mode 100644 index 0000000000..d1f22ec9be --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java @@ -0,0 +1,726 @@ +/* + * 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.binding.ws.wsdlgen; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Fault; +import javax.wsdl.Input; +import javax.wsdl.Message; +import javax.wsdl.OperationType; +import javax.wsdl.Output; +import javax.wsdl.Part; +import javax.wsdl.PortType; +import javax.wsdl.Types; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.schema.Schema; +import javax.wsdl.factory.WSDLFactory; +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.databinding.DataBinding; +import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.databinding.XMLTypeHelper; +import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaOperation; +import org.apache.tuscany.sca.interfacedef.util.ElementInfo; +import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper; +import org.apache.tuscany.sca.interfacedef.util.TypeInfo; +import org.apache.tuscany.sca.interfacedef.util.WrapperInfo; +import org.apache.tuscany.sca.interfacedef.util.XMLType; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.xsd.XSDFactory; +import org.apache.tuscany.sca.xsd.XSDefinition; +import org.apache.ws.commons.schema.XmlSchema; +import org.apache.ws.commons.schema.XmlSchemaCollection; +import org.apache.ws.commons.schema.XmlSchemaException; +import org.apache.ws.commons.schema.utils.NamespaceMap; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @version $Rev: 670103 $ $Date: 2008-06-21 01:35:00 +0100 (Sat, 21 Jun 2008) $ + */ +public class Interface2WSDLGenerator { + private static final Logger logger = Logger.getLogger(Interface2WSDLGenerator.class.getName()); + private static final String SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"; + private static final String SCHEMA_NAME = "schema"; + private static final QName SCHEMA_QNAME = new QName(SCHEMA_NS, SCHEMA_NAME); + private static final String XMLNS_NS = "http://www.w3.org/2000/xmlns/"; + + private static final String ANYTYPE_NAME = "anyType"; + private static final QName ANYTYPE_QNAME = new QName(SCHEMA_NS, ANYTYPE_NAME); + + + private WSDLFactory factory; + private DataBindingExtensionPoint dataBindings; + private WSDLDefinitionGenerator definitionGenerator; + private boolean requiresSOAP12; + private ModelResolver resolver; + private XSDFactory xsdFactory; + private Monitor monitor; + + public Interface2WSDLGenerator(boolean requiresSOAP12, + ModelResolver resolver, + DataBindingExtensionPoint dataBindings, + XSDFactory xsdFactory, + Monitor monitor) throws WSDLException { + super(); + this.requiresSOAP12 = requiresSOAP12; + this.resolver = resolver; + definitionGenerator = new WSDLDefinitionGenerator(requiresSOAP12); + this.dataBindings = dataBindings; + this.xsdFactory = xsdFactory; + this.monitor = monitor; + this.factory = WSDLFactory.newInstance(); + } + + /** + * Log a warning message. + * @param problem + */ + private static void logWarning(Problem problem) { + Logger problemLogger = Logger.getLogger(problem.getSourceClassName(), problem.getBundleName()); + if (problemLogger != null){ + problemLogger.logp(Level.WARNING, problem.getSourceClassName(), null, problem.getMessageId(), problem.getMessageParams()); + } else { + logger.severe("Can't get logger " + problem.getSourceClassName()+ " with bundle " + problem.getBundleName()); + } + } + + /** + * Report a warning. + * @param message + * @param binding + * @param parameters + */ + private void warning(String message, Interface interfaze, String... messageParameters) { + Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.WARNING, interfaze, message, (Object[])messageParameters); + if (monitor != null) { + monitor.problem(problem); + } else { + logWarning(problem); + } + } + + /** + * Report a fatal error. + * @param message + * @param binding + * @param parameters + */ + private void fatal(String message, Interface interfaze, String... messageParameters) { + Problem problem = new ProblemImpl(this.getClass().getName(), "wsdlgen-validation-messages", Severity.ERROR, interfaze, message, (Object[])messageParameters); + throw new WSDLGenerationException(problem.toString(), null, problem); + } + + private void addDataType(Map<String, List<DataType>> map, DataType type) { + if (type == null) { + return; + } + String db = type.getDataBinding(); + if (db == null) { + return; + } + if ("java:array".equals(db)) { + DataType dt = (DataType)type.getLogical(); + db = dt.getDataBinding(); + } + List<DataType> types = map.get(db); + if (types == null) { + types = new ArrayList<DataType>(); + map.put(db, types); + } + types.add(type); + } + + private Map<String, List<DataType>> getDataTypes(Interface intf, boolean useWrapper) { + Map<String, List<DataType>> dataTypes = new HashMap<String, List<DataType>>(); + for (Operation op : intf.getOperations()) { + WrapperInfo wrapper = op.getWrapper(); + if (useWrapper && wrapper != null) { + DataType dt1 = wrapper.getInputWrapperType(); + addDataType(dataTypes, dt1); + DataType dt2 = wrapper.getOutputWrapperType(); + addDataType(dataTypes, dt2); + } else { + for (DataType dt1 : op.getInputType().getLogical()) { + addDataType(dataTypes, dt1); + } + DataType dt2 = op.getOutputType(); + addDataType(dataTypes, dt2); + } + for (DataType<DataType> dt3 : op.getFaultTypes()) { + DataType dt4 = dt3.getLogical(); + addDataType(dataTypes, dt4); + } + } + return dataTypes; + } + + + public Definition generate(Interface interfaze, WSDLDefinition wsdlDefinition) throws WSDLException { + if (interfaze == null) { + return null; + } + if (interfaze instanceof WSDLInterface) { + return ((WSDLInterface)interfaze).getWsdlDefinition().getDefinition(); + } + JavaInterface iface = (JavaInterface)interfaze; + if (!interfaze.isRemotable()) { + fatal("InterfaceNotRemotable", interfaze, iface.getName()); + } + QName name = getQName(iface); + Definition definition = factory.newDefinition(); + if (requiresSOAP12) { + definition.addNamespace("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); + } else { + definition.addNamespace("soap", "http://schemas.xmlsoap.org/wsdl/soap/"); + } + definition.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/"); + definition.addNamespace("xs", SCHEMA_NS); + + String namespaceURI = name.getNamespaceURI(); + definition.setTargetNamespace(namespaceURI); + definition.setQName(new QName(namespaceURI, name.getLocalPart() + "Service", name.getPrefix())); + definition.addNamespace(name.getPrefix(), namespaceURI); + + PortType portType = definition.createPortType(); + portType.setQName(name); + Binding binding = definitionGenerator.createBinding(definition, portType); + Map<String, XMLTypeHelper> helpers = new HashMap<String, XMLTypeHelper>(); + Map<QName, List<ElementInfo>> wrappers = new HashMap<QName, List<ElementInfo>>(); + for (Operation op : interfaze.getOperations()) { + javax.wsdl.Operation operation = generateOperation(definition, op, helpers, wrappers); + portType.addOperation(operation); + String action = ((JavaOperation)op).getAction(); + BindingOperation bindingOp = definitionGenerator.createBindingOperation(definition, operation, action); + binding.addBindingOperation(bindingOp); + } + portType.setUndefined(false); + definition.addPortType(portType); + binding.setUndefined(false); + definition.addBinding(binding); + wsdlDefinition.setBinding(binding); + + // call each helper in turn to populate the wsdl.types element + XmlSchemaCollection schemaCollection = new XmlSchemaCollection(); + + for (Map.Entry<String, List<DataType>> en: getDataTypes(interfaze, false).entrySet()) { + XMLTypeHelper helper = helpers.get(en.getKey()); + if (helper == null) { + continue; + } + List<XSDefinition> xsDefinitions = helper.getSchemaDefinitions(xsdFactory, resolver, en.getValue()); + for (XSDefinition xsDef: xsDefinitions) { + addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition); + } + } + + // remove global wrapper elements with schema definitions from generation list + for (QName wrapperName: new HashSet<QName>(wrappers.keySet())) { + if (wsdlDefinition.getXmlSchemaElement(wrapperName) != null) { + wrappers.remove(wrapperName); + } + } + + // generate schema elements for wrappers that aren't defined in the schemas + if (wrappers.size() > 0) { + int i = 0; + Map<String, XSDefinition> wrapperXSDs = new HashMap<String, XSDefinition>(); + Map<Element, Map<String, String>> prefixMaps = new HashMap<Element, Map<String, String>>(); + for (Map.Entry<QName, List<ElementInfo>> entry: wrappers.entrySet()) { + String targetNS = entry.getKey().getNamespaceURI(); + Document schemaDoc = null; + Element schema = null; + XSDefinition xsDef = wrapperXSDs.get(targetNS); + if (xsDef != null) { + schemaDoc = xsDef.getDocument(); + schema = schemaDoc.getDocumentElement(); + } else { + schemaDoc = createDocument(); + schema = schemaDoc.createElementNS(SCHEMA_NS, "xs:schema"); + // The elementFormDefault should be set to unqualified, see TUSCANY-2388 + schema.setAttribute("elementFormDefault", "unqualified"); + schema.setAttribute("attributeFormDefault", "qualified"); + schema.setAttribute("targetNamespace", targetNS); + schema.setAttributeNS(XMLNS_NS, "xmlns:xs", SCHEMA_NS); + schemaDoc.appendChild(schema); + Schema schemaExt = createSchemaExt(definition); + schemaExt.setElement(schema); + prefixMaps.put(schema, new HashMap<String, String>()); + xsDef = xsdFactory.createXSDefinition(); + xsDef.setUnresolved(true); + xsDef.setNamespace(targetNS); + xsDef.setDocument(schemaDoc); + wrapperXSDs.put(targetNS, xsDef); + } + Element wrapper = schemaDoc.createElementNS(SCHEMA_NS, "xs:element"); + schema.appendChild(wrapper); + wrapper.setAttribute("name", entry.getKey().getLocalPart()); + if (entry.getValue().size() == 1 && entry.getValue().get(0).getQName() == null) { + // special case for global fault element + QName typeName = entry.getValue().get(0).getType().getQName(); + wrapper.setAttribute("type", typeName.getLocalPart()); + } else { + // normal wrapper containing type definition inline + Element complexType = schemaDoc.createElementNS(SCHEMA_NS, "xs:complexType"); + wrapper.appendChild(complexType); + if (entry.getValue().size() > 0) { + Element sequence = schemaDoc.createElementNS(SCHEMA_NS, "xs:sequence"); + complexType.appendChild(sequence); + for (ElementInfo element: entry.getValue()) { + Element xsElement = schemaDoc.createElementNS(SCHEMA_NS, "xs:element"); + if (element.isMany()) { + xsElement.setAttribute("maxOccurs", "unbounded"); + } + xsElement.setAttribute("minOccurs", "0"); + xsElement.setAttribute("name", element.getQName().getLocalPart()); + if (element.isNillable()) { + xsElement.setAttribute("nillable", "true"); + } + QName typeName = element.getType().getQName(); + String nsURI = typeName.getNamespaceURI(); + if ("".equals(nsURI) || targetNS.equals(nsURI)) { + xsElement.setAttribute("type", typeName.getLocalPart()); + } else if (SCHEMA_NS.equals(nsURI)) { + xsElement.setAttribute("type", "xs:" + typeName.getLocalPart()); + } else { + Map<String, String> prefixMap = prefixMaps.get(schema); + String prefix = prefixMap.get(nsURI); + if (prefix == null) { + prefix = "ns" + i++; + prefixMap.put(nsURI, prefix); + schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI); + } + xsElement.setAttribute("type", prefix + ":" + typeName.getLocalPart()); + } + sequence.appendChild(xsElement); + } + } + } + } + + // resolve XSDefinitions containing generated wrappers + for (XSDefinition xsDef: wrapperXSDs.values()) { + loadXSD(schemaCollection, xsDef); + wsdlDefinition.getXmlSchemas().add(xsDef); + } + } + + return definition; + } + + private void addSchemaExtension(XSDefinition xsDef, + XmlSchemaCollection schemaCollection, + WSDLDefinition wsdlDefinition, + Definition definition) throws WSDLException { + if (xsDef.getAggregatedDefinitions() != null) { + for (XSDefinition xsd: xsDef.getAggregatedDefinitions()) { + addSchemaExtension(xsd, schemaCollection, wsdlDefinition, definition); + } + } else { + String nsURI = xsDef.getNamespace(); + Document document = xsDef.getDocument(); + if (document == null) { + try { + NamespaceMap prefixMap = new NamespaceMap(); + prefixMap.add("xs", SCHEMA_NS); + prefixMap.add("tns", nsURI); + XmlSchema schemaDef = xsDef.getSchema(); + schemaDef.setNamespaceContext(prefixMap); + Document[] docs = schemaDef.getAllSchemas(); + document = docs[docs.length-1]; + document.setDocumentURI(xsDef.getLocation().toString()); + xsDef.setDocument(document); + } catch (XmlSchemaException e) { + throw new RuntimeException(e); + } + } + loadXSD(schemaCollection, xsDef); + wsdlDefinition.getXmlSchemas().add(xsDef); + Element schema = document.getDocumentElement(); + Schema schemaExt = createSchemaExt(definition); + schemaExt.setDocumentBaseURI(document.getDocumentURI()); + schemaExt.setElement(schema); + } + } + + private static void loadXSD(XmlSchemaCollection schemaCollection, XSDefinition definition) { + if (definition.getSchema() != null) { + return; + } + if (definition.getDocument() != null) { + String uri = null; + if (definition.getLocation() != null) { + uri = definition.getLocation().toString(); + } + XmlSchema schema = schemaCollection.read(definition.getDocument(), uri, null); + if (definition.getSchemaCollection() == null) { + definition.setSchemaCollection(schemaCollection); + } + if (definition.getSchema() == null) { + definition.setSchema(schema); + } + } + } + + public Schema createSchemaExt(Definition definition) throws WSDLException { + Types types = definition.getTypes(); + if (types == null) { + types = definition.createTypes(); + definition.setTypes(types); + } + + Schema schemaExt = createSchema(definition); + types.addExtensibilityElement(schemaExt); + + return schemaExt; + } + + public Schema createSchema(Definition definition) throws WSDLException { + return (Schema)definition.getExtensionRegistry().createExtension(Types.class, SCHEMA_QNAME); + } + + private DocumentBuilderFactory documentBuilderFactory; + + public Document createDocument() { + Document document; + try { + if (documentBuilderFactory == null) { + documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + } + document = documentBuilderFactory.newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException ex) { + throw new WSDLGenerationException(ex); + } + // document.setDocumentURI("http://"); + return document; + } + + protected QName getQName(Interface interfaze) { + JavaInterface iface = (JavaInterface)interfaze; + QName qname = iface.getQName(); + if (qname != null) { + return qname; + } else { + Class<?> javaClass = iface.getJavaClass(); + return new QName(JavaXMLMapper.getNamespace(javaClass), javaClass.getSimpleName(), "tns"); + } + } + + public javax.wsdl.Operation generateOperation(Definition definition, + Operation op, + Map<String, XMLTypeHelper> helpers, + Map<QName, List<ElementInfo>> wrappers) + throws WSDLException { + javax.wsdl.Operation operation = definition.createOperation(); + operation.setName(op.getName()); + operation.setUndefined(false); + + Input input = definition.createInput(); + Message inputMsg = definition.createMessage(); + String namespaceURI = definition.getQName().getNamespaceURI(); + QName inputMsgName = new QName(namespaceURI, op.getName()); + inputMsg.setQName(inputMsgName); + inputMsg.setUndefined(false); + definition.addMessage(inputMsg); + + // FIXME: By default, java interface is mapped to doc-lit-wrapper style WSDL + if (op.getWrapper() != null) { + // Generate doc-lit-wrapper style + inputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, true)); + } else { + // Bare style + int i = 0; + for (DataType d : op.getInputType().getLogical()) { + inputMsg.addPart(generatePart(definition, d, "arg" + i)); + i++; + } + } + input.setMessage(inputMsg); + operation.setInput(input); + + if (!op.isNonBlocking()) { + Output output = definition.createOutput(); + Message outputMsg = definition.createMessage(); + QName outputMsgName = new QName(namespaceURI, op.getName() + "Response"); + outputMsg.setQName(outputMsgName); + outputMsg.setUndefined(false); + definition.addMessage(outputMsg); + + if (op.getWrapper() != null) { + outputMsg.addPart(generateWrapperPart(definition, op, helpers, wrappers, false)); + } else { + outputMsg.addPart(generatePart(definition, op.getOutputType(), "return")); + } + output.setMessage(outputMsg); + + operation.setOutput(output); + operation.setStyle(OperationType.REQUEST_RESPONSE); + } else { + operation.setStyle(OperationType.ONE_WAY); + } + + for (DataType<DataType> faultType: op.getFaultTypes()) { + Fault fault = definition.createFault(); + QName faultName = ((XMLType)faultType.getLogical().getLogical()).getElementName(); + fault.setName(faultName.getLocalPart()); + Message faultMsg = definition.getMessage(faultName); + if (faultMsg == null) { + faultMsg = definition.createMessage(); + faultMsg.setQName(faultName); + faultMsg.setUndefined(false); + definition.addMessage(faultMsg); + faultMsg.addPart(generatePart(definition, faultType.getLogical(), faultName.getLocalPart())); + } + fault.setMessage(faultMsg); + operation.addFault(fault); + List<ElementInfo> elements = null; + if (faultType.getLogical().getPhysical() != faultType.getPhysical()) { + // create special wrapper for type indirection to real fault bean + elements = new ArrayList<ElementInfo>(1); + DataType logical = faultType.getLogical(); + elements.add(getElementInfo(logical.getPhysical(), logical, null, helpers)); + } else { + // convert synthesized fault bean to a wrapper type + elements = new ArrayList<ElementInfo>(); + for (DataType<XMLType> propDT: op.getFaultBeans().get(faultName)) { + XMLType logical = propDT.getLogical(); + elements.add(getElementInfo(propDT.getPhysical(), propDT, logical.getElementName(), helpers)); + } + } + wrappers.put(faultName, elements); + } + + operation.setUndefined(false); + return operation; + } + + public Part generatePart(Definition definition, DataType arg, String partName) { + Part part = definition.createPart(); + part.setName(partName); + if (arg != null && arg.getLogical() instanceof XMLType) { + XMLType xmlType = (XMLType)arg.getLogical(); + QName elementName = xmlType.getElementName(); + part.setElementName(elementName); + addNamespace(definition, elementName); + if (xmlType.getElementName() == null) { + QName typeName = xmlType.getTypeName(); + part.setTypeName(typeName); + addNamespace(definition, typeName); + } + } + return part; + } + + public Part generateWrapperPart(Definition definition, + Operation operation, + Map<String, XMLTypeHelper> helpers, + Map<QName, List<ElementInfo>> wrappers, + boolean input) throws WSDLException { + Part part = definition.createPart(); + String partName = input ? operation.getName() : (operation.getName() + "Response"); + part.setName(partName); + WrapperInfo opWrapper = operation.getWrapper(); + if (opWrapper != null) { + ElementInfo elementInfo = + input ? opWrapper.getInputWrapperElement() : opWrapper.getOutputWrapperElement(); + List<ElementInfo> elements = + input ? opWrapper.getInputChildElements() : opWrapper.getOutputChildElements(); + QName wrapperName = elementInfo.getQName(); + part.setElementName(wrapperName); + addNamespace(definition, wrapperName); + wrappers.put(wrapperName, elements); + + // FIXME: [rfeng] Ideally, we should try to register the wrappers only. But we are + // expriencing the problem that we cannot handle XSD imports + /* + Class<?> wrapperClass = input ? opWrapper.getInputWrapperClass() : opWrapper.getOutputWrapperClass(); + DataType wrapperDT = input ? opWrapper.getInputWrapperType() : opWrapper.getOutputWrapperType(); + if (wrapperClass != null) { + getElementInfo(wrapperClass, wrapperDT, wrapperName, helpers); + return part; + } + */ + + Method method = ((JavaOperation)operation).getJavaMethod(); + if (input) { + Class<?>[] paramTypes = method.getParameterTypes(); + for (int i = 0; i < paramTypes.length; i++) { + DataType dataType = operation.getInputType().getLogical().get(i); + elements.set(i, getElementInfo(paramTypes[i], dataType, elements.get(i).getQName(), helpers)); + } + } else { + Class<?> returnType = method.getReturnType(); + if (returnType != Void.TYPE) { + DataType dataType = operation.getOutputType(); + elements.set(0, getElementInfo(returnType, dataType, elements.get(0).getQName(), helpers)); + } + } + } + return part; + } + + private ElementInfo getElementInfo(Class javaType, + DataType dataType, + QName name, + Map<String, XMLTypeHelper> helpers) { + String db = dataType.getDataBinding(); + while ("java:array".equals(db)) { + dataType = (DataType)dataType.getLogical(); + db = dataType.getDataBinding(); + } + XMLTypeHelper helper = helpers.get(db); + if (helper == null) { + DataBinding dataBinding = dataBindings.getDataBinding(db); + if (dataBinding == null) { + QName element = name; + if (element == null || dataType.getLogical() instanceof XMLType) { + XMLType xmlType = (XMLType)dataType.getLogical(); + if (xmlType.getElementName() != null) { + element = xmlType.getElementName(); + } + } + return new ElementInfo(element, new TypeInfo(ANYTYPE_QNAME, false, null)); + // throw new ServiceRuntimeException("No data binding for " + db); + } + + helper = dataBinding.getXMLTypeHelper(); + if (helper == null) { + // Default to JAXB + helper = helpers.get(JAXBDataBinding.NAME); + if (helper == null) { + helper = dataBindings.getDataBinding(JAXBDataBinding.NAME).getXMLTypeHelper(); + helpers.put(JAXBDataBinding.NAME, helper); + } + } + helpers.put(db, helper); + } + TypeInfo typeInfo = helper.getTypeInfo(javaType.isArray() ? javaType.getComponentType() : javaType, + dataType.getLogical()); + ElementInfo element = new ElementInfo(name, typeInfo); + element.setMany(byte[].class != javaType && javaType.isArray()); + element.setNillable(!javaType.isPrimitive()); + return element; + } + + private static void addNamespace(Definition definition, QName name) { + String namespace = name.getNamespaceURI(); + if (definition.getPrefix(namespace) == null) { + definition.addNamespace("ns" + definition.getNamespaces().size(), namespace); + } + } + + /* + // currently not using the next three methods + public XmlSchemaType getXmlSchemaType(DataType type) { + return null; + } + + // FIXME: WE need to add databinding-specific Java2XSD generation + public Element generateXSD(DataType dataType) { + DataBinding dataBinding = dataBindings.getDataBinding(dataType.getDataBinding()); + if (dataBinding != null) { + // return dataBinding.generateSchema(dataType); + } + return null; + } + + public void generateWrapperElements(Operation op) { + XmlSchemaCollection collection = new XmlSchemaCollection(); + String ns = getQName(op.getInterface()).getNamespaceURI(); + XmlSchema schema = new XmlSchema(ns, collection); + schema.setAttributeFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED)); + schema.setElementFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED)); + + XmlSchemaElement inputElement = new XmlSchemaElement(); + inputElement.setQName(new QName(ns, op.getName())); + XmlSchemaComplexType inputType = new XmlSchemaComplexType(schema); + inputType.setName(""); + XmlSchemaSequence inputSeq = new XmlSchemaSequence(); + inputType.setParticle(inputSeq); + List<DataType> argTypes = op.getInputType().getLogical(); + for (DataType argType : argTypes) { + XmlSchemaElement child = new XmlSchemaElement(); + Object logical = argType.getLogical(); + if (logical instanceof XMLType) { + child.setName(((XMLType)logical).getElementName().getLocalPart()); + XmlSchemaType type = getXmlSchemaType(argType); + child.setType(type); + } + inputSeq.getItems().add(child); + } + inputElement.setType(inputType); + + XmlSchemaElement outputElement = new XmlSchemaElement(); + outputElement.setQName(new QName(ns, op.getName() + "Response")); + XmlSchemaComplexType outputType = new XmlSchemaComplexType(schema); + outputType.setName(""); + XmlSchemaSequence outputSeq = new XmlSchemaSequence(); + outputType.setParticle(outputSeq); + DataType returnType = op.getOutputType(); + XmlSchemaElement child = new XmlSchemaElement(); + Object logical = returnType.getLogical(); + if (logical instanceof XMLType) { + child.setName(((XMLType)logical).getElementName().getLocalPart()); + XmlSchemaType type = getXmlSchemaType(returnType); + child.setType(type); + } + outputSeq.getItems().add(child); + outputElement.setType(outputType); + + schema.getElements().add(inputElement.getQName(), inputElement); + schema.getElements().add(outputElement.getQName(), outputElement); + + } + */ + + public WSDLFactory getFactory() { + return factory; + } + + public void setFactory(WSDLFactory factory) { + this.factory = factory; + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java new file mode 100644 index 0000000000..f99947a52e --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLDefinitionGenerator.java @@ -0,0 +1,304 @@ +/* + * 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.binding.ws.wsdlgen; + +import java.util.Iterator; + +import javax.wsdl.Binding; +import javax.wsdl.BindingFault; +import javax.wsdl.BindingInput; +import javax.wsdl.BindingOperation; +import javax.wsdl.BindingOutput; +import javax.wsdl.Definition; +import javax.wsdl.Fault; +import javax.wsdl.Input; +import javax.wsdl.Operation; +import javax.wsdl.Output; +import javax.wsdl.Port; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.Types; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.ExtensibilityElement; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPBody; +import javax.wsdl.extensions.soap.SOAPFault; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.wsdl.extensions.soap12.SOAP12Address; +import javax.wsdl.extensions.soap12.SOAP12Binding; +import javax.wsdl.extensions.soap12.SOAP12Body; +import javax.wsdl.extensions.soap12.SOAP12Fault; +import javax.wsdl.extensions.soap12.SOAP12Operation; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; +import javax.xml.namespace.QName; + +import org.w3c.dom.Element; + +/** + * + * @version $Rev: 668025 $ $Date: 2008-06-16 01:06:34 +0100 (Mon, 16 Jun 2008) $ + */ +public class WSDLDefinitionGenerator { + private static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/"; + public static final QName SOAP_ADDRESS = new QName(SOAP_NS, "address"); + private static final QName SOAP_BINDING = new QName(SOAP_NS, "binding"); + private static final QName SOAP_BODY = new QName(SOAP_NS, "body"); + private static final QName SOAP_FAULT = new QName(SOAP_NS, "fault"); + private static final QName SOAP_OPERATION = new QName(SOAP_NS, "operation"); + private static final String SOAP12_NS = "http://schemas.xmlsoap.org/wsdl/soap12/"; + public static final QName SOAP12_ADDRESS = new QName(SOAP12_NS, "address"); + private static final QName SOAP12_BINDING = new QName(SOAP12_NS, "binding"); + private static final QName SOAP12_BODY = new QName(SOAP12_NS, "body"); + private static final QName SOAP12_FAULT = new QName(SOAP12_NS, "fault"); + private static final QName SOAP12_OPERATION = new QName(SOAP12_NS, "operation"); + + private static final String BINDING_SUFFIX = "Binding"; + private static final String SERVICE_SUFFIX = "Service"; + private static final String PORT_SUFFIX = "Port"; + + private boolean requiresSOAP12; + private QName soapAddress; + private QName soapBinding; + private QName soapBody; + private QName soapFault; + private QName soapOperation; + + public WSDLDefinitionGenerator(boolean requiresSOAP12) { + super(); + this.requiresSOAP12 = requiresSOAP12; + soapAddress = requiresSOAP12 ? SOAP12_ADDRESS : SOAP_ADDRESS; + soapBinding = requiresSOAP12 ? SOAP12_BINDING : SOAP_BINDING; + soapBody = requiresSOAP12 ? SOAP12_BODY : SOAP_BODY; + soapFault = requiresSOAP12 ? SOAP12_FAULT : SOAP_FAULT; + soapOperation = requiresSOAP12 ? SOAP12_OPERATION : SOAP_OPERATION; + } + + public Definition cloneDefinition(WSDLFactory factory, Definition definition) throws WSDLException { + Element root = definition.getDocumentationElement(); + root = (Element)root.cloneNode(true); + WSDLReader reader = factory.newWSDLReader(); + return reader.readWSDL(definition.getDocumentBaseURI(), root); + } + + public Types createTypes(Definition definition) { + Types types = definition.createTypes(); + definition.setTypes(types); + return types; + } + + public Binding createBinding(Definition definition, PortType portType) { + try { + Binding binding = definition.createBinding(); + binding.setPortType(portType); + configureBinding(definition, binding, portType); + ExtensibilityElement bindingExtension = + definition.getExtensionRegistry().createExtension(Binding.class, soapBinding); + if (requiresSOAP12) { + ((SOAP12Binding)bindingExtension).setStyle("document"); + ((SOAP12Binding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http"); + } else { + ((SOAPBinding)bindingExtension).setStyle("document"); + ((SOAPBinding)bindingExtension).setTransportURI("http://schemas.xmlsoap.org/soap/http"); + } + binding.addExtensibilityElement(bindingExtension); + return binding; + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + protected void configureBinding(Definition definition, Binding binding, PortType portType) throws WSDLException { + QName portTypeName = portType.getQName(); + if (portTypeName != null) { + // Choose <porttype>Binding if available. If this name is in use, insert + // separating underscores until there is no clash. + for (String suffix = BINDING_SUFFIX; ; suffix = "_" + suffix) { + QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix); + if (definition.getBinding(name) == null) { + binding.setQName(name); + break; + } + } + } + } + + @SuppressWarnings("unchecked") + public void createBindingOperations(Definition definition, Binding binding, PortType portType) { + try { + for (Iterator oi = portType.getOperations().iterator(); oi.hasNext();) { + Operation operation = (Operation)oi.next(); + BindingOperation bindingOperation = createBindingOperation(definition, operation, ""); + binding.addBindingOperation(bindingOperation); + } + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + @SuppressWarnings("unchecked") + public BindingOperation createBindingOperation(Definition definition, Operation operation, String action) + throws WSDLException { + BindingOperation bindingOperation = definition.createBindingOperation(); + bindingOperation.setOperation(operation); + configureBindingOperation(bindingOperation, operation); + ExtensibilityElement operationExtension = + definition.getExtensionRegistry().createExtension(BindingOperation.class, soapOperation); + if (requiresSOAP12) { + ((SOAP12Operation)operationExtension).setSoapActionURI(action); + } else { + ((SOAPOperation)operationExtension).setSoapActionURI(action); + } + bindingOperation.addExtensibilityElement(operationExtension); + if (operation.getInput() != null) { + BindingInput bindingInput = definition.createBindingInput(); + configureBindingInput(bindingInput, operation.getInput()); + ExtensibilityElement inputExtension = + definition.getExtensionRegistry().createExtension(BindingInput.class, soapBody); + if (requiresSOAP12) { + ((SOAP12Body)inputExtension).setUse("literal"); + } else { + ((SOAPBody)inputExtension).setUse("literal"); + } + bindingInput.addExtensibilityElement(inputExtension); + bindingOperation.setBindingInput(bindingInput); + } + if (operation.getOutput() != null) { + BindingOutput bindingOutput = definition.createBindingOutput(); + configureBindingOutput(bindingOutput, operation.getOutput()); + ExtensibilityElement outputExtension = + definition.getExtensionRegistry().createExtension(BindingOutput.class, soapBody); + if (requiresSOAP12) { + ((SOAP12Body)outputExtension).setUse("literal"); + } else { + ((SOAPBody)outputExtension).setUse("literal"); + } + bindingOutput.addExtensibilityElement(outputExtension); + bindingOperation.setBindingOutput(bindingOutput); + } + for (Iterator fi = operation.getFaults().values().iterator(); fi.hasNext();) { + Fault fault = (Fault)fi.next(); + BindingFault bindingFault = definition.createBindingFault(); + ExtensibilityElement faultExtension = + definition.getExtensionRegistry().createExtension(BindingFault.class, soapFault); + configureBindingFault(bindingFault, faultExtension, fault); + bindingFault.addExtensibilityElement(faultExtension); + bindingOperation.addBindingFault(bindingFault); + } + return bindingOperation; + } + + protected void configureBindingOperation(BindingOperation bindingOperation, Operation operation) + throws WSDLException { + bindingOperation.setName(operation.getName()); + } + + protected void configureBindingInput(BindingInput bindingInput, Input input) throws WSDLException { + bindingInput.setName(input.getName()); + } + + protected void configureBindingOutput(BindingOutput bindingOutput, Output output) throws WSDLException { + bindingOutput.setName(output.getName()); + } + + protected void configureBindingFault(BindingFault bindingFault, + ExtensibilityElement faultExtension, + Fault fault) + throws WSDLException { + String faultName = fault.getName(); + bindingFault.setName(faultName); + if (requiresSOAP12) { + ((SOAP12Fault)faultExtension).setName(faultName); + ((SOAP12Fault)faultExtension).setUse("literal"); + } else { + ((SOAPFault)faultExtension).setName(faultName); + ((SOAPFault)faultExtension).setUse("literal"); + } + } + + public Service createService(Definition definition, PortType portType) { + try { + Service service = definition.createService(); + configureService(definition, service, portType); + // createPort(definition, binding, service); + definition.addService(service); + return service; + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + public Service createService(Definition definition, Binding binding) { + try { + Service service = definition.createService(); + configureService(definition, service, binding.getPortType()); + // createPort(definition, binding, service); + definition.addService(service); + return service; + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + protected void configureService(Definition definition, Service service, PortType portType) throws WSDLException { + QName portTypeName = portType.getQName(); + if (portTypeName != null) { + // Choose <porttype>Service if available. If this name is in use, insert + // separating underscores until there is no clash. + for (String suffix = SERVICE_SUFFIX; ; suffix = "_" + suffix) { + QName name = new QName(definition.getTargetNamespace(), portTypeName.getLocalPart() + suffix); + if (definition.getService(name) == null) { + service.setQName(name); + break; + } + } + } + } + + public Port createPort(Definition definition, Binding binding, Service service, String uri) { + try { + Port port = definition.createPort(); + port.setBinding(binding); + configurePort(port, binding); + if (uri != null) { + ExtensibilityElement portExtension = + definition.getExtensionRegistry().createExtension(Port.class, soapAddress); + if (requiresSOAP12) { + ((SOAP12Address)portExtension).setLocationURI(uri); + } else { + ((SOAPAddress)portExtension).setLocationURI(uri); + } + port.addExtensibilityElement(portExtension); + } + service.addPort(port); + return port; + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + protected void configurePort(Port port, Binding binding) throws WSDLException { + if (binding.getPortType() != null && binding.getPortType().getQName() != null) { + port.setName(binding.getPortType().getQName().getLocalPart() + PORT_SUFFIX); + } + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java new file mode 100644 index 0000000000..bf9e22f645 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLGenerationException.java @@ -0,0 +1,54 @@ +/* + * 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.binding.ws.wsdlgen; + +import org.apache.tuscany.sca.monitor.Problem; +import org.osoa.sca.ServiceRuntimeException; + +public class WSDLGenerationException extends ServiceRuntimeException { + private static final long serialVersionUID = 1L; + private Problem problem; + + public WSDLGenerationException() { + super(); + } + + public WSDLGenerationException(String message, Throwable cause) { + super(message, cause); + } + + public WSDLGenerationException(String message) { + super(message); + } + + public WSDLGenerationException(Throwable cause) { + super(cause); + } + + public WSDLGenerationException(String message, Throwable cause, Problem problem) { + super(message, cause); + this.problem = problem; + } + + public Problem getProblem() { + return problem; + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java new file mode 100644 index 0000000000..407877c36d --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/WSDLServiceGenerator.java @@ -0,0 +1,527 @@ +/* + * 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.binding.ws.wsdlgen; + +//FIXME: trim the import list down to what's really needed + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Import; +import javax.wsdl.Port; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.WSDLException; +import javax.wsdl.extensions.ExtensibilityElement; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.wsdl.extensions.soap12.SOAP12Address; +import javax.wsdl.extensions.soap12.SOAP12Binding; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLWriter; +import javax.xml.namespace.QName; +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.dom.DOMSource; + +import org.apache.tuscany.sca.assembly.AbstractContract; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.builder.impl.ProblemImpl; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySetAttachPoint; +import org.apache.tuscany.sca.policy.security.ws.Axis2ConfigParamPolicy; +import org.apache.tuscany.sca.policy.util.PolicyHandler; +import org.apache.tuscany.sca.policy.util.PolicyHandlerTuple; +import org.apache.tuscany.sca.policy.util.PolicyHandlerUtils; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +/** + * WSDLServiceGenerator generates a binding WSDL service document. + * + * @version $Rev$ $Date$ + */ +public class WSDLServiceGenerator { + // the following switch is temporary for debugging + public static boolean printWSDL; // external code sets this to print generated WSDL + + private static final Logger logger = Logger.getLogger(WSDLServiceGenerator.class.getName()); + private static final QName TRANSPORT_JMS_QUALIFIED_INTENT = + new QName("http://www.osoa.org/xmlns/sca/1.0", "transport.jms"); + private static final String DEFAULT_QUEUE_CONNECTION_FACTORY = "TuscanyQueueConnectionFactory"; + private static final String ADDRESS = "Address"; + + private WSDLServiceGenerator() { + // this class has static methods only and cannot be instantiated + } + + /** + * Log a warning message. + * @param problem + */ + private static void logWarning(Problem problem) { + Logger problemLogger = Logger.getLogger(problem.getSourceClassName(), problem.getBundleName()); + if (problemLogger != null){ + problemLogger.logp(Level.WARNING, problem.getSourceClassName(), null, problem.getMessageId(), problem.getMessageParams()); + } else { + logger.severe("Can't get logger " + problem.getSourceClassName()+ " with bundle " + problem.getBundleName()); + } + } + + /** + * Report a warning. + * @param message + * @param binding + * @param parameters + */ + private static void warning(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) { + Problem problem = new ProblemImpl(WSDLServiceGenerator.class.getName(), "wsdlgen-validation-messages", Severity.WARNING, wsBinding, message, (Object[])messageParameters); + if (monitor != null) { + monitor.problem(problem); + } else { + logWarning(problem); + } + } + + /** + * Report an error. + * @param message + * @param binding + * @param parameters + */ + private static void error(Monitor monitor, String message, WebServiceBinding wsBinding, String... messageParameters) { + Problem problem = new ProblemImpl(WSDLServiceGenerator.class.getName(), "wsdlgen-validation-messages", Severity.ERROR, wsBinding, message, (Object[])messageParameters); + if (monitor != null) { + monitor.problem(problem); + } else { + throw new WSDLGenerationException(problem.toString(), null, problem); + } + } + + /** + * Generate a suitably configured WSDL definition + */ + protected static Definition configureWSDLDefinition(WebServiceBinding wsBinding, + Component component, + AbstractContract contract, + Monitor monitor) { + + // For every promoted composite service, the underlying component + // gets a copy of the service with the name prefixed by "$promoted$." + String contractName = (contract instanceof CompositeService ? "$promoted$." : "") + contract.getName(); + + List<Port> ports = new ArrayList<Port>(); + WSDLDefinition wsdlDefinition = wsBinding.getWSDLDefinition(); + if (wsdlDefinition == null) { + return null; + } + Definition def = wsdlDefinition.getDefinition(); + if (wsdlDefinition.getBinding() == null) { + // The WSDL document was provided by the user. Generate a new + // WSDL document with imports from the user-provided document. + WSDLFactory factory = null; + try { + factory = WSDLFactory.newInstance(); + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + Definition newDef = factory.newDefinition(); + + // Construct a target namespace from the base URI of the user's + // WSDL document (is this what we should be using?) and a path + // computed according to the SCA Web Service binding spec. + String nsName = component.getName() + "/" + contractName; + String namespaceURI = null; + try { + URI userTNS = new URI(def.getTargetNamespace()); + namespaceURI = userTNS.resolve("/" + nsName).toString(); + } catch (URISyntaxException e1) { + throw new WSDLGenerationException(e1); + } catch (IllegalArgumentException e2) { + throw new WSDLGenerationException(e2); + } + + // set name and targetNamespace attributes on the definition + String defsName = component.getName() + "." + contractName; + newDef.setQName(new QName(namespaceURI, defsName)); + newDef.setTargetNamespace(namespaceURI); + newDef.addNamespace("tns", namespaceURI); + + // set wsdl namespace prefix on the definition + newDef.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/"); + + // import the service or reference interface portType + List<WSDLDefinition> imports = new ArrayList<WSDLDefinition>(); + Interface interfaze = wsBinding.getBindingInterfaceContract().getInterface(); + if (interfaze instanceof WSDLInterface) { + PortType portType = ((WSDLInterface)interfaze).getPortType(); + boolean ok = importPortType(portType, wsdlDefinition, newDef, imports); + if (!ok) { + error(monitor, "PortTypeNotFound", wsBinding, portType.getQName().toString(), + component.getName(), contract.getName()); + } + } + + // import an existing binding if specified + Binding binding = wsBinding.getBinding(); + if (binding != null) { + boolean ok = importBinding(binding, wsdlDefinition, newDef, imports); + if (ok) { + boolean ok2 = importPortType(binding.getPortType(), wsdlDefinition, newDef, imports); + if (!ok2) { + error(monitor, "PortTypeNotFound", wsBinding, binding.getPortType().getQName().toString(), + component.getName(), contract.getName()); + } + } else { + error(monitor, "BindingNotFound", wsBinding, binding.getQName().toString(), + component.getName(), contract.getName()); + } + } + + // import bindings and portTypes needed by services and ports + QName serviceQName = wsBinding.getServiceName(); + String portName = wsBinding.getPortName(); + if (serviceQName != null) { + Service service = def.getService(serviceQName); + if (portName != null) { + Port port = service.getPort(portName); + Port newPort = copyPort(newDef, port, wsBinding); + if (newPort != null) { + importBinding(port.getBinding(), wsdlDefinition, newDef, imports); + ports.add(newPort); + } else { + error(monitor, "InvalidPort", wsBinding, serviceQName.toString(), portName, + component.getName(), contract.getName()); + } + } else { + for (Object port : service.getPorts().values()) { + Port newPort = copyPort(newDef, (Port)port, wsBinding); + if (newPort != null) { + importBinding(((Port)port).getBinding(), wsdlDefinition, newDef, imports); + ports.add(newPort); + } else { + // not an error, just ignore the port + warning(monitor, "IgnoringPort", wsBinding, serviceQName.toString(), ((Port)port).getName(), + component.getName(), contract.getName()); + } + } + if (ports.size() == 0) { + error(monitor, "NoValidPorts", wsBinding, serviceQName.toString(), + component.getName(), contract.getName()); + } + } + } + + // replace original WSDL definition by the generated definition + def = newDef; + + } else { + // The WSDL definition was generated by Interface2WSDLGenerator. + // Reuse it instead of creating a new definition here. + } + + // add a service and ports to the generated definition + WSDLDefinitionGenerator helper = + new WSDLDefinitionGenerator(BindingWSDLGenerator.requiresSOAP12(wsBinding)); + WSDLInterface wi = (WSDLInterface)wsBinding.getBindingInterfaceContract().getInterface(); + PortType portType = wi.getPortType(); + Service service = helper.createService(def, portType); + if (wsBinding.getBinding() == null && ports.size() == 0) { + Binding binding = helper.createBinding(def, portType); + if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) { + def.addNamespace("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); + } else { + def.addNamespace("soap11", "http://schemas.xmlsoap.org/wsdl/soap/"); + } + helper.createBindingOperations(def, binding, portType); + binding.setUndefined(false); + def.addBinding(binding); + + String endpointURI = computeActualURI(wsBinding, null); + Port port = helper.createPort(def, binding, service, endpointURI); + wsBinding.setService(service); + wsBinding.setPort(port); + } else { + if (ports.size() > 0) { + // there are one or more user-specified valid ports + for (Port port : ports) { + service.addPort(port); + } + if (ports.size() == 1) { + // only one port, so use it + wsBinding.setPort(ports.get(0)); + } else { + // multiple ports, make them all available + wsBinding.setPort(null); + } + } else { + // no valid user-specified ports, so create a suitably configured port + String endpointURI = computeActualURI(wsBinding, null); + Port port = helper.createPort(def, wsBinding.getBinding(), service, endpointURI); + if (BindingWSDLGenerator.requiresSOAP12(wsBinding)) { + def.addNamespace("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); + } else { + def.addNamespace("soap11", "http://schemas.xmlsoap.org/wsdl/soap/"); + } + wsBinding.setPort(port); + } + wsBinding.setService(service); + } + + // for debugging + if (printWSDL) { + try { + System.out.println("Generated WSDL for " + component.getName() + "/" + contractName); + WSDLWriter writer = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLWriter(); + writer.writeWSDL(def, System.out); + } catch (WSDLException e) { + throw new WSDLGenerationException(e); + } + } + + return def; + } + + private static boolean importPortType(PortType portType, + WSDLDefinition wsdlDef, + Definition newDef, + List<WSDLDefinition> imports) { + return addImport(portType.getQName(), PortType.class, wsdlDef, newDef, imports); + } + + private static boolean importBinding(Binding binding, + WSDLDefinition wsdlDef, + Definition newDef, + List<WSDLDefinition> imports) { + boolean ok = addImport(binding.getQName(), Binding.class, wsdlDef, newDef, imports); + if (ok) { + List bindingExtensions = binding.getExtensibilityElements(); + for (final Object extension : bindingExtensions) { + if (extension instanceof SOAPBinding) { + newDef.addNamespace("soap11", "http://schemas.xmlsoap.org/wsdl/soap/"); + } + if (extension instanceof SOAP12Binding) { + newDef.addNamespace("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); + } + } + } + return ok; + } + + private static boolean addImport(QName name, + Class type, + WSDLDefinition wsdlDef, + Definition newDef, + List<WSDLDefinition> imports) { + String namespace = name.getNamespaceURI(); + if (newDef.getImports(namespace) == null) { + WSDLDefinition impDef = findDefinition(wsdlDef, name, type); + if (impDef != null) { + Import imp = newDef.createImport(); + imp.setNamespaceURI(namespace); + imp.setLocationURI(impDef.getURI().toString()); + imp.setDefinition(impDef.getDefinition()); + newDef.addNamespace("ns" + imports.size(), namespace); + newDef.addImport(imp); + imports.add(impDef); + return true; + } else { + // import was not added because element not found + return false; + } + } + return true; + } + + private static WSDLDefinition findDefinition(WSDLDefinition wsdlDef, QName name, Class type) { + if (wsdlDef == null || name == null) { + return wsdlDef; + } + if (wsdlDef.getURI() != null) { // not a facade + Definition def = wsdlDef.getDefinition(); + Map types = type == PortType.class ? def.getPortTypes() : def.getBindings(); + if (types.get(name) != null) { + return wsdlDef; + } + } + for (WSDLDefinition impDef : wsdlDef.getImportedDefinitions()) { + WSDLDefinition d = findDefinition(impDef, name, type); + if (d != null) { + return d; + } + } + return null; + } + + private static Port copyPort(Definition def, Port port, WebServiceBinding wsBinding) { + Port newPort = def.createPort(); + newPort.setName(port.getName()); + newPort.setBinding(port.getBinding()); + List portExtensions = port.getExtensibilityElements(); + for (final Object extension : portExtensions) { + ExtensibilityElement newExt = null; + if (extension instanceof SOAPAddress) { + def.addNamespace("soap11", "http://schemas.xmlsoap.org/wsdl/soap/"); + try { + newExt = def.getExtensionRegistry().createExtension( + Port.class, WSDLDefinitionGenerator.SOAP_ADDRESS); + } catch (WSDLException e) { + } + String uri = computeActualURI(wsBinding, port); + ((SOAPAddress)newExt).setLocationURI(uri); + newPort.addExtensibilityElement(newExt); + } else if (extension instanceof SOAP12Address) { + def.addNamespace("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/"); + try { + newExt = def.getExtensionRegistry().createExtension( + Port.class, WSDLDefinitionGenerator.SOAP12_ADDRESS); + } catch (WSDLException e) { + } + String uri = computeActualURI(wsBinding, port); + ((SOAP12Address)newExt).setLocationURI(uri); + newPort.addExtensibilityElement(newExt); + } else { + // we don't support ports with other extensibility elements such as HTTPAddress + return null; + } + } + return newPort; + } + + /** + * Compute the endpoint URI based on section 2.1.1 of the WS binding Specification 1. + * The URIs in the endpoint(s) of the referenced WSDL, which may be relative + * 2. The URI specified by the wsa:Address element of the + * wsa:EndpointReference, which may be relative 3. The explicitly stated URI + * in the "uri" attribute of the binding.ws element, which may be relative, + * 4. The implicit URI as defined by in section 1.7 in the SCA Assembly Specification + * If the <binding.ws> has no wsdlElement but does have a uri attribute then + * the uri takes precedence over any implicitly used WSDL. + * + */ + private static String computeActualURI(WebServiceBinding wsBinding, Port port) { + + URI eprURI = null; + if (wsBinding.getEndPointReference() != null) { + eprURI = getEPR(wsBinding); + } + + URI wsdlURI = null; + if (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null) { + // <binding.ws> explicitly points at a WSDL port, may be a relative URI + wsdlURI = getEndpoint(port); + } + + // if the WSDL port/endpoint has an absolute URI use that + if (wsdlURI != null && wsdlURI.isAbsolute()) { + return wsdlURI.toString(); + } + + // if the wsa:EndpointReference has an address element with an absolute URI use that + if (eprURI != null && eprURI.isAbsolute()) { + return eprURI.toString(); + } + + // either there is no WSDL port endpoint URI or that URI is relative + String actualURI = wsBinding.getURI(); + if (eprURI != null && eprURI.toString().length() != 0) { + // there is a relative URI in the binding EPR + actualURI = actualURI + "/" + eprURI; + } + + if (wsdlURI != null && wsdlURI.toString().length() != 0) { + // there is a relative URI in the WSDL port + actualURI = actualURI + "/" + wsdlURI; + } + + if (actualURI != null) { + actualURI = URI.create(actualURI).normalize().toString(); + } + + return actualURI; + } + + private static URI getEPR(WebServiceBinding wsBinding) { + NodeList nodeList = wsBinding.getEndPointReference().getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node childNode = nodeList.item(i); + if (childNode instanceof Element && ADDRESS.equals(childNode.getLocalName())) { + NodeList addrNodes = childNode.getChildNodes(); + for (int j = 0; j < addrNodes.getLength(); j++) { + Node addrNode = addrNodes.item(j); + if (addrNode instanceof Text) { + return URI.create(((Text)addrNode).getWholeText()); + } + } + } + } + return null; + } + + /** + * Returns the endpoint of a given port. + */ + private static URI getEndpoint(Port wsdlPort) { + if (wsdlPort != null) { + List<?> wsdlPortExtensions = wsdlPort.getExtensibilityElements(); + for (Object extension : wsdlPortExtensions) { + if (extension instanceof SOAPAddress) { + String uri = ((SOAPAddress)extension).getLocationURI(); + return (uri == null || "".equals(uri)) ? null : URI.create(uri); + } + if (extension instanceof SOAP12Address) { + SOAP12Address address = (SOAP12Address)extension; + String uri = address.getLocationURI(); + return (uri == null || "".equals(uri)) ? null : URI.create(uri); + } + } + } + return null; + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/main/resources/wsdlgen-validation-messages.properties b/java/sca/modules/binding-ws-wsdlgen/src/main/resources/wsdlgen-validation-messages.properties new file mode 100644 index 0000000000..91e99f1891 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/main/resources/wsdlgen-validation-messages.properties @@ -0,0 +1,30 @@ +# +# +# 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. +# +# +WsdlGenProblem = Unable to generate WSDL for {0}/{1} +WsdlGenException = Exception while generating WSDL for {0}/{1} +UnexpectedException = Exception thrown was: {0} +MissingInterfaceContract = No interface contract for {0}/{1} +InterfaceNotRemotable = Interface not remotable: {0} +IgnoringPort = Port {0}/{1} in {2}/{3} is not supported and was ignored +PortTypeNotFound = PortType {0} in {1}/{2} was not found +BindingNotFound = Binding {0} in {1}/{2} was not found +InvalidPort = Port {0}/{1} in {2}/{3} is not supported +NoValidPorts = No valid ports for service {0} in {1}/{2} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGeneratorTestCase.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGeneratorTestCase.java new file mode 100644 index 0000000000..e474c7a318 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/BindingWSDLGeneratorTestCase.java @@ -0,0 +1,86 @@ +/* + * 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.binding.ws.wsdlgen; + +import java.util.List; +import java.util.Map; + +import javax.wsdl.Definition; +import javax.wsdl.Operation; +import javax.wsdl.PortType; + +import junit.framework.TestCase; + +import org.apache.tuscany.sca.contribution.DefaultModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.databinding.processor.DataBindingJavaInterfaceProcessor; +import org.apache.tuscany.sca.databinding.DefaultDataBindingExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; +import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract; +import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSFaultExceptionMapper; +import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSJavaInterfaceProcessor; +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.xml.XSDModelResolver; +import org.osoa.sca.annotations.Remotable; + +/** + * + * @version $Rev$ $Date$ + */ +public class BindingWSDLGeneratorTestCase extends TestCase { + + public void testCreateWSDLInterfaceContract() throws InvalidInterfaceException { + DefaultModelFactoryExtensionPoint modelFactories = new DefaultModelFactoryExtensionPoint(); + WSDLFactory wsdlFactory = modelFactories.getFactory(WSDLFactory.class); + XSDFactory xsdFactory = modelFactories.getFactory(XSDFactory.class); + DefaultJavaInterfaceFactory factory = new DefaultJavaInterfaceFactory(); + JavaInterfaceContract javaIC = factory.createJavaInterfaceContract(); + JavaInterface iface = factory.createJavaInterface(HelloWorld.class); + DefaultDataBindingExtensionPoint dataBindings = new DefaultDataBindingExtensionPoint(); + JAXWSFaultExceptionMapper faultExceptionMapper = new JAXWSFaultExceptionMapper(dataBindings, null); + new JAXWSJavaInterfaceProcessor(dataBindings, faultExceptionMapper, null).visitInterface(iface); + new DataBindingJavaInterfaceProcessor(dataBindings).visitInterface(iface); + javaIC.setInterface(iface); + WSDLInterfaceContract wsdlIC = BindingWSDLGenerator.createWSDLInterfaceContract(javaIC, false, new XSDModelResolver(null, null), dataBindings, wsdlFactory, xsdFactory, null); + assertNotNull(wsdlIC); + WSDLInterface wsdlInterface = (WSDLInterface)wsdlIC.getInterface(); + assertNotNull(wsdlInterface); + assertEquals(1, wsdlInterface.getOperations().size()); + assertEquals("sayHello", wsdlInterface.getOperations().get(0).getName()); + assertNotNull(wsdlInterface.getPortType()); + + JavaInterfaceContract javaIC2 = factory.createJavaInterfaceContract(); + JavaInterface iface2 = factory.createJavaInterface(TestJavaInterface.class); + new JAXWSJavaInterfaceProcessor(dataBindings, faultExceptionMapper, null).visitInterface(iface2); + new DataBindingJavaInterfaceProcessor(dataBindings).visitInterface(iface2); + javaIC2.setInterface(iface2); + WSDLInterfaceContract wsdlIC2 = BindingWSDLGenerator.createWSDLInterfaceContract(javaIC2, false, new XSDModelResolver(null, null), dataBindings, wsdlFactory, xsdFactory, null); + assertNotNull(wsdlIC2); + } + +} + +@Remotable +interface HelloWorld { + String sayHello(String s); +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGeneratorTestCase.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGeneratorTestCase.java new file mode 100644 index 0000000000..f1e12f8ce0 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGeneratorTestCase.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.binding.ws.wsdlgen; + +import java.io.StringWriter; + +import javax.wsdl.Definition; +import javax.wsdl.xml.WSDLWriter; + +import org.apache.tuscany.sca.contribution.DefaultModelFactoryExtensionPoint; +import org.apache.tuscany.sca.core.databinding.processor.DataBindingJavaInterfaceProcessor; +import org.apache.tuscany.sca.databinding.DefaultDataBindingExtensionPoint; +import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory; +import org.apache.tuscany.sca.interfacedef.java.JavaInterface; +import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSFaultExceptionMapper; +import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSJavaInterfaceProcessor; +import org.apache.tuscany.sca.interfacedef.wsdl.DefaultWSDLFactory; +import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; +import org.apache.tuscany.sca.xsd.DefaultXSDFactory; +import org.apache.tuscany.sca.xsd.xml.XSDModelResolver; +import org.junit.Test; + +/** + * @version $Rev$ $Date$ + */ +public class Interface2WSDLGeneratorTestCase { + + @Test + public void testGenerate() throws Exception { + DefaultJavaInterfaceFactory iFactory = new DefaultJavaInterfaceFactory(); + JavaInterface iface = iFactory.createJavaInterface(TestJavaInterface.class); + DefaultDataBindingExtensionPoint dataBindings = new DefaultDataBindingExtensionPoint(); + JAXWSFaultExceptionMapper faultExceptionMapper = new JAXWSFaultExceptionMapper(dataBindings, null); + new JAXWSJavaInterfaceProcessor(dataBindings, faultExceptionMapper, null).visitInterface(iface); + new DataBindingJavaInterfaceProcessor(dataBindings).visitInterface(iface); + DefaultModelFactoryExtensionPoint modelFactories = new DefaultModelFactoryExtensionPoint(); + WSDLDefinition wsdlDefinition = new DefaultWSDLFactory(modelFactories).createWSDLDefinition(); + DefaultXSDFactory factory = new DefaultXSDFactory(); + Interface2WSDLGenerator generator = new Interface2WSDLGenerator(false, new XSDModelResolver(null, null), dataBindings, factory, null); + Definition definition = generator.generate(iface, wsdlDefinition); + + // print the generated WSDL file and inline schemas + WSDLWriter writer = generator.getFactory().newWSDLWriter(); + StringWriter sw = new StringWriter(); + writer.writeWSDL(definition, sw); + System.out.println(sw.toString()); + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestException.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestException.java new file mode 100644 index 0000000000..1e4f802e01 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestException.java @@ -0,0 +1,47 @@ +/* + * 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.binding.ws.wsdlgen; + +/** + * + * @version $Rev$ $Date$ + */ +public class TestException extends Exception { + + private String userdata; + + public TestException(String message) { + super(message); + } + + public TestException(String message, String userdata) { + super(message); + this.userdata = userdata; + } + + public String getUserdata() { + return userdata; + } + + public void setUserdata(String userdata) { + this.userdata = userdata; + } + +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFault.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFault.java new file mode 100644 index 0000000000..da2c285bac --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFault.java @@ -0,0 +1,46 @@ +/* + * 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.binding.ws.wsdlgen; + +import javax.xml.ws.WebFault; + +/** + * + * @version $Rev$ $Date$ + */ +@WebFault(faultBean="org.apache.tuscany.sca.binding.ws.wsdlgen.TestFaultBean") +public class TestFault extends Exception { + + private TestFaultBean bean; + + public TestFault(TestFaultBean bean, String message) { + super(message); + this.bean = bean; + } + + public TestFault(TestFaultBean bean, String message, Throwable cause) { + super(message, cause); + this.bean = bean; + } + + public TestFaultBean getFaultInfo() { + return bean; + } +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFaultBean.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFaultBean.java new file mode 100644 index 0000000000..64cce0e49d --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestFaultBean.java @@ -0,0 +1,54 @@ +/* + * 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.binding.ws.wsdlgen; + +/** + * + * @version $Rev$ $Date$ + */ +public class TestFaultBean { + private String lastName; + private String firstName; + private float age; + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public float getAge() { + return age; + } + + public void setAge(float age) { + this.age = age; + } +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaClass.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaClass.java new file mode 100644 index 0000000000..909d1f4c49 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaClass.java @@ -0,0 +1,30 @@ +/* + * 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.binding.ws.wsdlgen; + +/** + * + * @version $Rev$ $Date$ + */ +public class TestJavaClass { + public String name; + public int number; + public float balance; +} diff --git a/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaInterface.java b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaInterface.java new file mode 100644 index 0000000000..9635d65f99 --- /dev/null +++ b/java/sca/modules/binding-ws-wsdlgen/src/test/java/org/apache/tuscany/sca/binding/ws/wsdlgen/TestJavaInterface.java @@ -0,0 +1,57 @@ +/* + * 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.binding.ws.wsdlgen; + +import javax.jws.WebMethod; +import javax.jws.WebService; + +import org.osoa.sca.annotations.OneWay; +import org.osoa.sca.annotations.Remotable; + +/** + * + * @version $Rev$ $Date$ + */ +@Remotable +@WebService +public interface TestJavaInterface { + String m1(String str); + + @OneWay + @WebMethod + void m2(int i); + + @WebMethod + String m3(); + + void m4(); + + @WebMethod + String m5(String str, int i); + + @WebMethod(exclude = true) + void dummy(); + + @WebMethod + void m6(TestJavaClass info) throws TestException; + + @WebMethod + void m7(TestJavaClass info) throws TestFault; +} diff --git a/java/sca/modules/binding-ws-xml/pom.xml b/java/sca/modules/binding-ws-xml/pom.xml index f4499d483e..6a3151cd04 100644 --- a/java/sca/modules/binding-ws-xml/pom.xml +++ b/java/sca/modules/binding-ws-xml/pom.xml @@ -55,6 +55,12 @@ <dependency> <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-binding-ws-wsdlgen</artifactId> + <version>1.4-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> <artifactId>tuscany-interface-wsdl</artifactId> <version>1.4-SNAPSHOT</version> </dependency> diff --git a/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/BindingBuilderImpl.java b/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/BindingBuilderImpl.java new file mode 100644 index 0000000000..f2376231ab --- /dev/null +++ b/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/BindingBuilderImpl.java @@ -0,0 +1,51 @@ +/* + * 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.binding.ws.xml; + +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.wsdlgen.BindingWSDLGenerator; +import org.apache.tuscany.sca.assembly.AbstractContract; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.builder.BindingBuilder; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A factory for the calculated WSDL document needed by Web Service bindings. + * + * @version $Rev$ $Date$ + */ +public class BindingBuilderImpl implements BindingBuilder { + + private ExtensionPointRegistry extensionPoints; + + public BindingBuilderImpl(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + } + + /** + * Create a calculated WSDL document and save it in the Web Service binding. + */ + public void build(Component component, AbstractContract contract, Binding binding, Monitor monitor) { + BindingWSDLGenerator.generateWSDL(component, contract, (WebServiceBinding)binding, extensionPoints, monitor); + } + +} diff --git a/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/WebServiceBindingProcessor.java b/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/WebServiceBindingProcessor.java index a1b4a51c9f..c472caac3a 100644 --- a/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/WebServiceBindingProcessor.java +++ b/java/sca/modules/binding-ws-xml/src/main/java/org/apache/tuscany/sca/binding/ws/xml/WebServiceBindingProcessor.java @@ -47,6 +47,8 @@ import org.apache.tuscany.sca.contribution.resolver.ModelResolver; import org.apache.tuscany.sca.contribution.service.ContributionReadException; import org.apache.tuscany.sca.contribution.service.ContributionResolveException; import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory; @@ -54,6 +56,7 @@ import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLObject; import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.MonitorFactory; import org.apache.tuscany.sca.monitor.Problem; import org.apache.tuscany.sca.monitor.Problem.Severity; import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory; @@ -66,6 +69,7 @@ import org.apache.tuscany.sca.policy.PolicyFactory; */ public class WebServiceBindingProcessor implements StAXArtifactProcessor<WebServiceBinding>, WebServiceConstants { + private ExtensionPointRegistry extensionPoints; private WSDLFactory wsdlFactory; private WebServiceBindingFactory wsFactory; private PolicyFactory policyFactory; @@ -74,13 +78,19 @@ public class WebServiceBindingProcessor implements StAXArtifactProcessor<WebServ private ConfiguredOperationProcessor configuredOperationProcessor; private Monitor monitor; - public WebServiceBindingProcessor(ModelFactoryExtensionPoint modelFactories, Monitor monitor) { + public WebServiceBindingProcessor(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; + ModelFactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(ModelFactoryExtensionPoint.class); this.policyFactory = modelFactories.getFactory(PolicyFactory.class); this.wsFactory = new DefaultWebServiceBindingFactory(); this.wsdlFactory = modelFactories.getFactory(WSDLFactory.class); this.policyProcessor = new PolicyAttachPointProcessor(policyFactory); this.intentAttachPointTypeFactory = modelFactories.getFactory(IntentAttachPointTypeFactory.class); - this.monitor = monitor; + UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class); + MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class); + if (monitorFactory != null) { + this.monitor = monitorFactory.createMonitor(); + } this.configuredOperationProcessor = new ConfiguredOperationProcessor(modelFactories, this.monitor); } @@ -121,6 +131,7 @@ public class WebServiceBindingProcessor implements StAXArtifactProcessor<WebServ bindingType.setUnresolved(true); ((PolicySetAttachPoint)wsBinding).setType(bindingType);*/ wsBinding.setUnresolved(true); + wsBinding.setBuilder(new BindingBuilderImpl(extensionPoints)); // Read policies policyProcessor.readPolicies(wsBinding, reader); diff --git a/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/WebServiceBinding.java b/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/WebServiceBinding.java index d8f50e962c..0d07a55a14 100644 --- a/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/WebServiceBinding.java +++ b/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/WebServiceBinding.java @@ -24,6 +24,7 @@ import javax.wsdl.Service; import javax.xml.namespace.QName; import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; import org.w3c.dom.Element; @@ -34,7 +35,7 @@ import org.w3c.dom.Element; * * @version $Rev$ $Date$ */ -public interface WebServiceBinding extends Binding { +public interface WebServiceBinding extends Binding, BindingBuilderExtension { /** * Sets the WSDL location. diff --git a/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java b/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java index df03dbf5d4..26857abe83 100644 --- a/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java +++ b/java/sca/modules/binding-ws/src/main/java/org/apache/tuscany/sca/binding/ws/impl/WebServiceBindingImpl.java @@ -31,6 +31,7 @@ import javax.xml.namespace.QName; import org.apache.tuscany.sca.assembly.ConfiguredOperation; import org.apache.tuscany.sca.assembly.Extensible; import org.apache.tuscany.sca.assembly.OperationsConfigurator; +import org.apache.tuscany.sca.assembly.builder.BindingBuilder; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; @@ -71,6 +72,7 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySetAttachPoint, private InterfaceContract bindingInterfaceContract; private Element endPointReference; private Definition generatedWSDLDocument; + private BindingBuilder builder; protected WebServiceBindingImpl() { } @@ -283,6 +285,14 @@ class WebServiceBindingImpl implements WebServiceBinding, PolicySetAttachPoint, this.generatedWSDLDocument = definition; } + public BindingBuilder getBuilder() { + return builder; + } + + public void setBuilder(BindingBuilder builder) { + this.builder = builder; + } + public void setPolicySets(List<PolicySet> policySets) { this.policySets = policySets; } diff --git a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java index fd8998447d..5b8ad81545 100644 --- a/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java +++ b/java/sca/modules/core/src/main/java/org/apache/tuscany/sca/core/context/CallableReferenceImpl.java @@ -34,6 +34,7 @@ import org.apache.tuscany.sca.assembly.ComponentService; import org.apache.tuscany.sca.assembly.OptimizableBinding; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.assembly.builder.BindingBuilderExtension; import org.apache.tuscany.sca.core.assembly.CompositeActivator; import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl; import org.apache.tuscany.sca.core.assembly.EndpointReferenceImpl; @@ -344,6 +345,9 @@ public class CallableReferenceImpl<B> implements CallableReference<B>, Externali } this.businessInterface = (Class<B>)javaInterface.getJavaClass(); } + if (binding instanceof BindingBuilderExtension) { + ((BindingBuilderExtension)binding).getBuilder().build(component, reference, binding, null); + } this.proxyFactory = compositeActivator.getProxyFactory(); } } else { |