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.http.tools;
018    
019    import java.util.Iterator;
020    import java.util.List;
021    import java.util.Map;
022    
023    import javax.wsdl.Binding;
024    import javax.wsdl.BindingFault;
025    import javax.wsdl.BindingInput;
026    import javax.wsdl.BindingOperation;
027    import javax.wsdl.BindingOutput;
028    import javax.wsdl.Definition;
029    import javax.wsdl.Fault;
030    import javax.wsdl.Import;
031    import javax.wsdl.Operation;
032    import javax.wsdl.Port;
033    import javax.wsdl.PortType;
034    import javax.wsdl.Service;
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.SOAPFault;
039    import javax.wsdl.extensions.soap.SOAPOperation;
040    import javax.wsdl.extensions.soap12.SOAP12Address;
041    import javax.wsdl.extensions.soap12.SOAP12Binding;
042    import javax.wsdl.extensions.soap12.SOAP12Body;
043    import javax.wsdl.extensions.soap12.SOAP12Fault;
044    import javax.wsdl.extensions.soap12.SOAP12Operation;
045    import javax.wsdl.factory.WSDLFactory;
046    import javax.xml.namespace.QName;
047    
048    import com.ibm.wsdl.extensions.soap.SOAPAddressImpl;
049    import com.ibm.wsdl.extensions.soap.SOAPBindingImpl;
050    import com.ibm.wsdl.extensions.soap.SOAPBodyImpl;
051    import com.ibm.wsdl.extensions.soap.SOAPFaultImpl;
052    import com.ibm.wsdl.extensions.soap.SOAPOperationImpl;
053    import com.ibm.wsdl.extensions.soap12.SOAP12AddressImpl;
054    import com.ibm.wsdl.extensions.soap12.SOAP12BindingImpl;
055    import com.ibm.wsdl.extensions.soap12.SOAP12BodyImpl;
056    import com.ibm.wsdl.extensions.soap12.SOAP12FaultImpl;
057    import com.ibm.wsdl.extensions.soap12.SOAP12OperationImpl;
058    
059    public final class PortTypeDecorator {
060    
061        private PortTypeDecorator() {
062        }
063        
064        public static Definition createImportDef(Definition definition, String targetNamespace, String importUri)
065            throws Exception {
066            // Create definition
067            Definition def = WSDLFactory.newInstance().newDefinition();
068            def.setTargetNamespace(targetNamespace);
069    
070            // Add namespaces
071            Map<?, ?> namespaces = definition.getNamespaces();
072            for (Iterator<?> iter = namespaces.keySet().iterator(); iter.hasNext();) {
073                String prefix = (String) iter.next();
074                String uri = definition.getNamespace(prefix);
075                def.addNamespace(prefix, uri);
076            }
077            def.addNamespace("tns", targetNamespace);
078            def.addNamespace("tnspt", definition.getTargetNamespace());
079    
080            // Create import
081            Import imp = def.createImport();
082            imp.setNamespaceURI(definition.getTargetNamespace());
083            imp.setLocationURI(importUri);
084            imp.setDefinition(definition);
085            def.addImport(imp);
086    
087            return def;
088        }
089        
090        public static void decorate(Definition def,
091                                    PortType portType,
092                                    String locationUri) throws Exception {
093            decorate(def,
094                     portType,
095                     locationUri,
096                     portType.getQName().getLocalPart() + "Binding",
097                     portType.getQName().getLocalPart() + "Service",
098                     "JBI",
099                     "1.1");
100        }
101        
102        public static void decorate(Definition def,
103                                    PortType portType,
104                                    String locationUri,
105                                    String bindingName,
106                                    String serviceName,
107                                    String portName,
108                                    String soapVersion) throws Exception {
109            boolean soap11 = "1.1".equals(soapVersion);
110            if (soap11) {
111                def.addNamespace("wsdlsoap", "http://schemas.xmlsoap.org/wsdl/soap/");
112            } else {
113                def.addNamespace("wsdlsoap", "http://schemas.xmlsoap.org/wsdl/soap12/");
114            }
115            // Create binding
116            Binding binding = def.createBinding();
117            binding.setQName(new QName(def.getTargetNamespace(), bindingName));
118            binding.setPortType(portType);
119            binding.setUndefined(false);
120            // Create soap extension
121            if (soap11) {
122                SOAPBinding soap = new SOAPBindingImpl();
123                soap.setTransportURI("http://schemas.xmlsoap.org/soap/http");
124                soap.setStyle("document");
125                binding.addExtensibilityElement(soap);
126            } else {
127                SOAP12Binding soap = new SOAP12BindingImpl();
128                soap.setTransportURI("http://schemas.xmlsoap.org/soap/http");
129                soap.setStyle("document");
130                binding.addExtensibilityElement(soap);
131            }
132            // Create operations
133            List<?> operations = portType.getOperations();
134            for (Iterator<?> iter = operations.iterator(); iter.hasNext();) {
135                Operation operation = (Operation) iter.next();
136                BindingOperation bindingOp = createBindingOperation(def, soap11, operation);
137                binding.addBindingOperation(bindingOp);
138            }
139            def.addBinding(binding);
140            // Create service
141            Service service = def.createService();
142            service.setQName(new QName(def.getTargetNamespace(), serviceName));
143            Port port = def.createPort();
144            port.setName(portName);
145            port.setBinding(binding);
146            if (soap11) {
147                SOAPAddress address = new SOAPAddressImpl();
148                address.setLocationURI(locationUri);
149                port.addExtensibilityElement(address);
150            } else {
151                SOAP12Address address = new SOAP12AddressImpl();
152                address.setLocationURI(locationUri);
153                port.addExtensibilityElement(address);
154            }
155            service.addPort(port);
156            def.addService(service);
157        }
158    
159        private static BindingOperation createBindingOperation(Definition def, boolean soap11, Operation operation) {
160            BindingOperation bindingOp = def.createBindingOperation();
161            bindingOp.setName(operation.getName());
162            if (soap11) {
163                SOAPOperation op = new SOAPOperationImpl();
164                op.setSoapActionURI("");
165                bindingOp.addExtensibilityElement(op);
166            } else {
167                SOAP12Operation op = new SOAP12OperationImpl();
168                op.setSoapActionURI("");
169                bindingOp.addExtensibilityElement(op);
170            }
171            if (operation.getInput() != null) {
172                BindingInput in = def.createBindingInput();
173                in.setName(operation.getInput().getName());
174                if (soap11) {
175                    SOAPBody body = new SOAPBodyImpl();
176                    body.setUse("literal");
177                    in.addExtensibilityElement(body);
178                } else {
179                    SOAP12Body body = new SOAP12BodyImpl();
180                    body.setUse("literal");
181                    in.addExtensibilityElement(body);
182                }
183                bindingOp.setBindingInput(in);
184            }
185            if (operation.getOutput() != null) {
186                BindingOutput out = def.createBindingOutput();
187                out.setName(operation.getOutput().getName());
188                if (soap11) {
189                    SOAPBody body = new SOAPBodyImpl();
190                    body.setUse("literal");
191                    out.addExtensibilityElement(body);
192                } else {
193                    SOAP12Body body = new SOAP12BodyImpl();
194                    body.setUse("literal");
195                    out.addExtensibilityElement(body);
196                }
197                bindingOp.setBindingOutput(out);
198            }
199            for (Iterator<?> itf = operation.getFaults().values().iterator(); itf.hasNext();) {
200                Fault fault = (Fault) itf.next();
201                BindingFault bindingFault = def.createBindingFault();
202                bindingFault.setName(fault.getName());
203                if (soap11) {
204                    SOAPFault soapFault = new SOAPFaultImpl();
205                    soapFault.setUse("literal");
206                    soapFault.setName(fault.getName());
207                    bindingFault.addExtensibilityElement(soapFault);
208                } else {
209                    SOAP12Fault soapFault = new SOAP12FaultImpl();
210                    soapFault.setUse("literal");
211                    soapFault.setName(fault.getName());
212                    bindingFault.addExtensibilityElement(soapFault);
213                }
214                bindingOp.addBindingFault(bindingFault);
215            }
216            return bindingOp;
217        }
218    
219        public static Definition decorate(Definition definition, String importUri, String targetNamespace,
220                        String locationUri) throws Exception {
221            // Create definition
222            Definition def = createImportDef(definition, targetNamespace, importUri);
223    
224            // Iterator through port types
225            for (Iterator<?> it = definition.getPortTypes().values().iterator(); it.hasNext();) {
226                PortType portType = (PortType) it.next();
227                decorate(def, portType, locationUri);
228            }
229            return def;
230        }
231    
232    }