Skip to content

Commit

Permalink
Merge pull request #260 from arykov/master
Browse files Browse the repository at this point in the history
fix related to wsdl namespaces issue 
@arykov thanks for your contribution
  • Loading branch information
predic8 authored Apr 18, 2017
2 parents 68641c9 + 83ea925 commit cabbb60
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 13 deletions.
30 changes: 17 additions & 13 deletions core/src/main/groovy/com/predic8/wsdl/creator/WSDLCreator.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,16 @@ import com.predic8.wsdl.*
import com.predic8.wsdl.http.HTTPBinding

class WSDLCreator extends AbstractWSDLCreator{
def nameWithPrefix(WSDLElement element){

return (element.getPrefix()?element.getPrefix()+':':'')+element.getElementName().getLocalPart();
}

def createDefinitions(Definitions definitions, WSDLCreatorContext ctx){
def attrs = ['targetNamespace':getDisplayName(definitions.targetNamespace, 'definitions.targetNamespace', ctx.error)]
if(definitions.name) attrs['name'] = definitions.name

builder.definitions(attrs + getNamespaceAttributes(definitions)) {
builder.(nameWithPrefix(definitions))(attrs + getNamespaceAttributes(definitions)) {
definitions.documentation?.create(this, ctx)

/**
Expand Down Expand Up @@ -61,11 +65,11 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createImport(Import imp, WSDLCreatorContext ctx){
builder.'import'([namespace: imp.namespace, location: imp.location] + getNamespaceAttributes(imp))
builder.(nameWithPrefix(imp))([namespace: imp.namespace, location: imp.location] + getNamespaceAttributes(imp))
}

def createTypes(Types types, WSDLCreatorContext ctx){
builder.types(){
builder.(nameWithPrefix(types))(){
types.documentation?.create(this, ctx)
types.schemas.each{
it.create(new SchemaCreator(builder: builder), new SchemaCreatorContext(ctx.clone()))
Expand All @@ -74,7 +78,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createMessage(Message message, WSDLCreatorContext ctx){
builder.message([name : getDisplayName(message.name, 'definitions.message.name', ctx.error)] + getNamespaceAttributes(message)) {
builder.(nameWithPrefix(message))([name : getDisplayName(message.name, 'definitions.message.name', ctx.error)] + getNamespaceAttributes(message)) {
message.documentation?.create(this, ctx)
message.parts.each {
it.create(this, ctx)
Expand All @@ -86,11 +90,11 @@ class WSDLCreator extends AbstractWSDLCreator{
def attrs = [name : part.name]
if(part.element) {attrs.put('element' , "${part.getPrefix(part.element.namespaceUri)}:${part.element.name}")}
if(part.type) {attrs.put('type' , part.typePN)}
builder.part(attrs + getNamespaceAttributes(part))
builder.(nameWithPrefix(part))(attrs + getNamespaceAttributes(part))
}

def createPortType(PortType portType, WSDLCreatorContext ctx) {
builder.portType([name : getDisplayName(portType.name, 'definitions.portTypes.name', ctx.error)] + getNamespaceAttributes(portType)) {
builder.(nameWithPrefix(portType))([name : getDisplayName(portType.name, 'definitions.portTypes.name', ctx.error)] + getNamespaceAttributes(portType)) {
portType.documentation?.create(this, ctx)
portType.operations.each{
//TODO call it.create() instead.
Expand All @@ -100,7 +104,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createOperation(Operation operation, WSDLCreatorContext ctx) {
builder.operation([name : getDisplayName(operation.name, 'definitions.operations.name', ctx.error)] + getNamespaceAttributes(operation)){
builder.(nameWithPrefix(operation))([name : getDisplayName(operation.name, 'definitions.operations.name', ctx.error)] + getNamespaceAttributes(operation)){
operation.documentation?.create(this, ctx)
operation.input?.create(this, ctx)
operation.output?.create(this, ctx)
Expand All @@ -111,7 +115,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createBinding(Binding binding, WSDLCreatorContext ctx){
builder.binding([name : binding.name, type: binding.getTypeString(binding.type)] + getNamespaceAttributes(binding)){
builder.(nameWithPrefix(binding))([name : binding.name, type: binding.getTypeString(binding.type)] + getNamespaceAttributes(binding)){
binding.policyReference?.create(new PolicyCreator(builder: builder), ctx)
binding.documentation?.create(this, ctx)
binding.binding?.create(this, ctx)
Expand All @@ -136,7 +140,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createBindingOperation(BindingOperation bindingOperation, WSDLCreatorContext ctx) {
builder."operation"([name : bindingOperation.name] + getNamespaceAttributes(bindingOperation)) {
builder.(nameWithPrefix(bindingOperation))([name : bindingOperation.name] + getNamespaceAttributes(bindingOperation)) {
bindingOperation.operation?.create(this, ctx)
bindingOperation.input?.create(this, ctx)
bindingOperation.output?.create(this, ctx)
Expand All @@ -159,13 +163,13 @@ class WSDLCreator extends AbstractWSDLCreator{
def createPortTypeMessage(AbstractPortTypeMessage portTypeMessage, WSDLCreatorContext ctx) {
def attrs = [message: "${portTypeMessage.definitions.targetNamespacePrefix}:${portTypeMessage.message.name}"]
if(portTypeMessage.name) attrs['name'] = portTypeMessage.name
builder."${portTypeMessage.ELEMENTNAME.localPart}"(attrs + getNamespaceAttributes(portTypeMessage))
builder.(nameWithPrefix(portTypeMessage))(attrs + getNamespaceAttributes(portTypeMessage))
}

def createBindingMessage(BindingMessage bindingMessage, WSDLCreatorContext ctx){
def attrs = [:]
if(bindingMessage.name ) attrs['name'] = bindingMessage.name
builder."${bindingMessage.ELEMENTNAME.localPart}"(attrs + getNamespaceAttributes(bindingMessage)){
builder.(nameWithPrefix(bindingMessage))(attrs + getNamespaceAttributes(bindingMessage)){
bindingMessage.bindingElements.each{
it.create(this, ctx)
}
Expand Down Expand Up @@ -197,7 +201,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createService(Service service , WSDLCreatorContext ctx) {
builder.service(name : getDisplayName(service.name, 'definitions.services.name', ctx.error)) {
builder.(nameWithPrefix(service))(name : getDisplayName(service.name, 'definitions.services.name', ctx.error)) {
service.documentation?.create(this, ctx)
service.ports.each {
it.create(this, ctx)
Expand All @@ -206,7 +210,7 @@ class WSDLCreator extends AbstractWSDLCreator{
}

def createPort(Port port, WSDLCreatorContext ctx) {
builder.port([name: port.name, binding : "${port.definitions.targetNamespacePrefix}:${port.binding.name}"] + getNamespaceAttributes(port)) {
builder.(nameWithPrefix(port))([name: port.name, binding : "${port.definitions.targetNamespacePrefix}:${port.binding.name}"] + getNamespaceAttributes(port)) {
port.documentation?.create(this, ctx)
port.address.create(this, ctx)
}
Expand Down
123 changes: 123 additions & 0 deletions core/src/test/groovy/com/predic8/wsdl/NamespaceWsdlTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Copyright 2012 predic8 GmbH, www.predic8.com
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.predic8.wsdl

import javax.xml.stream.*

import com.predic8.soamodel.Difference
import com.predic8.wsdl.diff.WsdlDiffGenerator

/**
* This test is created to deal with the problem described here
* https://github.com/membrane/soa-model/issues/259
*
* If wsdl is loaded from a file, modified and then exported using
* getAsString() it gets generated in default namespace. If the
* original wsdl was defined with a namespace prefix and default
* namespace was not defined or was defined as something other
* than http://schemas.xmlsoap.org/wsdl/, wsdl produced using
* getAsString will be invalid due to incorrect namespace.
*
* @author [email protected]
*
*/
class NamespaceWsdlTest extends GroovyTestCase{


def static wsdlWithNsPrefix =
'''<?xml version="1.0" encoding="UTF-8"?>
<wsdl1:definitions xmlns:wsdl1="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://new.webservice.namespace" targetNamespace="http://new.webservice.namespace">
<wsdl1:types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified"/>
</wsdl1:types>
<wsdl1:message name="NewMessageRequest">
<wsdl1:part name="parameter" type="xs:string"/>
</wsdl1:message>
<wsdl1:message name="NewMessageResponse">
<wsdl1:part name="parameter" type="xs:string"/>
</wsdl1:message>
<wsdl1:portType name="NewPortType">
<wsdl1:operation name="NewOperation">
<wsdl1:input message="tns:NewMessageRequest"/>
<wsdl1:output message="tns:NewMessageResponse"/>
</wsdl1:operation>
</wsdl1:portType>
<wsdl1:binding name="NewBinding" type="tns:NewPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl1:operation name="NewOperation">
<soap:operation soapAction="urn:#NewOperation"/>
<wsdl1:input>
<soap:body use="literal"/>
</wsdl1:input>
<wsdl1:output>
<soap:body use="literal"/>
</wsdl1:output>
</wsdl1:operation>
</wsdl1:binding>
<wsdl1:service name="NewService">
<wsdl1:port name="NewPort" binding="tns:NewBinding">
<soap:address location="No target address"/>
</wsdl1:port>
</wsdl1:service>
</wsdl1:definitions>'''
def wsdlWithoutNsPrefix =
'''<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://new.webservice.namespace" targetNamespace="http://new.webservice.namespace">
<types>
<xs:schema targetNamespace="http://new.webservice.namespace" elementFormDefault="qualified"/>
</types>
<message name="NewMessageRequest">
<part name="parameter" type="xs:string"/>
</message>
<message name="NewMessageResponse">
<part name="parameter" type="xs:string"/>
</message>
<portType name="NewPortType">
<operation name="NewOperation">
<input message="tns:NewMessageRequest"/>
<output message="tns:NewMessageResponse"/>
</operation>
</portType>
<binding name="NewBinding" type="tns:NewPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="NewOperation">
<soap:operation soapAction="urn:#NewOperation"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="NewService">
<port name="NewPort" binding="tns:NewBinding">
<soap:address location="No target address"/>
</port>
</service>
</definitions>'''
def parser = new WSDLParser();

void testWsdlNameSpaceWithPrefix() {
def loadedDefinitions = parser.parse(new ByteArrayInputStream(wsdlWithNsPrefix.bytes));
//chances are failure will be at parse time
def reparsedDefinitions = parser.parse(new ByteArrayInputStream(loadedDefinitions.getAsString().bytes));
List<Difference> diffs = new WsdlDiffGenerator(loadedDefinitions, reparsedDefinitions).compare();
assert diffs.size() == 0;
}
void testWsdlNameSpaceWithoutPrefix() {
def loadedDefinitions = parser.parse(new ByteArrayInputStream(wsdlWithoutNsPrefix.bytes));
//chances are failure will be at parse time
def reparsedDefinitions = parser.parse(new ByteArrayInputStream(loadedDefinitions.getAsString().bytes));
List<Difference> diffs = new WsdlDiffGenerator(loadedDefinitions, reparsedDefinitions).compare();
assert diffs.size() == 0;
}
}

0 comments on commit cabbb60

Please sign in to comment.