001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.soap.wsdl;
018
019 import java.net.URI;
020 import java.util.Arrays;
021 import java.util.HashSet;
022
023 import org.apache.servicemix.soap.api.model.Binding;
024 import org.apache.servicemix.soap.api.model.wsdl2.Wsdl2Message.ContentModel;
025 import org.apache.servicemix.soap.bindings.http.impl.Wsdl2HttpBindingImpl;
026 import org.apache.servicemix.soap.bindings.http.impl.Wsdl2HttpHeaderImpl;
027 import org.apache.servicemix.soap.bindings.http.impl.Wsdl2HttpMessageImpl;
028 import org.apache.servicemix.soap.bindings.http.impl.Wsdl2HttpOperationImpl;
029 import org.apache.woden.internal.wsdl20.Constants;
030 import org.apache.woden.internal.wsdl20.extensions.http.HTTPConstants;
031 import org.apache.woden.wsdl20.BindingMessageReference;
032 import org.apache.woden.wsdl20.BindingOperation;
033 import org.apache.woden.wsdl20.Endpoint;
034 import org.apache.woden.wsdl20.Interface;
035 import org.apache.woden.wsdl20.InterfaceFault;
036 import org.apache.woden.wsdl20.InterfaceFaultReference;
037 import org.apache.woden.wsdl20.InterfaceMessageReference;
038 import org.apache.woden.wsdl20.InterfaceOperation;
039 import org.apache.woden.wsdl20.enumeration.Direction;
040 import org.apache.woden.wsdl20.extensions.ComponentExtensions;
041 import org.apache.woden.wsdl20.extensions.http.HTTPBindingMessageReferenceExtensions;
042 import org.apache.woden.wsdl20.extensions.http.HTTPBindingOperationExtensions;
043 import org.apache.woden.wsdl20.extensions.http.HTTPHeader;
044 import org.apache.woden.xml.XMLAttr;
045 import org.apache.ws.commons.schema.XmlSchemaElement;
046
047 public class Wsdl2BindingFactory {
048
049 public static URI HTTP_BINDING_TYPE = URI.create("http://www.w3.org/2006/01/wsdl/http");
050 public static URI XSD_2001_SYSTEM = URI.create(Constants.TYPE_XSD_2001);
051
052 public static Binding<?> createBinding(Endpoint wsdlEndpoint) {
053 if (HTTP_BINDING_TYPE.equals(wsdlEndpoint.getBinding().getType())) {
054 return createWsdl2HttpBinding(wsdlEndpoint);
055 }
056 return null;
057 }
058
059 private static Binding<?> createWsdl2HttpBinding(Endpoint wsdlEndpoint) {
060 Wsdl2HttpBindingImpl binding = new Wsdl2HttpBindingImpl();
061 binding.setLocation(wsdlEndpoint.getAddress().toString());
062 Interface wsdlInterface = wsdlEndpoint.getBinding().getInterface();
063 InterfaceOperation[] wsdlOperations = wsdlInterface.getInterfaceOperations();
064 for (int i = 0; i < wsdlOperations.length; i++) {
065 // Retrieve binding and extension
066 InterfaceOperation wsdlOperation = wsdlOperations[i];
067 BindingOperation wsdlBindingOperation = findBindingOperation(wsdlEndpoint.getBinding(), wsdlOperation);
068 HTTPBindingOperationExtensions opExt = wsdlBindingOperation != null ? (HTTPBindingOperationExtensions) wsdlBindingOperation.getComponentExtensionsForNamespace(ComponentExtensions.URI_NS_HTTP) : null;
069 // Create operation
070 Wsdl2HttpOperationImpl operation = new Wsdl2HttpOperationImpl();
071 // Standard WSDL2 attributes
072 operation.setName(wsdlOperation.getName());
073 operation.setMep(wsdlOperation.getMessageExchangePattern());
074 operation.setStyle(new HashSet<URI>(Arrays.asList(wsdlOperation.getStyle())));
075 // HTTP extensions
076 if (opExt != null) {
077 operation.setHttpInputSerialization(opExt.getHttpInputSerialization());
078 operation.setHttpOutputSerialization(opExt.getHttpOutputSerialization());
079 operation.setHttpFaultSerialization(opExt.getHttpFaultSerialization());
080 operation.setHttpLocation(extractLocation(wsdlBindingOperation));
081 operation.setHttpMethod(opExt.getHttpMethod());
082 operation.setHttpTransferCodingDefault(opExt.getHttpTransferCodingDefault());
083 operation.setHttpLocationIgnoreUncited(opExt.isHttpLocationIgnoreUncited());
084 }
085 // Messages
086 InterfaceMessageReference[] iMsgRefs = wsdlOperation.getInterfaceMessageReferences();
087 for (int j = 0; j < iMsgRefs.length; j++) {
088 // Retrieve binding and extension
089 InterfaceMessageReference iMsgRef = iMsgRefs[j];
090 BindingMessageReference bMsgRef = findBindingMessage(wsdlBindingOperation, iMsgRef);
091 HTTPBindingMessageReferenceExtensions msgExt = bMsgRef != null ? (HTTPBindingMessageReferenceExtensions) bMsgRef.getComponentExtensionsForNamespace(ComponentExtensions.URI_NS_HTTP) : null;
092 // Create message
093 Wsdl2HttpMessageImpl message = new Wsdl2HttpMessageImpl();
094 // Standard WSDL2 attributes
095 message.setContentModel(ContentModel.parse(iMsgRef.getMessageContentModel()));
096 message.setElementName(iMsgRef.getElementDeclaration().getName());
097 if (!XSD_2001_SYSTEM.equals(iMsgRef.getElementDeclaration().getSystem())) {
098 throw new IllegalStateException("Unsupported type system: " + iMsgRef.getElementDeclaration().getSystem());
099 }
100 if (Constants.API_APACHE_WS_XS.equals(iMsgRef.getElementDeclaration().getContentModel())) {
101 XmlSchemaElement xsEl = (XmlSchemaElement) iMsgRef.getElementDeclaration().getContent();
102 message.setElementDeclaration(xsEl);
103 }
104 // HTTP extensions
105 if (msgExt != null) {
106 message.setHttpTransferCoding(msgExt.getHttpTransferCoding());
107 HTTPHeader[] headers = msgExt.getHttpHeaders();
108 for (int k = 0; k < headers.length; k++) {
109 Wsdl2HttpHeaderImpl h = new Wsdl2HttpHeaderImpl();
110 h.setName(headers[k].getName());
111 h.setRequired(headers[k].isRequired() ? headers[k].isRequired().booleanValue() : false);
112 if (!XSD_2001_SYSTEM.equals(headers[k].getTypeDefinition().getSystem())) {
113 throw new IllegalStateException("Unsupported type system: " + headers[k].getTypeDefinition().getSystem());
114 }
115 h.setType(headers[k].getTypeDefinition().getName());
116 message.addHttpHeader(h);
117 }
118 }
119 // Add the message
120 if (iMsgRef.getDirection() == Direction.IN) {
121 operation.setInput(message);
122 } else if (iMsgRef.getDirection() == Direction.OUT) {
123 operation.setOutput(message);
124 } else {
125 throw new IllegalStateException("Unsupported message direction: " + iMsgRef.getDirection());
126 }
127 }
128 // Faults
129 InterfaceFaultReference[] faults = wsdlOperation.getInterfaceFaultReferences();
130 for (int j = 0; j < faults.length; j++) {
131 // TODO: handle interface faults references
132 }
133 // Add the operation
134 binding.addOperation(operation);
135 }
136 // Faults
137 InterfaceFault[] faults = wsdlInterface.getInterfaceFaults();
138 for (int i = 0; i < faults.length; i++) {
139 // TODO: handle interface faults
140 }
141 // Return the complete binding
142 return binding;
143 }
144
145 private static BindingMessageReference findBindingMessage(BindingOperation wsdlBindingOperation, InterfaceMessageReference iMsgRef) {
146 BindingMessageReference[] bMsgRefs = wsdlBindingOperation.getBindingMessageReferences();
147 for (int i = 0; i < bMsgRefs.length; i++) {
148 if (bMsgRefs[i].getInterfaceMessageReference() == iMsgRef) {
149 return bMsgRefs[i];
150 }
151 }
152 return null;
153 }
154
155 private static BindingOperation findBindingOperation(org.apache.woden.wsdl20.Binding binding, InterfaceOperation operation) {
156 BindingOperation[] bindingOps = binding.getBindingOperations();
157 for (int i = 0; i < bindingOps.length; i++) {
158 if (bindingOps[i].getInterfaceOperation() == operation) {
159 return bindingOps[i];
160 }
161 }
162 return null;
163 }
164
165 private static String extractLocation(BindingOperation bOperation) {
166 String location = null;
167 if (bOperation != null) {
168 XMLAttr attr = bOperation.toElement().getExtensionAttribute(HTTPConstants.Q_ATTR_LOCATION);
169 if (attr != null) {
170 location = attr.toExternalForm();
171 }
172 }
173 return location;
174 }
175 }