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.util.Collection;
020    import java.util.Iterator;
021    import java.util.List;
022    
023    import javax.wsdl.BindingInput;
024    import javax.wsdl.BindingOperation;
025    import javax.wsdl.BindingOutput;
026    import javax.wsdl.Fault;
027    import javax.wsdl.Input;
028    import javax.wsdl.Operation;
029    import javax.wsdl.OperationType;
030    import javax.wsdl.Output;
031    import javax.wsdl.Part;
032    import javax.wsdl.Port;
033    import javax.wsdl.PortType;
034    import javax.wsdl.extensions.ExtensibilityElement;
035    import javax.wsdl.extensions.soap.SOAPAddress;
036    import javax.wsdl.extensions.soap.SOAPBinding;
037    import javax.wsdl.extensions.soap.SOAPBody;
038    import javax.wsdl.extensions.soap.SOAPHeader;
039    import javax.wsdl.extensions.soap.SOAPOperation;
040    import javax.xml.namespace.QName;
041    
042    import org.apache.servicemix.soap.bindings.soap.Soap11;
043    import org.apache.servicemix.soap.bindings.soap.impl.Wsdl1SoapBindingImpl;
044    import org.apache.servicemix.soap.bindings.soap.impl.Wsdl1SoapMessageImpl;
045    import org.apache.servicemix.soap.bindings.soap.impl.Wsdl1SoapOperationImpl;
046    import org.apache.servicemix.soap.bindings.soap.impl.Wsdl1SoapPartImpl;
047    import org.apache.servicemix.soap.bindings.soap.model.wsdl1.Wsdl1SoapBinding;
048    import org.apache.servicemix.soap.bindings.soap.model.wsdl1.Wsdl1SoapBinding.Style;
049    import org.apache.servicemix.soap.interceptors.jbi.JbiConstants;
050    
051    public class Wsdl1Soap11BindingFactory {
052    
053        public static Wsdl1SoapBinding createWsdl1SoapBinding(Port wsdlPort) {
054            Wsdl1SoapBindingImpl binding = new Wsdl1SoapBindingImpl(Soap11.getInstance());
055            // Find infos from port
056            for (Iterator iter = wsdlPort.getExtensibilityElements().iterator(); iter.hasNext();) {
057                ExtensibilityElement element = (ExtensibilityElement) iter.next();
058                if (element instanceof SOAPAddress) {
059                    SOAPAddress soapAddress = (SOAPAddress) element;
060                    binding.setLocationURI(soapAddress.getLocationURI());
061                } else {
062                    //throw new IllegalStateException("Unrecognized extension: " + QNameUtil.toString(element.getElementType()));
063                }
064            }
065            javax.wsdl.Binding wsdlBinding = wsdlPort.getBinding();
066            for (Iterator iter = wsdlBinding.getExtensibilityElements().iterator(); iter.hasNext();) {
067                ExtensibilityElement element = (ExtensibilityElement) iter.next();
068                if (element instanceof SOAPBinding) {
069                    SOAPBinding soapBinding = (SOAPBinding) element;
070                    binding.setTransportURI(soapBinding.getTransportURI());
071                    binding.setStyle(getStyle(soapBinding.getStyle()));
072                } else {
073                    //throw new IllegalStateException("Unrecognized extension: " + QNameUtil.toString(element.getElementType()));
074                }
075            }
076            PortType wsdlPortType = wsdlBinding.getPortType();
077            for (Iterator iter = wsdlPortType.getOperations().iterator(); iter.hasNext();) {
078                Operation wsdlOperation = (Operation) iter.next();
079                BindingOperation wsdlBindingOperation = wsdlBinding.getBindingOperation(wsdlOperation.getName(), null, null);
080                SOAPOperation wsdlSoapOperation = WSDLUtils.getExtension(wsdlBindingOperation, SOAPOperation.class);
081                Wsdl1SoapOperationImpl operation = new Wsdl1SoapOperationImpl();
082                operation.setName(new QName(wsdlPortType.getQName().getNamespaceURI(), wsdlOperation.getName()));
083                if (wsdlSoapOperation != null) {
084                    operation.setSoapAction(wsdlSoapOperation.getSoapActionURI());
085                    operation.setStyle(getStyle(wsdlSoapOperation.getStyle()));
086                } else {
087                    operation.setSoapAction("");
088                }
089                if (operation.getStyle() == null) {
090                    operation.setStyle(binding.getStyle() != null ? binding.getStyle() : Style.DOCUMENT);
091                }
092                if (wsdlOperation.getStyle() == OperationType.ONE_WAY) {
093                    operation.setMep(JbiConstants.IN_ONLY);
094                } else if (wsdlOperation.getStyle() == OperationType.REQUEST_RESPONSE) {
095                    operation.setMep(JbiConstants.IN_OUT);
096                }
097                
098                // Create input
099                createInput(operation, wsdlBindingOperation);
100                // Create output
101                createOutput(operation, wsdlBindingOperation);
102                // Create faults
103                Collection faults = wsdlOperation.getFaults().values();
104                for (Iterator itFault = faults.iterator(); itFault.hasNext();) {
105                    Fault fault = (Fault) itFault.next();
106                    createFault(operation, wsdlBindingOperation.getBindingFaults().get(fault.getName()));
107                }
108                // Add operation
109                binding.addOperation(operation);
110            }
111            
112            return binding;
113        }
114        
115        private static void createFault(Wsdl1SoapOperationImpl operation, Object object) {
116            // TODO Auto-generated method stub
117            
118        }
119    
120        private static void createInput(Wsdl1SoapOperationImpl operation, BindingOperation wsdlBindingOperation) {
121            Operation wsdlOperation = wsdlBindingOperation.getOperation();
122            Input wsdlInput = wsdlOperation.getInput();
123            if (wsdlInput == null) {
124                return;
125            }
126            BindingInput wsdlBindingInput = wsdlBindingOperation.getBindingInput();
127            SOAPBody wsdlSoapBody = WSDLUtils.getExtension(wsdlBindingInput, SOAPBody.class);
128            List<SOAPHeader> wsdlSoapHeaders = WSDLUtils.getExtensions(wsdlBindingInput, SOAPHeader.class);
129            Wsdl1SoapMessageImpl input = new Wsdl1SoapMessageImpl();
130            input.setName(wsdlInput.getMessage().getQName());
131            input.setNamespace(wsdlSoapBody.getNamespaceURI());
132            String inputName = wsdlInput.getName();
133            if (inputName == null || inputName.length() == 0) {
134                inputName = wsdlOperation.getName();
135            }
136            input.setMessageName(inputName);
137            
138            for (Iterator itPart = wsdlInput.getMessage().getOrderedParts(null).iterator(); itPart.hasNext();) {
139                Part wsdlPart = (Part) itPart.next();
140                Wsdl1SoapPartImpl part = new Wsdl1SoapPartImpl();
141                part.setName(wsdlPart.getName());
142                part.setType(wsdlPart.getTypeName());
143                part.setElement(wsdlPart.getElementName());
144                if ((wsdlSoapBody.getParts() == null && wsdlInput.getMessage().getOrderedParts(null).size() == 1) ||
145                        wsdlSoapBody.getParts().contains(part.getName())) {
146                    part.setBody(true);
147                    if (operation.getStyle() == Style.DOCUMENT) {
148                        input.setElementName(wsdlPart.getElementName());
149                    }
150                } else {
151                    boolean header = false;
152                    for (SOAPHeader h : wsdlSoapHeaders) {
153                        if (wsdlPart.getName().equals(h.getPart())) {
154                            header = true;
155                        }
156                    }
157                    if (header) {
158                        part.setHeader(true);
159                    } else {
160                        throw new IllegalStateException("Unbound part: " + part.getName());
161                    }
162                }
163                input.addPart(part);
164            }
165            if (operation.getStyle() == Style.RPC) {
166                input.setElementName(new QName(input.getNamespace(), operation.getName().getLocalPart()));
167            }
168            operation.setInput(input);
169        }
170        
171        private static void createOutput(Wsdl1SoapOperationImpl operation, BindingOperation wsdlBindingOperation) {
172            Operation wsdlOperation = wsdlBindingOperation.getOperation();
173            Output wsdlOutput = wsdlOperation.getOutput();
174            if (wsdlOutput == null) {
175                return;
176            }
177            BindingOutput wsdlBindingOutput = wsdlBindingOperation.getBindingOutput();
178            SOAPBody wsdlSoapBody = WSDLUtils.getExtension(wsdlBindingOutput, SOAPBody.class);
179            List<SOAPHeader> wsdlSoapHeaders = WSDLUtils.getExtensions(wsdlBindingOutput, SOAPHeader.class);
180            Wsdl1SoapMessageImpl output = new Wsdl1SoapMessageImpl();
181            output.setName(wsdlOutput.getMessage().getQName());
182            output.setNamespace(wsdlSoapBody.getNamespaceURI());
183            String outputName = wsdlOutput.getName();
184            if (outputName == null || outputName.length() == 0) {
185                outputName = wsdlOperation.getName() + "Response";
186            }
187            output.setMessageName(outputName);
188            
189            for (Iterator itPart = wsdlOutput.getMessage().getOrderedParts(null).iterator(); itPart.hasNext();) {
190                Part wsdlPart = (Part) itPart.next();
191                Wsdl1SoapPartImpl part = new Wsdl1SoapPartImpl();
192                part.setName(wsdlPart.getName());
193                part.setType(wsdlPart.getTypeName());
194                part.setElement(wsdlPart.getElementName());
195                if ((wsdlSoapBody.getParts() == null && wsdlOutput.getMessage().getOrderedParts(null).size() == 1) ||
196                        wsdlSoapBody.getParts().contains(part.getName())) {
197                    part.setBody(true);
198                    output.setElementName(wsdlPart.getElementName());
199                } else {
200                    boolean header = false;
201                    for (SOAPHeader h : wsdlSoapHeaders) {
202                        if (wsdlPart.getName().equals(h.getPart())) {
203                            header = true;
204                        }
205                    }
206                    if (header) {
207                        part.setHeader(true);
208                    } else {
209                        throw new IllegalStateException("Unbound part: " + part.getName());
210                    }
211                }
212                output.addPart(part);
213            }
214            if (operation.getStyle() == Style.RPC) {
215                output.setElementName(new QName(output.getNamespace(), operation.getName().getLocalPart() + "Response"));
216            }
217            operation.setOutput(output);
218        }
219        
220        private static Style getStyle(String str) {
221            if (WSDLUtils.WSDL1_STYLE_DOCUMENT.equalsIgnoreCase(str)) {
222                return Style.DOCUMENT;
223            } else if (WSDLUtils.WSDL1_STYLE_RPC.equalsIgnoreCase(str)) {
224                return Style.RPC;
225            } else {
226                return null;
227            }
228        }
229    }