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