SoapBinding::Style Converter::soapStyle( const Binding& binding ) const
{
    if ( binding.type() == Binding::SOAPBinding ) {
        const SoapBinding soapBinding( binding.soapBinding() );
        return soapBinding.binding().style();
    }
    return SoapBinding::RPCStyle;
}
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);
    }
Example #4
0
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);
    }