Пример #1
0
void Converter::convertOutputMessage( const Port&, const Message &message, KODE::Class &newClass )
{
  Message::Part part = message.parts().first();

  // signal
  QString messageName = message.name();
  messageName[ 0 ] = messageName[ 0 ].lower();
  KODE::Function respSignal( messageName, "void", KODE::Function::Signal );

  /**
    If one output message is used by two input messages, don't define
    it twice.
   */
  if ( newClass.hasFunction( respSignal.name() ) )
    return;

  const Message::Part::List parts = message.parts();
  Message::Part::List::ConstIterator it;
  for ( it = parts.begin(); it != parts.end(); ++it ) {
    QStringList headers = mTypeMapper.header( (*it).type() );
    for ( uint i = 0; i < headers.count(); ++i )
      if ( !headers[ i ].isEmpty() )
        newClass.addHeaderInclude( headers[ i ] );

    respSignal.addArgument( mTypeMapper.argument( "value", (*it).type() ) );
  }

  newClass.addFunction( respSignal );

  // slot
  KODE::Function respSlot( messageName + "Slot", "void", KODE::Function::Slot | KODE::Function::Private );
  respSlot.addArgument( "const QString &xml" );

  KODE::Code code;
  code += "QDomDocument doc;";
  code += "QString errorMsg;";
  code += "int column, row;";
  code.newLine();
  code += "qDebug( \"%s\", xml.latin1() );";
  code.newLine();
  code += "if ( !doc.setContent( xml, true, &errorMsg, &row, &column ) ) {";
  code.indent();
  code += "qDebug( \"Unable to parse xml: %s (%d:%d)\", errorMsg.latin1(), row, column );";
  code += "return;";
  code.unindent();
  code += "}";
  code.newLine();
  code += mTypeMapper.type( part.type() ) + "* value = new " + mTypeMapper.type( part.type() ) + ";";
  code += "QDomElement envelope = doc.documentElement();";
  code += "QDomElement body = envelope.firstChild().toElement();";
  code += "QDomElement method = body.firstChild().toElement();";
  code += "Serializer::demarshal( method.firstChild().toElement(), value );";
  code.newLine();
  code += "emit " + respSignal.name() + "( value );";
  respSlot.setBody( code );

  newClass.addFunction( respSlot );
}
Пример #2
0
void Converter::convertInputMessage( const Port &port, const Message &message, KODE::Class &newClass )
{
  KODE::MemberVariable transport( message.name() + "Transport", "Transport*" );
  newClass.addMemberVariable( transport );

  // call
  QString messageName = message.name();
  messageName[ 0 ] = messageName[ 0 ].lower();
  KODE::Function callFunc( mNameMapper.escape( messageName ), "void", KODE::Function::Public );

  const Message::Part::List parts = message.parts();
  Message::Part::List::ConstIterator it;
  for ( it = parts.begin(); it != parts.end(); ++it ) {
    newClass.addHeaderIncludes( mTypeMapper.header( (*it).type() ) );
    QString lowerName = (*it).name();
    lowerName[ 0 ] = lowerName[ 0 ].lower();
    callFunc.addArgument( mTypeMapper.argument( mNameMapper.escape( lowerName ), (*it).type() ) );
  }

  KODE::Code code;
  code += "QDomDocument doc( \"kwsdl\" );";
  code += "doc.appendChild( doc.createProcessingInstruction( \"xml\", \"version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"\" ) );";
  code += "QDomElement env = doc.createElement( \"SOAP-ENV:Envelope\" );";
  code += "env.setAttribute( \"xmlns:SOAP-ENV\", \"http://schemas.xmlsoap.org/soap/envelope/\" );";
  code += "env.setAttribute( \"xmlns:xsi\", \"http://www.w3.org/1999/XMLSchema-instance\" );";
  code += "env.setAttribute( \"xmlns:xsd\", \"http://www.w3.org/1999/XMLSchema\" );";
  code += "doc.appendChild( env );";
  code += "QDomElement body = doc.createElement( \"SOAP-ENV:Body\" );";
  code += "env.appendChild( body );";
  code += "QDomElement method = doc.createElement( \"ns1:" + message.name() + "\" );";
  QString nameSpace = mWSDL.findBindingOperation( port.name(), message.name() ).input().nameSpace();
  code += "method.setAttribute( \"xmlns:ns1\", \"" + nameSpace + "\" );";
  code += "method.setAttribute( \"SOAP-ENV:encodingStyle\", \"http://schemas.xmlsoap.org/soap/encoding/\" );";
  code += "body.appendChild( method );";
  code.newLine();

  for ( it = parts.begin(); it != parts.end(); ++it ) {
    QString lowerName = (*it).name();
    lowerName[ 0 ] = lowerName[ 0 ].lower();
    code += "Serializer::marshal( doc, method, \"" + (*it).name() + "\", " + mNameMapper.escape( lowerName ) + " );";
    code += "delete " + mNameMapper.escape( lowerName ) + ";";
  }

  code += "qDebug( \"%s\", doc.toString().latin1() );";
  code += transport.name() + "->query( doc.toString() );";
  callFunc.setBody( code );

  newClass.addFunction( callFunc );
}
Пример #3
0
static KODE::Code createRangeCheckCode( const XSD::SimpleType *type, const QString &variableName, KODE::Class &parentClass )
{
    KODE::Code code;
    code += "bool rangeOk = true;";
    code.newLine();

    // TODO
    /*
      WhiteSpaceType facetWhiteSpace() const;
      int facetTotalDigits() const;
      int facetFractionDigits() const;
    */

    if ( type->facetType() & XSD::SimpleType::MININC )
        code += "rangeOk = rangeOk && (" + variableName + " >= " + QString::number( type->facetMinimumInclusive() ) + ");";
    if ( type->facetType() & XSD::SimpleType::MINEX )
        code += "rangeOk = rangeOk && (" + variableName + " > " + QString::number( type->facetMinimumExclusive() ) + ");";
    if ( type->facetType() & XSD::SimpleType::MAXINC )
        code += "rangeOk = rangeOk && (" + variableName + " <= " + QString::number( type->facetMaximumInclusive() ) + ");";
    if ( type->facetType() & XSD::SimpleType::MINEX )
        code += "rangeOk = rangeOk && (" + variableName + " < " + QString::number( type->facetMaximumExclusive() ) + ");";

    if ( type->facetType() & XSD::SimpleType::LENGTH )
        code += "rangeOk = rangeOk && (" + variableName + ".length() == " + QString::number( type->facetLength() ) + ");";
    if ( type->facetType() & XSD::SimpleType::MINLEN )
        code += "rangeOk = rangeOk && (" + variableName + ".length() >= " + QString::number( type->facetMinimumLength() ) + ");";
    if ( type->facetType() & XSD::SimpleType::MAXLEN )
        code += "rangeOk = rangeOk && (" + variableName + ".length() <= " + QString::number( type->facetMaximumLength() ) + ");";
    if ( type->facetType() & XSD::SimpleType::PATTERN ) {
        code += "QRegExp exp( \"" + type->facetPattern() + "\" );";
        code += "rangeOk = rangeOk && exp.exactMatch( " + variableName + " );";

        parentClass.addInclude( "QRegExp" );
    }

    return code;
}
Пример #4
0
void Converter::convertSimpleType( const XSD::SimpleType *type )
{
    const QString typeName( mTypeMap.localType( type->qualifiedName() ) );
    KODE::Class newClass( typeName );

    newClass.addInclude( QString(), "Serializer" );

    KODE::Code ctorBody;
    KODE::Code dtorBody;

    QString classDocumentation;

    if ( type->subType() == XSD::SimpleType::TypeRestriction ) {
        /**
          Use setter and getter method for enums as well.
         */
        if ( type->facetType() & XSD::SimpleType::ENUM ) {
            classDocumentation = "This class is a wrapper for an enumeration.\n";

            QStringList enums = type->facetEnums();
            for ( int i = 0; i < enums.count(); ++i )
                enums[ i ] = escapeEnum( enums[ i ] );

            newClass.addEnum( KODE::Enum( "Type", enums ) );

            classDocumentation += "Whenever you have to pass an object of type " + newClass.name() +
                                  " you can also pass the enum directly (e.g. someMethod( " + newClass.name() + "::" + enums.first() + "  )).";

            // member variables
            KODE::MemberVariable variable( "type", "Type" );
            newClass.addMemberVariable( variable );

            // setter method
            KODE::Function setter( "setType", "void" );
            setter.addArgument( "Type type" );
            setter.setBody( variable.name() + " = type;" );

            // getter method
            KODE::Function getter( "type", upperlize( newClass.name() ) + "::Type" );
            getter.setBody( "return " + variable.name() + ';' );
            getter.setConst( true );

            // convenience constructor
            KODE::Function conctor( upperlize( newClass.name() ) );
            conctor.addArgument( "const " + upperlize( newClass.name() ) + "::Type &type" );
            KODE::Code code;
            code += variable.name() + " = type;";
            conctor.setBody( code );

            // type operator
            KODE::Function op( "operator const " + upperlize( newClass.name() ) + "::Type" );
            op.setBody( "return " + variable.name() + ';' );
            op.setConst( true );

            newClass.addFunction( conctor );
            newClass.addFunction( setter );
            newClass.addFunction( getter );
            newClass.addFunction( op );
        }

        /**
          A class can't derive from basic types (e.g. int or unsigned char), so
          we add setter and getter methods to set the value of this class.
         */
        if ( type->baseTypeName() != XmlAnyType
                && !type->baseTypeName().isEmpty()
                && !(type->facetType() & XSD::SimpleType::ENUM) ) {
            classDocumentation = "This class encapsulates an basic type.\n";

            const QName baseName = type->baseTypeName();
            const QString typeName = mTypeMap.localType( baseName );

            classDocumentation += "Whenever you have to pass an object of type " + newClass.name() +
                                  " you can also pass the value directly (e.g. someMethod( (" + typeName + "*)value  )).";
            // include header
            newClass.addIncludes( QStringList(), mTypeMap.forwardDeclarations( baseName ) );

            // member variables
            KODE::MemberVariable variable( "value", typeName + '*' );
            newClass.addMemberVariable( variable );

            ctorBody += variable.name() + " = 0;";
            dtorBody += "delete " + variable.name() + "; " + variable.name() + " = 0;";

            // setter method
            KODE::Function setter( "setValue", "void" );
            setter.addArgument( typeName + " *value" );
            KODE::Code setterBody;
            setterBody += createRangeCheckCode( type, "(*value)", newClass );
            setterBody.newLine();
            setterBody += "if ( !rangeOk )";
            setterBody.indent();
            setterBody += "qDebug( \"Invalid range in " + newClass.name() + "::" + setter.name() + "()\" );";
            setterBody.unindent();
            setterBody.newLine();
            setterBody += variable.name() + " = value;";
            setter.setBody( setterBody );

            // getter method
            KODE::Function getter( "value", typeName + '*' );
            getter.setBody( "return " + variable.name() + ';' );
            getter.setConst( true );

            // convenience constructor
            KODE::Function conctor( upperlize( newClass.name() ) );
            conctor.addArgument( typeName + " *value" );
            KODE::Code code;
            code += createRangeCheckCode( type, "(*value)", newClass );
            code.newLine();
            code += "if ( !rangeOk )";
            code.indent();
            code += "qDebug( \"Invalid range in " + newClass.name() + "::" + conctor.name() + "()\" );";
            code.unindent();
            code.newLine();
            code += variable.name() + " = value;";
            conctor.setBody( code );

            if ( typeName == "QString" ) {
                KODE::Function charctor( upperlize( newClass.name() ) );
                charctor.addArgument( "const char *charValue" );
                KODE::Code code;
                code += "QString *value = new QString( charValue );";
                code += createRangeCheckCode( type, "(*value)", newClass );
                code.newLine();
                code += "if ( !rangeOk )";
                code.indent();
                code += "qDebug( \"Invalid range in " + newClass.name() + "::" + charctor.name() + "()\" );";
                code.unindent();
                code.newLine();
                code += variable.name() + " = value;";
                charctor.setBody( code );

                newClass.addFunction( charctor );
            }

            // type operator
            KODE::Function op( "operator const " + typeName + '*' );
            op.setBody( "return " + variable.name() + ';' );
            op.setConst( true );

            newClass.addFunction( conctor );
            newClass.addFunction( op );
            newClass.addFunction( setter );
            newClass.addFunction( getter );
        }
    } else if ( type->subType() == XSD::SimpleType::TypeList ) {
        classDocumentation = "This class encapsulates a list type.";

        newClass.addHeaderInclude( "QList" );
        const QName baseName = type->listTypeName();
        const QString typeName = mTypeMap.localType( baseName );

        // include header
        newClass.addIncludes( QStringList(), mTypeMap.forwardDeclarations( baseName ) );

        // member variables
        KODE::MemberVariable variable( "entries", "QList<" + typeName + "*>*" );
        newClass.addMemberVariable( variable );

        ctorBody += variable.name() + " = 0;";
        dtorBody += "qDeleteAll( *" + variable.name() + " );";
        dtorBody += variable.name() + "->clear();";
        dtorBody += "delete " + variable.name() + "; " + variable.name() + " = 0;";

        // setter method
        KODE::Function setter( "setEntries", "void" );
        setter.addArgument( "QList<" + typeName + "*> *entries" );
        setter.setBody( variable.name() + " = entries;" );

        // getter method
        KODE::Function getter( "entries", "QList<" + typeName + "*>*" );
        getter.setBody( "return " + variable.name() + ';' );
        getter.setConst( true );

        newClass.addFunction( setter );
        newClass.addFunction( getter );
    }

    if ( !type->documentation().isEmpty() )
        newClass.setDocs( type->documentation().simplified() );
    else
        newClass.setDocs( classDocumentation );

    createSimpleTypeSerializer( type );

    KODE::Function ctor( upperlize( newClass.name() ) );
    ctor.setBody( ctorBody );
    newClass.addFunction( ctor );

    KODE::Function dtor( '~' + upperlize( newClass.name() ) );
    dtor.setBody( dtorBody );
    newClass.addFunction( dtor );

    mClasses.append( newClass );
}
Пример #5
0
void Converter::createTransportClass()
{
  KODE::Class transport( "Transport" );
  transport.addBaseClass( mQObject );
  transport.addHeaderInclude( "qobject.h" );
  transport.addHeaderInclude( "kio/job.h" );

  transport.addInclude( "kdebug.h" );

  KODE::MemberVariable url( "url", "QString" );
  transport.addMemberVariable( url );

  KODE::MemberVariable slotDataVar( "data", "QByteArray" );
  transport.addMemberVariable( slotDataVar );

  // ctor
  KODE::Function ctor( "Transport" );
  ctor.addArgument( "const QString &url" );
  ctor.setBody( url.name() + " = url;" );

  transport.addFunction( ctor );

  // query
  KODE::Function query( "query", "void" );
  query.addArgument( "const QString &xml" );

  KODE::Code queryCode;
  queryCode += slotDataVar.name() + ".truncate( 0 );";
  queryCode.newLine();
  queryCode += "QByteArray postData;";
  queryCode += "QDataStream stream( postData, IO_WriteOnly );";
  queryCode += "stream.writeRawBytes( xml.utf8(), xml.utf8().length() );";
  queryCode.newLine();
  queryCode += "KIO::TransferJob* job = KIO::http_post( KURL( " + url.name() + " ), postData, false );";
  queryCode += "if ( !job ) {";
  queryCode.indent();
  queryCode += "kdWarning() << \"Unable to create KIO job for \" << " + url.name() + " << endl;";
  queryCode += "return;";
  queryCode.unindent();
  queryCode += "}";
  queryCode.newLine();
  queryCode += "job->addMetaData( \"UserAgent\", \"KWSDL\" );";
  queryCode += "job->addMetaData( \"content-type\", \"Content-Type: text/xml; charset=utf-8\" );";
  queryCode.newLine();
  queryCode += "connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) );";
  queryCode += "connect( job, SIGNAL( result( KIO::Job* ) ), this, SLOT( slotResult( KIO::Job* ) ) );";

  query.setBody( queryCode );

  transport.addFunction( query );

  // signal
  KODE::Function result( "result", "void", KODE::Function::Signal );
  result.addArgument( "const QString &xml" );

  transport.addFunction( result );

  // data slot
  KODE::Function slotData( "slotData", "void", KODE::Function::Private | KODE::Function::Slot );

  slotData.addArgument( "KIO::Job*" );
  slotData.addArgument( "const QByteArray &data" );

  KODE::Code slotDataCode;
  slotDataCode += "unsigned int oldSize = " + slotDataVar.name() + ".size();";
  slotDataCode += slotDataVar.name() + ".resize( oldSize + data.size() );";
  slotDataCode += "memcpy( " + slotDataVar.name() + ".data() + oldSize, data.data(), data.size() );";

  slotData.setBody( slotDataCode );

  transport.addFunction( slotData );

  // result slot
  KODE::Function slotResult( "slotResult", "void", KODE::Function::Private | KODE::Function::Slot );
  slotResult.addArgument( "KIO::Job* job" );

  KODE::Code slotResultCode;
  slotResultCode += "if ( job->error() != 0 ) {";
  slotResultCode.indent();
  slotResultCode += "kdWarning() << \"Error occurred \" << job->errorText() << endl;";
  slotResultCode += "kdWarning() << " + slotDataVar.name() + " << endl;";
  slotResultCode += "return;";
  slotResultCode.unindent();
  slotResultCode += "}";
  slotResultCode.newLine();

  slotResultCode += "emit result( QString::fromUtf8( " + slotDataVar.name() + ".data(), " + slotDataVar.name() + ".size() ) );";

  slotResult.setBody( slotResultCode );

  transport.addFunction( slotResult );

  mClasses.append( transport );
}
Пример #6
0
void Converter::convertSimpleType(const XSD::SimpleType *type, const XSD::SimpleType::List &simpleTypeList)
{
    const QString typeName(mTypeMap.localType(type->qualifiedName()));
    //qDebug() << "convertSimpleType:" << type->qualifiedName() << typeName;
    KODE::Class newClass;
    newClass.setNamespaceAndName(typeName);
    if (!Settings::self()->exportDeclaration().isEmpty()) {
        newClass.setExportDeclaration(Settings::self()->exportDeclaration());
    }
    newClass.setNameSpace(Settings::self()->nameSpace());

    QString classDocumentation;

    switch (type->subType()) {
    case XSD::SimpleType::TypeRestriction: {
        /**
          Use setter and getter method for enums as well.
         */
        if (type->facetType() & XSD::SimpleType::ENUM) {
            classDocumentation = "This class is a wrapper for an enumeration.\n";
            NameMapper nameMapper;
            QStringList enums = type->facetEnums();
            for (int i = 0; i < enums.count(); ++i) {
                enums[ i ] = nameMapper.escape(escapeEnum(enums[ i ]));
            }

            newClass.addEnum(KODE::Enum("Type", enums));

            classDocumentation += "Whenever you have to pass an object of type " + newClass.name() +
                                  " you can also pass the enum directly. Example:\n" +
                                  "someMethod(" + newClass.name() + "::" + enums.first() + ").";

            // member variables
            KODE::MemberVariable variable("type", "Type");
            variable.setInitializer("Type(0)");
            newClass.addMemberVariable(variable);

            // setter method
            KODE::Function setter("setType", "void");
            setter.addArgument("Type type");
            setter.setBody(variable.name() + " = type;");

            // getter method
            KODE::Function getter("type", newClass.qualifiedName() + "::Type");
            getter.setBody("return " + variable.name() + ';');
            getter.setConst(true);

            // convenience constructor
            KODE::Function conctor(newClass.name());
            conctor.addArgument("const Type &type");
            KODE::Code code;
            code += variable.name() + " = type;";
            conctor.setBody(code);

            // type operator
            KODE::Function op("operator Type");
            op.setBody("return " + variable.name() + ';');
            op.setConst(true);

            newClass.addFunction(conctor);
            newClass.addFunction(setter);
            newClass.addFunction(getter);
            newClass.addFunction(op);
        }

        /**
          A class can't derive from basic types (e.g. int or unsigned char), so
          we add setter and getter methods to set the value of this class.
         */
        if (type->baseTypeName() != XmlAnyType
                && !type->baseTypeName().isEmpty()
                && !(type->facetType() & XSD::SimpleType::ENUM)) {
            classDocumentation = "This class encapsulates a simple type.\n";

            const QName baseName = type->baseTypeName();
            const QString baseTypeName = mTypeMap.localType(baseName);
            Q_ASSERT(!baseTypeName.isEmpty());

            QList<QName> parentBasicTypes;
            parentBasicTypes.append(baseName);
            QName currentType = baseName;
            Q_FOREVER {
                const XSD::SimpleType simpleType = simpleTypeList.simpleType(currentType);
                if (!simpleType.isNull() && simpleType.isRestriction()) {
                    currentType = simpleType.baseTypeName();
                    parentBasicTypes.append(currentType);
                    continue;
                }
                break;
            }

            classDocumentation += "Whenever you have to pass an object of type " + newClass.name() +
                                  " you can also pass the value directly as a " + mTypeMap.localType(currentType) + '.';
            // include header
            newClass.addIncludes(QStringList(), mTypeMap.forwardDeclarations(baseName));
            newClass.addHeaderIncludes(mTypeMap.headerIncludes(baseName));

            // member variables
            KODE::MemberVariable variable("value", baseTypeName);
            addVariableInitializer(variable);
            newClass.addMemberVariable(variable);

            // setter method
            KODE::Function setter("setValue", "void");
            const QString inputType = mTypeMap.localInputType(baseName, QName());
            setter.addArgument(inputType + " value");
            KODE::Code setterBody;
            if (type->facetType() != XSD::SimpleType::NONE) {
                const XSD::SimpleType baseSimpleType = simpleTypeList.simpleType(baseName);
                setterBody += createRangeCheckCode(type, baseTypeName, "value", newClass, baseSimpleType);
                setterBody.newLine();
                setterBody += "if (!rangeOk)";
                setterBody.indent();
                setterBody += "qDebug( \"Invalid range in " + newClass.name() + "::" + setter.name() + "()\" );";
                setterBody.unindent();
                setterBody.newLine();
            }
            setterBody += variable.name() + " = value;"; // ### call setValue in base class?
            setter.setBody(setterBody);
            newClass.addFunction(setter);

            // getter method
            KODE::Function getter("value", baseTypeName);
            getter.setBody("return " + variable.name() + ';');
            getter.setConst(true);
            newClass.addFunction(getter);

            // convenience constructor
            KODE::Function conctor(newClass.name());
            conctor.addArgument(inputType + " value");
            conctor.addBodyLine("setValue(value);");
            newClass.addFunction(conctor);

            // even more convenient constructor, for the case of multiple-level simple-type restrictions
            //qDebug() << typeName << ": baseName=" << baseName << "further up:" << parentBasicTypes;
            if (parentBasicTypes.count() > 1) {
                parentBasicTypes.removeLast(); // the top-most one is in "currentType", so it's the input arg.
                KODE::Function baseCtor(conctor.name());
                baseCtor.addArgument(mTypeMap.localInputType(currentType, QName()) + " value");
                QString beginLine = "setValue(";
                QString endLine = ")";
                Q_FOREACH (const QName &base, parentBasicTypes) {
                    beginLine += mTypeMap.localType(base) + '(';
                    endLine += ')';
                }
                baseCtor.addBodyLine(beginLine + "value" + endLine + ';');
                newClass.addFunction(baseCtor);
            }

            // type operator
            KODE::Function op("operator " + baseTypeName);
            op.setBody("return " + variable.name() + ';');
            op.setConst(true);
            newClass.addFunction(op);
        }
Пример #7
0
void Converter::createKDETransport()
{
  KODE::Class transport( "Transport" );
  transport.addBaseClass( mQObject );
  transport.addHeaderInclude( "QObject" );
  transport.addHeaderInclude( "kio/job.h" );

  transport.addInclude( "kdebug.h" );

  KODE::MemberVariable url( "url", "QString" );
  transport.addMemberVariable( url );

  KODE::MemberVariable slotDataVar( "data", "QByteArray" );
  transport.addMemberVariable( slotDataVar );

  // ctor
  KODE::Function ctor( "Transport" );
  ctor.addArgument( "const QString &url" );
  ctor.setBody( url.name() + " = url;" );

  transport.addFunction( ctor );

  // query
  KODE::Function query( "query", "void" );
  query.addArgument( "const QString &xml" );
  query.addArgument( "const QString &header" );

  KODE::Code queryCode;
  queryCode += slotDataVar.name() + ".truncate( 0 );";
  queryCode.newLine();
  queryCode += "QByteArray postData;";
  queryCode += "QDataStream stream( &postData, QIODevice::WriteOnly );";
  queryCode += "stream.writeRawData( xml.toUtf8(), xml.toUtf8().length() );";
  queryCode.newLine();
  queryCode += "KIO::TransferJob* job = KIO::http_post( KUrl( " + url.name() + " ), postData, KIO::HideProgressInfo );";
  queryCode += "if ( !job ) {";
  queryCode.indent();
  queryCode += "kWarning() << \"Unable to create KIO job for \" <<" + url.name() +";";
  queryCode += "return;";
  queryCode.unindent();
  queryCode += '}';
  queryCode.newLine();
  queryCode += "job->addMetaData( \"UserAgent\", \"KWSDL\" );";
  queryCode += "job->addMetaData( \"content-type\", \"Content-Type: application/xml; charset=utf-8\" );";
  queryCode += "if ( !header.isEmpty() ) {";
  queryCode.indent();
  queryCode += "job->addMetaData( \"customHTTPHeader\", \"SOAPAction:\" + header );";
  queryCode.unindent();
  queryCode += '}';
  queryCode.newLine();
  queryCode += "connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), this, SLOT( slotData( KIO::Job*, const QByteArray& ) ) );";
  queryCode += "connect( job, SIGNAL( result( KJob* ) ), this, SLOT( slotResult( KJob* ) ) );";

  query.setBody( queryCode );

  transport.addFunction( query );

  // signal
  KODE::Function result( "result", "void", KODE::Function::Signal );
  result.addArgument( "const QString &xml" );

  KODE::Function error( "error", "void", KODE::Function::Signal );
  error.addArgument( "const QString &msg" );

  transport.addFunction( result );
  transport.addFunction( error );

  // data slot
  KODE::Function slotData( "slotData", "void", KODE::Function::Private | KODE::Function::Slot );

  slotData.addArgument( "KIO::Job*" );
  slotData.addArgument( "const QByteArray &data" );

  KODE::Code slotDataCode;
  slotDataCode += "unsigned int oldSize = " + slotDataVar.name() + ".size();";
  slotDataCode += slotDataVar.name() + ".resize( oldSize + data.size() );";
  slotDataCode += "memcpy( " + slotDataVar.name() + ".data() + oldSize, data.data(), data.size() );";

  slotData.setBody( slotDataCode );

  transport.addFunction( slotData );

  // result slot
  KODE::Function slotResult( "slotResult", "void", KODE::Function::Private | KODE::Function::Slot );
  slotResult.addArgument( "KJob* job" );

  KODE::Code slotResultCode;
  slotResultCode += "if ( job->error() != 0 ) {";
  slotResultCode.indent();
  slotResultCode += "emit error( job->errorText() );";
  slotResultCode += "return;";
  slotResultCode.unindent();
  slotResultCode += '}';
  slotResultCode.newLine();

  slotResultCode += "emit result( QString::fromUtf8( " + slotDataVar.name() + ".data(), " + slotDataVar.name() + ".size() ) );";

  slotResult.setBody( slotResultCode );

  transport.addFunction( slotResult );

  mClasses.append( transport );
}
Пример #8
0
void Converter::createQtTransport()
{
  KODE::Class transport( "Transport" );
  transport.addBaseClass( mQObject );
  transport.addHeaderInclude( "QBuffer" );
  transport.addHeaderInclude( "QByteArray" );
  transport.addHeaderInclude( "QObject" );
  transport.addHeaderInclude( "QHttp" );
  transport.addHeaderInclude( "QUrl" );

  // member variables
  KODE::MemberVariable bufferVar( "buffer", "QBuffer" );
  transport.addMemberVariable( bufferVar );

  KODE::MemberVariable dataVar( "data", "QByteArray" );
  transport.addMemberVariable( dataVar );

  KODE::MemberVariable httpVar( "http", "QHttp*" );
  transport.addMemberVariable( httpVar );

  KODE::MemberVariable urlVar( "url", "QUrl" );
  transport.addMemberVariable( urlVar );

  KODE::MemberVariable idVar( "id", "int" );
  transport.addMemberVariable( idVar );

  // functions
  KODE::Function ctor( "Transport" );
  ctor.addArgument( "const QString &url" );
  ctor.addInitializer( "QObject( 0 )" );
  ctor.addInitializer( urlVar.name() + "( url )" );

  KODE::Function query( "query", "void" );
  query.addArgument( "const QString &message" );
  query.addArgument( "const QString &headerStr" );

  KODE::Function resultSignal( "result", "void", KODE::Function::Signal );
  resultSignal.addArgument( "const QString &result" );

  KODE::Function errorSignal( "error", "void", KODE::Function::Signal );
  errorSignal.addArgument( "const QString &msg" );

  KODE::Function finishedSlot( "finished", "void", KODE::Function::Slot | KODE::Function::Private );
  finishedSlot.addArgument( "int id" );
  finishedSlot.addArgument( "bool errorOccurred" );

  // codes
  KODE::Code code;

  code += "QUrl server( url );";
  code.newLine();
  code += httpVar.name() + " = new QHttp( this );";
  code += httpVar.name() + "->setHost( server.host(), server.port( 80 ) );";
  code.newLine();
  code += "connect( " + httpVar.name() + ", SIGNAL( requestFinished( int, bool ) ), this, SLOT( " + finishedSlot.name() + "( int, bool ) ) );";
  ctor.setBody( code );

  code.clear();
  code += dataVar.name() + ".clear();";
  code += bufferVar.name() + ".setBuffer( &" + dataVar.name() + " );";
  code.newLine();
  code += "QHttpRequestHeader header;";
  code += "header.setRequest( \"POST\", " + urlVar.name() + ".path() );";
  code += "header.addValue( \"Connection\", \"Keep-Alive\" );";
  code += "header.addValue( \"Content-Type\", \"application/xml; charset=utf-8\" );";
  code += "header.addValue( \"Host\", QUrl( " + urlVar.name() + " ).host() );";
  code.newLine();
  code += "if ( !headerStr.isEmpty() )";
  code.indent();
  code += "header.addValue( \"SOAPAction\", headerStr );";
  code.unindent();
  code.newLine();
  code += "QUrl server( " + urlVar.name() + " );";
  code += "if ( server.port( 80 ) != 80 )";
  code.indent();
  code += "header.setValue( \"Host\", server.host() + \":\" + QString::number( server.port() ) );";
  code.unindent();
  code += "else";
  code.indent();
  code += "header.setValue( \"Host\", server.host() );";
  code.unindent();
  code.newLine();
  code += idVar.name() + " = " + httpVar.name() + "->request( header, message.toUtf8(), &" + bufferVar.name() + " );";
  query.setBody( code );

  code.clear();
  code += "if ( id != " + idVar.name() + " )";
  code.indent();
  code += "return;";
  code.unindent();
  code.newLine();
  code += "if ( errorOccurred )";
  code.indent();
  code += "emit " + errorSignal.name() + "( " + httpVar.name() + "->errorString() );";
  code.unindent();
  code += "else";
  code.indent();
  code += "emit " + resultSignal.name() + "( QString::fromUtf8( " + dataVar.name() + " ) );";
  code.unindent();
  finishedSlot.setBody( code );

  transport.addFunction( ctor );
  transport.addFunction( query );
  transport.addFunction( resultSignal );
  transport.addFunction( errorSignal );
  transport.addFunction( finishedSlot );

  mClasses.append( transport );
}
Пример #9
0
int create(KCmdLineArgs *args)
{
    KODE::Printer p;
    if(args->isSet("warning")) p.setCreationWarning(true);

    bool createKioslave = args->isSet("create-kioslave");
    bool createMain = args->isSet("create-main");

    QString filename = args->getOption("filename");

    if(createMain)
    {
        if(filename.isEmpty())
        {
            kdError() << "Error: No file name given." << endl;
            return 1;
        }

        if(filename.endsWith(".cpp"))
        {
            filename = filename.left(filename.length() - 4);
        }
    }
    else
    {
        if(!args->isSet("classname"))
        {
            kdError() << "Error: No class name given." << endl;
            return 1;
        }
    }

    QString className = args->getOption("classname");

    QString protocol;

    if(createKioslave)
    {
        if(!args->isSet("protocol"))
        {
            protocol = className.lower();
            kdWarning() << "Warning: No protocol for kioslave given. Assuming '"
                        << protocol << "'" << endl;
        }
        else
        {
            protocol = args->getOption("protocol");
        }
    }

    KODE::File file;

    file.setProject(args->getOption("project"));

    QString authorEmail = args->getOption("author-email");
    QString authorName;
    KABC::Addressee a;
    if(authorEmail.isEmpty())
    {
        a = KABC::StdAddressBook::self()->whoAmI();
        authorEmail = a.preferredEmail();
    }
    else
    {
        KABC::Addressee::List as =
            KABC::StdAddressBook::self()->findByEmail(authorEmail);
        if(as.isEmpty())
        {
            kdDebug() << "Unable to find '" << authorEmail << "' in address book."
                      << endl;
        }
        else
        {
            a = as.first();
        }
    }
    if(!a.isEmpty())
    {
        authorName = a.realName();
    }
    if(!authorEmail.isEmpty())
    {
        file.addCopyright(QDate::currentDate().year(), authorName, authorEmail);
    }

    KODE::License l;
    if(args->isSet("gpl")) l = KODE::License(KODE::License::GPL);
    if(args->isSet("lgpl")) l = KODE::License(KODE::License::LGPL);
    l.setQtException(args->isSet("qt-exception"));
    file.setLicense(l);

    file.setNameSpace(args->getOption("namespace"));

    if(createMain)
    {
        file.addInclude("kaboutdata.h");
        file.addInclude("kapplication.h");
        file.addInclude("kdebug");
        file.addInclude("klocale");
        file.addInclude("kcmdlineargs");

        KODE::Code code;
        code += "static const KCmdLineOptions options[] =";
        code += "{";
        code += "  { \"verbose\", \"Verbose output\", 0 },";
        code += "  KCmdLineLastOption";
        code += "};";
        file.addFileCode(code);

        KODE::Function main("main", "int");
        main.addArgument("int argc");
        main.addArgument("char **argv");

        code.clear();
        code += "KAboutData aboutData(\"test\",\"Test\",\"0.1\");";
        code += "KCmdLineArgs::init(argc,argv,&aboutData);";
        code += "KCmdLineArgs::addCmdLineOptions( options );";
        code += "";
        code += "KApplication app;";
        code += "";
        code += "KCmdLineArgs *args = KCmdLineArgs::parsedArgs();";
        code += "";
        code += "Q_UNUSED( args );";
        main.setBody(code);

        file.addFileFunction(main);

        file.setFilename(filename);

        p.printImplementation(file, false);

        return 0;
    }

    KODE::Class c(className);

    if(args->isSet("create-dialog"))
    {
        c.addBaseClass(KODE::Class("KDialogBase"));
        c.addInclude("kdialogbase.h");
    }
    else if(createKioslave)
    {
        c.setDocs("This class implements a kioslave for ...");

        c.addBaseClass(KODE::Class("SlaveBase", "KIO"));
        c.addHeaderInclude("kio/slavebase.h");

        KODE::Function get("get", "void");
        get.addArgument("const KURL &url");

        KODE::Code code;

        code += "kdDebug(7000) << \"" + className + "::get()\" << endl;";
        code += "kdDebug(7000) << \" URL: \" << url.url() << endl;";
        code += "#if 1";
        code += "kdDebug(7000) << \" Path: \" << url.path() << endl;";
        code += "kdDebug(7000) << \" Query: \" << url.query() << endl;";
        code += "kdDebug(7000) << \" Protocol: \" << url.protocol() << endl;";
        code += "kdDebug(7000) << \" Filename: \" << url.filename() << endl;";
        code += "#endif";
        code.newLine();

        code += "mimeType( \"text/plain\" );";
        code.newLine();

        code += "QCString str( \"Hello!\" );";
        code += "data( str );";
        code.newLine();

        code += "finished();";
        code.newLine();

        code += "kdDebug(7000) << \"" + className + "CgiProtocol::get() done\" << endl;";

        get.setBody(code);

        c.addFunction(get);


        c.addInclude("kinstance.h");
        c.addInclude("kdebug.h");
        c.addInclude("sys/types.h");
        c.addInclude("unistd.h");
        c.addInclude("stdlib.h");

        KODE::Function main("kdemain", "int");
        main.addArgument("int argc");
        main.addArgument("char **argv");

        code.clear();

        code += "KInstance instance( \"kio_" + protocol + "\" );";
        code += "";
        code += "kdDebug(7000) << \"Starting kio_" + protocol + "(pid:  \" << getpid() << \")\" << endl;";
        code += "";
        code += "if (argc != 4) {";
        code.indent();
        code += "fprintf( stderr, \"Usage: kio_" + protocol + " protocol domain-socket1 domain-socket2\\n\");";
        code += "exit( -1 );";
        code.unindent();
        code += "}";
        code += "";
        code += className + " slave( argv[2], argv[3] );";
        code += "slave.dispatchLoop();";
        code += "";
        code += "return 0;";

        main.setBody(code);

        file.addFileFunction(main);

        file.addExternCDeclaration(p.functionSignature(main));
    }

    KODE::Function constructor(className);

    if(args->isSet("singleton"))
    {
        constructor.setAccess(KODE::Function::Private);

        KODE::Function self("self", className + " *");
        self.setStatic(true);

        KODE::Code code;
        code += "if ( !mSelf ) {";
        code += "  selfDeleter.setObject( mSelf, new " + className + "() );";
        code += "}";
        code += "return mSelf;";

        self.setBody(code);

        c.addFunction(self);

        KODE::MemberVariable selfVar("mSelf", className + " *", true);
        selfVar.setInitializer("0");

        c.addMemberVariable(selfVar);

        KODE::Variable staticDeleter("selfDeleter",
                                     "KStaticDeleter<" + className + ">",
                                     true);
        file.addFileVariable(staticDeleter);
        file.addInclude("kstaticdeleter.h");
    }

    if(createKioslave)
    {
        constructor.addArgument("const QCString &pool");
        constructor.addArgument("const QCString &app");

        constructor.addInitializer("SlaveBase( \"" + protocol + "\", pool, app )");
    }

    c.addFunction(constructor);

    file.insertClass(c);

    p.printHeader(file);
    p.printImplementation(file);

    if(createKioslave)
    {
        // Write automake Makefile
        KODE::AutoMakefile am;

        am.addEntry("INCLUDES", "$(all_includes)");
        am.newLine();
        am.addEntry("noinst_HEADERS", className.lower() + ".h");
        am.newLine();
        am.addEntry("METASOURCES", "AUTO");
        am.newLine();
        am.addEntry("kdelnkdir", "$(kde_servicesdir)");
        am.addEntry("kdelnk_DATA", protocol + ".protocol");

        KODE::AutoMakefile::Target t("kde_module_LTLIBRARIES",
                                     "kio_" + protocol + ".la");
        t.setSources(className.lower() + ".cpp");
        t.setLibAdd("$(LIB_KIO)");
        t.setLdFlags("$(all_libraries) -module $(KDE_PLUGIN)");

        am.addTarget(t);

        p.printAutoMakefile(am);


        // Write protocol file
        QString protocolFilename = protocol + ".protocol";

        QFileInfo fi(protocolFilename);
        protocolFilename = fi.absFilePath();

        KSaveFile::backupFile(protocolFilename, QString::null, ".backup");

        QFile::remove(protocolFilename);

        KSimpleConfig protocolFile(protocolFilename);

        protocolFile.setGroup("Protocol");
        protocolFile.writeEntry("exec", "kio_" + protocol);
        protocolFile.writeEntry("protocol", protocol);
        protocolFile.writeEntry("input", "none");
        protocolFile.writeEntry("output", "filesystem");
        protocolFile.writeEntry("reading", "true");
        protocolFile.writeEntry("DocPath", "kioslave/" + protocol + ".html");

        protocolFile.sync();
    }

    return 0;
}