boolean introduceNewNS = false;
String operationName = node.getOperationName();
WsdlMessage newInputMessage = null;
Iterable<WsdlPortType> servicePortTypes = serviceWSDL.portTypes();
WsdlPortTypeOperation serviceOperation = null;
WsdlPortType servicePortType = null;
for (WsdlPortType wsdlPortType : servicePortTypes) {
serviceOperation = wsdlPortType.getOperation(operationName);
if(serviceOperation != null){
QName inputMessageName = serviceOperation.getInput().getMessage();
WsdlMessagePart part = WSDLUtil.getfirst(serviceWSDL.getMessage(inputMessageName.getLocalPart()).parts());
nsPrefix = part.getElement().getPrefix();
oldNSPrefix = nsPrefix;
introduceNewNS = false;
while( null != wsdl.xml().lookupNamespaceByPrefix(nsPrefix)){
//this namespace is already there so keep adding control at the end and check for
//its existance
nsPrefix += "_control";
introduceNewNS = true;
}
wsdl.xml().declareNamespace(BUILDER.newNamespace(nsPrefix, serviceTns));
WsdlMessage inputMessage = serviceWSDL.getMessage(inputMessageName.getLocalPart());
newInputMessage = wsdl.addMessage(inputMessageName.getLocalPart());
Iterable<WsdlMessagePart> parts = inputMessage.parts();
for (WsdlMessagePart wsdlMessagePart : parts) {
XmlElement newPart = null;
if(introduceNewNS){
XmlElement clone = wsdlMessagePart.xml().clone();
String xmlAsString = BUILDER.serializeToString(clone).replaceAll(oldNSPrefix+":", nsPrefix+":");
newPart= BUILDER.parseFragmentFromString(xmlAsString);
}else{
newPart = wsdlMessagePart.xml().clone();
}
newInputMessage.xml().addElement(newPart);
}
//add lead header part to the new input messag because this message is copied from the service wsdl.
XmlElement newLeadHeaderPart = newInputMessage.xml().addElement(newInputMessage.xml().getNamespace(), "part");
newLeadHeaderPart.setAttributeValue("name", "leadHeader");
newLeadHeaderPart.setAttributeValue("element", "lc:context");
WsdlMessage newOutputMessage = null;
if(null != serviceOperation.getOutput()){
QName outputMessageName = serviceOperation.getOutput().getMessage();
WsdlMessage outputMessage = serviceWSDL.getMessage(outputMessageName.getLocalPart());
newOutputMessage = wsdl.addMessage(outputMessageName.getLocalPart());
Iterable<WsdlMessagePart> parts2 = outputMessage.parts();
for (WsdlMessagePart wsdlMessagePart : parts2) {
XmlElement newPart = null;
if(introduceNewNS){
XmlElement clone = wsdlMessagePart.xml().clone();
String xmlAsString = BUILDER.serializeToString(clone).replaceAll(oldNSPrefix+":", nsPrefix+":");
newPart = BUILDER.parseFragmentFromString(xmlAsString);
}else{
newPart = wsdlMessagePart.xml().clone();
}
newOutputMessage.xml().addElement(newPart);
}
}
if(introduceNewNS){
List<XmlNamespace> namespacesPresentInSchema = WSDLUtil.getNamespaces(serviceSchema);
WSDLUtil.print(serviceSchema);
for (XmlNamespace shouldBeDefinedNamespaces : namespacesPresentInSchema) {
if(shouldBeDefinedNamespaces.getPrefix() != null &&
null == wsdl.xml().lookupNamespaceByPrefix(shouldBeDefinedNamespaces.getPrefix())){
wsdl.xml().declareNamespace(shouldBeDefinedNamespaces);
}
}
XmlElement clone = serviceSchema.clone();
String xmlAsString = BUILDER.serializeToString(clone).replaceAll(oldNSPrefix+":", nsPrefix+":");
XmlElement newSchema= BUILDER.parseFragmentFromString(xmlAsString);
types.addChild(newSchema);
XmlElement crosscutImport = BUILDER.newFragment(newSchema.getNamespace(), "import");
crosscutImport.setAttributeValue("namespace", "http://lead.extreme.indiana.edu/namespaces/2006/lead-crosscut-parameters/");
crosscutImport.setAttributeValue("schemaLocation", "lead-crosscut-parameters.xsd");
newSchema.addChild(0, crosscutImport);
}else{
types.addChild(serviceSchema.clone());
}
//adding new operation for the receive
Iterator<WsdlPortType> portTypes = wsdl.portTypes().iterator();
if(portTypes.hasNext()){
WsdlPortType newOperationPortType = portTypes.next();
WsdlPortTypeOperation newOp = newOperationPortType.addOperation(node.getOperationName());
XmlNamespace wsaNS = BUILDER.newNamespace("http://www.w3.org/2006/05/addressing/wsdl");
newOp.setInput(newInputMessage.getName(),newInputMessage);
String inputAction = serviceOperation.getInput().xml().attributeValue(wsaNS, "Action");
newInputMessage.xml().setAttributeValue(wsaNS, "Action", inputAction);
if(newOutputMessage != null){
newOp.setOutput(newOutputMessage.getName(), newOutputMessage);
String outputAction = serviceOperation.getOutput().xml().attributeValue(wsaNS, "Action");
newOutputMessage.xml().setAttributeValue(wsaNS, "Action", outputAction);
}
}
servicePortType = wsdlPortType;
}
addreceive(workflow.getOdeProcess(null, null), wsdl, operationName, newInputMessage.getName() ) ;
}
// find the binding for the operation in the service wsdl
Iterable<WsdlBinding> serviceBindings = serviceWSDL.bindings();
WsdlBinding serviceBinding = null;
for (WsdlBinding wsdlBinding : serviceBindings) {
if(wsdlBinding.getPortType().equals(servicePortType.getQName())){
serviceBinding = wsdlBinding;
break;
}
}
WsdlBindingOperation serviceBindingOperation = serviceBinding.getOperation(node.getOperationName());
//find the binding in the final wsdl
Iterator<WsdlPortType> portTypeItr = wsdl.portTypes().iterator();
if(portTypeItr.hasNext()){
WsdlPortType portType = portTypeItr.next();
Iterable<WsdlBinding> bindings = wsdl.bindings();
for (WsdlBinding wsdlBinding : bindings) {
if(wsdlBinding.getPortType().equals(portType.getQName())){
WsdlBindingOperation newBindingOperation = wsdlBinding.addOperation(node.getOperationName());
Iterable serviceBindingChildren = serviceBindingOperation.xml().children();
for (Object object : serviceBindingChildren) {
if(object instanceof XmlElement){
XmlElement newBindingOperationChild = ((XmlElement)object).clone();
newBindingOperation.xml().addElement(newBindingOperationChild);
//if this is the input element add a header binding because that is missing in the
// wsdl that this was copied from
if("input".equals(newBindingOperationChild.getName())){
XmlElement bindingBody = newBindingOperationChild.element("body");
bindingBody.setAttributeValue("parts", "input");
XmlNamespace soapNS = XmlConstants.BUILDER.newNamespace("http://schemas.xmlsoap.org/wsdl/soap/");
XmlElement bindingHeader = newBindingOperationChild.addElement(soapNS, "header");
bindingHeader.setAttributeValue("part", "leadHeader");
bindingHeader.setAttributeValue("use", "literal");
bindingHeader.setAttributeValue("message", "tns:"+newInputMessage.getName());
}
}
}
break;
}
}
}
WsdlPortType portType = WSDLUtil.getfirst(wsdl.portTypes());
//Thinking that the first operation is the the one that is workflow input
QName workflowInputMessage = WSDLUtil.getfirst(portType.operations()).getInput().getMessage();
addCorrelationProperties(wsdl, wsdl.getMessage(workflowInputMessage.getLocalPart()),
newInputMessage);
}