/** * Copyright 2015 Nortal 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. **/ package com.nortal.jroad.wsdl; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import javax.wsdl.Binding; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; import javax.wsdl.BindingOutput; import javax.wsdl.Definition; import javax.wsdl.Input; import javax.wsdl.Output; import javax.wsdl.Port; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.ExtensionRegistry; import javax.wsdl.extensions.UnknownExtensibilityElement; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; import javax.wsdl.extensions.soap.SOAPHeader; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.springframework.ws.wsdl.wsdl11.provider.Soap11Provider; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.nortal.jroad.mapping.XTeeEndpointMapping; import com.nortal.jroad.model.XTeeHeader; /** * Creates X-Road specific SOAP headers and bindings (<code>Document/Literal</code> is used). Used by * {@link XTeeWsdlDefinition}. * * @author Lauri Lättemäe (lauri.lattemae@nortal.com) - protocol 4.0 */ public class XTeeSoapProvider extends Soap11Provider { private static final String ENCODED = "encoded"; private static final String LITERAL = "literal"; private static final String ENCODING = "http://schemas.xmlsoap.org/soap/encoding/"; private String xRoadDatabase; private String use = LITERAL; private XTeeEndpointMapping xRoadEndpointMapping; private List<SOAPHeader> makeHeaders(Definition definition) throws WSDLException { List<SOAPHeader> list = new ArrayList<SOAPHeader>(); String[] parts = new String[] { XTeeHeader.CLIENT.getLocalPart(), XTeeHeader.SERVICE.getLocalPart(), XTeeHeader.USER_ID.getLocalPart(), XTeeHeader.ID.getLocalPart(), XTeeHeader.PROTOCOL_VERSION.getLocalPart() }; ExtensionRegistry extReg = definition.getExtensionRegistry(); for (int i = 0; i < parts.length; i++) { SOAPHeader header = (SOAPHeader) extReg.createExtension(BindingInput.class, new QName(SOAP_11_NAMESPACE_URI, "header")); header.setMessage(new QName(definition.getTargetNamespace(), XTeeWsdlDefinition.XROAD_HEADER)); header.setPart(parts[i]); if (use.equalsIgnoreCase(LITERAL)) { header.setUse(LITERAL); } else { header.setUse(ENCODED); header.setEncodingStyles(Arrays.asList(ENCODING)); } list.add(header); } return list; } @Override protected void populateBindingInput(Definition definition, BindingInput bindingInput, Input input) throws WSDLException { for (SOAPHeader header : makeHeaders(definition)) { bindingInput.addExtensibilityElement(header); } super.populateBindingInput(definition, bindingInput, input); } @Override protected void populateBindingOutput(Definition definition, BindingOutput bindingOutput, Output output) throws WSDLException { for (SOAPHeader header : makeHeaders(definition)) { bindingOutput.addExtensibilityElement(header); } super.populateBindingOutput(definition, bindingOutput, output); } @Override protected void populateBindingOperation(Definition definition, BindingOperation bindingOperation) throws WSDLException { super.populateBindingOperation(definition, bindingOperation); XTeeElement element = (XTeeElement) definition.getExtensionRegistry().createExtension(BindingOperation.class, XTeeElement.VERSION_TYPE); String version = "v1"; String name = bindingOperation.getName().toLowerCase(); for (String method : xRoadEndpointMapping.getMethods()) { method = method.substring(method.indexOf('.') + 1).toLowerCase(); if (method.startsWith(name + ".")) { version = method.substring(method.indexOf('.') + 1); break; } } element.setValue(version); bindingOperation.addExtensibilityElement(element); } @Override protected void populateBinding(Definition definition, Binding binding) throws WSDLException { definition.getExtensionRegistry().mapExtensionTypes(BindingOperation.class, XTeeElement.VERSION_TYPE, XTeeElement.class); definition.getExtensionRegistry().registerSerializer(BindingOperation.class, XTeeElement.VERSION_TYPE, new XTeeElement.XRoadElementSerializer()); super.populateBinding(definition, binding); } @Override protected void populateSoapBinding(SOAPBinding soapBinding, Binding binding) throws WSDLException { soapBinding.setStyle("document"); soapBinding.setTransportURI(getTransportUri()); } @Override protected void populatePort(Definition definition, Port port) throws WSDLException { super.populatePort(definition, port); ExtensionRegistry extensionRegistry = definition.getExtensionRegistry(); extensionRegistry.mapExtensionTypes(Port.class, new QName(XTeeWsdlDefinition.XROAD_NAMESPACE, "address", XTeeWsdlDefinition.XROAD_PREFIX), UnknownExtensibilityElement.class); UnknownExtensibilityElement element = (UnknownExtensibilityElement) extensionRegistry.createExtension(Port.class, new QName(XTeeWsdlDefinition.XROAD_NAMESPACE, "address", XTeeWsdlDefinition.XROAD_NAMESPACE)); Document doc; try { doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } Element xRoadAddr = doc.createElementNS(XTeeWsdlDefinition.XROAD_NAMESPACE, "address"); xRoadAddr.setPrefix(XTeeWsdlDefinition.XROAD_PREFIX); xRoadAddr.setAttribute("producer", xRoadDatabase); element.setElement(xRoadAddr); port.addExtensibilityElement(element); } public void setXRoadDatabase(String xRoadDatabase) { this.xRoadDatabase = xRoadDatabase; } public void setXRoadEndpointMapping(XTeeEndpointMapping xRoadEndpointMapping) { this.xRoadEndpointMapping = xRoadEndpointMapping; } public void setUse(String use) { this.use = use; } @Override protected void populateSoapBody(SOAPBody soapBody) throws WSDLException { if (use.equalsIgnoreCase(LITERAL)) { soapBody.setUse(LITERAL); } else { soapBody.setUse(ENCODED); List<String> encStyles = new ArrayList<String>(1); encStyles.add(ENCODING); soapBody.setEncodingStyles(encStyles); } } }