static Part::List selectedParts( const Binding& binding, const Message& message, const Operation& operation, bool input ) { if ( binding.type() == Binding::SOAPBinding ) { const SoapBinding soapBinding = binding.soapBinding(); const SoapBinding::Operation op = soapBinding.operations().value( operation.name() ); const QString selectedPart = input ? op.input().part() : op.output().part(); if (!selectedPart.isEmpty()) { Part::List selected; Q_FOREACH( const Part& part, message.parts() ) { if ( part.name() == selectedPart ) { // support for <soap:body parts="MoveFolderResult"/> (msexchange) selected << part; } } return selected; } }
void Converter::generateServerMethod(KODE::Code &code, const Binding &binding, const Operation &operation, KODE::Class &newClass, bool first) { const QString requestVarName = "_request"; const QString responseVarName = "_response"; const Message message = mWSDL.findMessage(operation.input().message()); Message outputMessage; if (operation.operationType() != Operation::OneWayOperation) { outputMessage = mWSDL.findMessage(operation.output().message()); } const QString operationName = operation.name(); const QString methodName = mNameMapper.escape(lowerlize(operationName)); KODE::Function virtualMethod(methodName); virtualMethod.setVirtualMode(KODE::Function::PureVirtual); QString condition = "method == \"" + operationName + "\""; if (binding.type() == Binding::SOAPBinding) { const SoapBinding soapBinding(binding.soapBinding()); const SoapBinding::Operation op = soapBinding.operations().value(operation.name()); if (!op.action().isEmpty()) { condition += " || _soapAction == \"" + op.action() + "\""; } } code += QString(first ? "" : "else ") + "if (" + condition + ") {"; code.indent(); QStringList inputVars; const Part::List parts = message.parts(); for (int partNum = 0; partNum < parts.count(); ++partNum) { const Part part = parts.at(partNum); const QString lowerName = lowerlize(part.name()); const QString argType = mTypeMap.localType(part.type(), part.element()); //qDebug() << "localInputType" << part.type().qname() << part.element().qname() << "->" << argType; if (argType != "void") { const QString varName = mNameMapper.escape(lowerName); code += argType + ' ' + varName + ";" + COMMENT; QString soapValueVarName = requestVarName; if (soapStyle(binding) == SoapBinding::RPCStyle) { // RPC comes with a wrapper element, dig into it here soapValueVarName = "val"; if (partNum > 0) { soapValueVarName += QString::number(partNum + 1); } code += QString::fromLatin1("const KDSoapValue %1 = %2.childValues().at(%3);").arg(soapValueVarName, requestVarName).arg(partNum) + COMMENT; } // what if there's more than one? code.addBlock(demarshalVar(part.type(), part.element(), varName, argType, soapValueVarName, false, false)); inputVars += varName; newClass.addIncludes(mTypeMap.headerIncludes(part.type()), mTypeMap.forwardDeclarationsForElement(part.element())); virtualMethod.addArgument(mTypeMap.localInputType(part.type(), part.element()) + ' ' + varName); } } const Part::List outParts = outputMessage.parts(); if (outParts.count() > 1) { qWarning("ERROR: multiple output parameters are not supported (operation %s) - please file" "an issue on github with your wsdl file", qPrintable(operation.name())); virtualMethod.setReturnType("void /*UNSUPPORTED*/"); } else if (outParts.isEmpty()) { code += lowerlize(operationName) + '(' + inputVars.join(", ") + ");"; virtualMethod.setReturnType("void"); } else { QString retType; QString retInputType; //bool isBuiltin = false; //bool isComplex = false; Part retPart; Q_FOREACH (const Part &outPart, outParts /* only one */) { retType = mTypeMap.localType(outPart.type(), outPart.element()); retInputType = mTypeMap.localInputType(outPart.type(), outPart.element()); //isBuiltin = mTypeMap.isBuiltinType( outPart.type(), outPart.element() ); //isComplex = mTypeMap.isComplexType( outPart.type(), outPart.element() ); retPart = outPart; } const QString methodCall = methodName + '(' + inputVars.join(", ") + ')'; if (retType == "void") { code += methodCall + ";" + COMMENT; } else { code += retType + " ret = " + methodCall + ";" + COMMENT; } code += "if (!hasFault()) {"; code.indent(); // TODO factorize with same code in next method if (soapStyle(binding) == SoapBinding::DocumentStyle) { code.addBlock(serializePart(retPart, "ret", responseVarName, false)); } else { code += QString("KDSoapValue wrapper(\"%1\", QVariant(), \"%2\");").arg(outputMessage.name()).arg(outputMessage.nameSpace()); code.addBlock(serializePart(retPart, "ret", "wrapper.childValues()", true)); code += responseVarName + " = wrapper;"; } code.unindent(); code += "}"; Q_ASSERT(!retType.isEmpty()); virtualMethod.setReturnType(retType); newClass.addIncludes(mTypeMap.headerIncludes(retPart.type()), mTypeMap.forwardDeclarationsForElement(retPart.element())); generateDelayedReponseMethod(methodName, retInputType, retPart, newClass, binding, outputMessage); }
void Converter::generateServerMethod(KODE::Code& code, const Binding& binding, const Operation& operation, KODE::Class &newClass, bool first) { const Message message = mWSDL.findMessage( operation.input().message() ); Message outputMessage; if (operation.operationType() != Operation::OneWayOperation) { outputMessage = mWSDL.findMessage( operation.output().message() ); } const QString operationName = operation.name(); const QString methodName = mNameMapper.escape( lowerlize( operationName ) ); KODE::Function virtualMethod(methodName); virtualMethod.setVirtualMode(KODE::Function::PureVirtual); QString condition = "method == \"" + operationName + "\""; if ( binding.type() == Binding::SOAPBinding ) { const SoapBinding soapBinding( binding.soapBinding() ); const SoapBinding::Operation op = soapBinding.operations().value( operation.name() ); if (!op.action().isEmpty()) { condition += "|| soapAction == \"" + op.action() + "\""; } } code += QString(first ? "" : "else ") + "if (" + condition + ") {"; code.indent(); QStringList inputVars; const Part::List parts = message.parts(); if (parts.count() > 1) { qWarning("ERROR: multiple input parameters are not supported - please report this with your wsdl file to [email protected]"); } Q_FOREACH( const Part& part, parts ) { const QString lowerName = lowerlize( part.name() ); const QString argType = mTypeMap.localType( part.type(), part.element() ); //qDebug() << "localInputType" << part.type().qname() << part.element().qname() << "->" << argType; if ( argType != "void" ) { const QString varName = mNameMapper.escape( lowerName ); code += argType + ' ' + varName + ";" + COMMENT; QString soapValueVarName = "request"; if (soapStyle(binding) == SoapBinding::RPCStyle) { // RPC comes with a wrapper element, dig into it here code += QLatin1String("const KDSoapValue val = request.childValues().first();") + COMMENT; soapValueVarName = "val"; } // what if there's more than one? code.addBlock( demarshalVar( part.type(), part.element(), varName, argType, soapValueVarName ) ); inputVars += varName; newClass.addIncludes( mTypeMap.headerIncludes( part.type() ) ); virtualMethod.addArgument( mTypeMap.localInputType( part.type(), part.element() ) + ' ' + varName ); } } const Part::List outParts = outputMessage.parts(); if (outParts.count() > 1) { qWarning("ERROR: multiple output parameters are not supported (operation %s) - please report" " this with your wsdl file to [email protected]", qPrintable(operation.name())); virtualMethod.setReturnType("void /*UNSUPPORTED*/"); } else if (outParts.isEmpty()) { code += operationName + '(' + inputVars.join(", ") + ");"; virtualMethod.setReturnType("void"); } else { QString retType; QString retInputType; //bool isBuiltin = false; //bool isComplex = false; Part retPart; Q_FOREACH( const Part& outPart, outParts /* only one */ ) { retType = mTypeMap.localType( outPart.type(), outPart.element() ); retInputType = mTypeMap.localInputType( outPart.type(), outPart.element() ); //isBuiltin = mTypeMap.isBuiltinType( outPart.type(), outPart.element() ); //isComplex = mTypeMap.isComplexType( outPart.type(), outPart.element() ); retPart = outPart; } const QString methodCall = methodName + '(' + inputVars.join(", ") + ')'; if (retType == "void") { code += methodCall + ";" + COMMENT; } else { code += retType + " ret = " + methodCall + ";" + COMMENT; } code += "if (!hasFault()) {"; code.indent(); bool qualified; const QName elemName = elementNameForPart( retPart, &qualified ); if (soapStyle(binding) == SoapBinding::RPCStyle) { code += QString("KDSoapValue wrapper(\"%1\", QVariant());").arg(outputMessage.name()); code.addBlock( serializeElementArg( retPart.type(), retPart.element(), elemName, "ret", "wrapper.childValues()", true, qualified ) ); code += "response = wrapper;"; } else { code.addBlock( serializeElementArg( retPart.type(), retPart.element(), elemName, "ret", "response", false, qualified ) ); } code.unindent(); code += "}"; Q_ASSERT(!retType.isEmpty()); virtualMethod.setReturnType(retType); generateDelayedReponseMethod(methodName, retInputType, retPart, newClass, binding, outputMessage); }