예제 #1
0
QString TypeMapper::type( const QString &typeName ) const
{
  // check basic types
  QMap<QString, TypeInfo>::ConstIterator it = mMap.find( typeName );
  if ( it != mMap.end() )
    return it.data().type;

  Schema::SimpleType::List simpleTypes = mTypes.simpleTypes();
  Schema::SimpleType::List::ConstIterator simpleIt;
  for ( simpleIt = simpleTypes.begin(); simpleIt != simpleTypes.end(); ++simpleIt ) {
    if ( (*simpleIt).name() == typeName ) {
      return type( &(*simpleIt) );
    }
  }

  Schema::ComplexType::List complexTypes = mTypes.complexTypes();
  Schema::ComplexType::List::ConstIterator complexIt;
  for ( complexIt = complexTypes.begin(); complexIt != complexTypes.end(); ++complexIt ) {
    if ( (*complexIt).name() == typeName ) {
      return type( &(*complexIt) );
    }
  }

  Schema::Element::List elements = mTypes.elements();
  Schema::Element::List::ConstIterator elemIt;
  for ( elemIt = elements.begin(); elemIt != elements.end(); ++elemIt ) {
    if ( (*elemIt).name() == typeName ) {
      return type( &(*elemIt) );
    }
  }

  return QString();
}
예제 #2
0
void Converter::createComplexTypeSerializer( const Schema::ComplexType *type )
{
  const QString typeName = mTypeMapper.type( type );

  KODE::Function marshal( "marshal", "void" );
  marshal.setStatic( true );
  marshal.addArgument( "QDomDocument &doc" );
  marshal.addArgument( "QDomElement &parent" );
  marshal.addArgument( "const QString &name" );
  marshal.addArgument( "const " + typeName + "* value" );

  KODE::Function demarshal( "demarshal", "void" );
  demarshal.setStatic( true );
  demarshal.addArgument( "const QDomElement &parent" );
  demarshal.addArgument( typeName + "* value" );

  KODE::Code marshalCode, demarshalCode, demarshalFinalCode;

  // include header
  QMap<QString, QString> headerDec = mTypeMapper.headerDec( type->name() );
  QMap<QString, QString>::ConstIterator it;
  for ( it = headerDec.begin(); it != headerDec.end(); ++it ) {
    if ( !it.key().isEmpty() )
      mSerializer.addInclude( it.key(), it.data() );

    if ( it.data().isEmpty() )
      mSerializer.addHeaderInclude( it.key() );
  }

  marshalCode += "QDomElement root = doc.createElement( name );";
  marshalCode += "root.setAttribute( \"xsi:type\", \"ns1:" + typeName + "\" );";
  marshalCode += "parent.appendChild( root );";

  demarshalCode += "QDomNode node = parent.firstChild();";
  demarshalCode += "while ( !node.isNull() ) {";
  demarshalCode.indent();
  demarshalCode += "QDomElement element = node.toElement();";
  demarshalCode += "if ( !element.isNull() ) {";
  demarshalCode.indent();

  // elements
  Schema::Element::List elements = type->elements();
  Schema::Element::List::ConstIterator elemIt;
  for ( elemIt = elements.begin(); elemIt != elements.end(); ++elemIt ) {
    const QString typeName = mTypeMapper.type( &*elemIt );

    QString upperName = (*elemIt).name();
    QString lowerName = (*elemIt).name();
    upperName[ 0 ] = upperName[ 0 ].upper();
    lowerName[ 0 ] = lowerName[ 0 ].lower();

    KODE::Function setter( "set" + upperName, "void" );
    KODE::Function getter( mNameMapper.escape( lowerName ), typeName + "*" );

    if ( (*elemIt).maxOccurs() > 1 ) {
      marshalCode += "if ( value->" + mNameMapper.escape( lowerName ) + "() ) {";
      marshalCode.indent();
      marshalCode += "const QPtrList<" + typeName + ">* list = value->" + mNameMapper.escape( lowerName ) + "();";
      marshalCode.newLine();
      marshalCode += "QDomElement element = doc.createElement( name );";
      // no idea about the namespaces here...
      marshalCode += "element.setAttribute( \"xmlns:ns1\", \"http://schemas.xmlsoap.org/soap/encoding/\" );";
      marshalCode += "element.setAttribute( \"xsi:type\", \"ns1:Array\" );";
      marshalCode += "element.setAttribute( \"ns1:arrayType\", \"ns1:" + typeName + "[\" + QString::number( list->count() ) + \"]\" );";
      marshalCode += "parent.appendChild( element );";
      marshalCode.newLine();
      marshalCode += "QPtrListIterator<" + typeName + "> it( *list );";
      marshalCode += "while ( it.current() != 0 ) {";
      marshalCode.indent();
      marshalCode += "Serializer::marshal( doc, element, \"item\", it.current() );";
      marshalCode += "++it;";
      marshalCode.unindent();
      marshalCode += "}";
      marshalCode.unindent();
      marshalCode += "}";

      const QString listName = mNameMapper.escape( lowerName ) + "List";
      // TODO: prepend the code somehow
      KODE::Code code;
      code += "QPtrList<" + typeName + ">* " + listName + " = new QPtrList<" + typeName + ">();";
      code += listName + "->setAutoDelete( true );";
      code += demarshalCode;
      demarshalCode = code;
      demarshalCode += "if ( element.tagName() == \"item\" ) {";
      demarshalCode.indent();
      demarshalCode += typeName + " *item = new " + typeName + ";";
      demarshalCode += "Serializer::demarshal( element, item );";
      demarshalCode += listName + "->append( item );";
      demarshalCode.unindent();
      demarshalCode += "}";

      demarshalFinalCode += "value->" + setter.name() + "( " + listName + " );";
    } else {
      marshalCode += "if ( value->" + getter.name() + "() ) {";
      marshalCode.indent();
      marshalCode += "Serializer::marshal( doc, root, \"" + (*elemIt).name() + "\", value->" + getter.name() + "() );";
      marshalCode.unindent();
      marshalCode += "}";

      demarshalCode += "if ( element.tagName() == \"" + (*elemIt).name() + "\" ) {";
      demarshalCode.indent();
      demarshalCode += typeName + "* item = new " + typeName + ";";
      demarshalCode += "Serializer::demarshal( element, item );";
      demarshalCode += "value->" + setter.name() + "( item );";
      demarshalCode.unindent();
      demarshalCode += "}";
    }
  }

  // attributes
  Schema::Attribute::List attributes = type->attributes();
  Schema::Attribute::List::ConstIterator attrIt;
  for ( attrIt = attributes.begin(); attrIt != attributes.end(); ++attrIt ) {
    const QString typeName = mTypeMapper.type( &*attrIt );

    QString upperName = (*attrIt).name();
    QString lowerName = (*attrIt).name();
    upperName[ 0 ] = upperName[ 0 ].upper();
    lowerName[ 0 ] = lowerName[ 0 ].lower();

    KODE::Function setter( "set" + upperName, "void" );
    KODE::Function getter( mNameMapper.escape( lowerName ), typeName + "*" );

    marshalCode += "if ( value->" + mNameMapper.escape( lowerName ) + "() )";
    marshalCode.indent();
    marshalCode += "parent.setAttribute( \"" + (*attrIt).name() + "\","
                                         "Serializer::marshalValue( value->" + mNameMapper.escape( lowerName ) + "() ) );";
    marshalCode.newLine();

    demarshalCode += "if ( element.hasAttribute( \"" + (*attrIt).name() + "\" ) ) {";
    demarshalCode.indent();
    demarshalCode += typeName + "* item = new " + typeName + ";";
    demarshalCode += "Serializer::demarshalValue( element.attribute( \"" + (*attrIt).name() + "\" ), item );";
    demarshalCode += "value->" + setter.name() + "( item );";
    demarshalCode.unindent();
    demarshalCode += "}";
  }

  demarshalCode.unindent();
  demarshalCode += "}";
  demarshalCode += "node = node.nextSibling();";
  demarshalCode.unindent();
  demarshalCode += "}";
  demarshalCode.newLine();
  demarshalCode += demarshalFinalCode;

  marshal.setBody( marshalCode );
  mSerializer.addFunction( marshal );

  demarshal.setBody( demarshalCode );
  mSerializer.addFunction( demarshal );
}
예제 #3
0
void Converter::convertComplexType( const Schema::ComplexType *type )
{
  KODE::Class newClass( type->name() );
  newClass.addInclude( "serializer.h" );

  KODE::Code ctorCode, dtorCode;

  if ( type->baseType() != Schema::XSDType::ANYTYPE && !type->isArray() ) {
    QString baseName = mTypeMapper.type( type->baseTypeName() );
    newClass.addBaseClass( KODE::Class( baseName ) );
    newClass.addHeaderIncludes( mTypeMapper.header( type->baseTypeName() ) );
  }

  if ( !type->documentation().isEmpty() )
    newClass.setDocs( type->documentation().simplifyWhiteSpace() );

  // elements
  Schema::Element::List elements = type->elements();
  Schema::Element::List::ConstIterator elemIt;
  for ( elemIt = elements.begin(); elemIt != elements.end(); ++elemIt ) {
    QString typeName = mTypeMapper.type( &*elemIt );

    if ( (*elemIt).maxOccurs() > 1 )
      typeName = "QPtrList<" + typeName + ">";

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

    ctorCode += variable.name() + " = 0;";
    dtorCode += "delete " + variable.name() + ";";
    dtorCode += variable.name() + " = 0;";

    QString upperName = (*elemIt).name();
    QString lowerName = (*elemIt).name();
    upperName[ 0 ] = upperName[ 0 ].upper();
    lowerName[ 0 ] = lowerName[ 0 ].lower();

    // setter method
    KODE::Function setter( "set" + upperName, "void" );
    setter.addArgument( mTypeMapper.argument( mNameMapper.escape( lowerName ), &*elemIt ) );
    setter.setBody( variable.name() + " = " + mNameMapper.escape( lowerName ) + ";" );

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

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

    // include header
    QMap<QString, QString> headerDec = mTypeMapper.headerDec( &*elemIt);
    QMap<QString, QString>::ConstIterator it;
    for ( it = headerDec.begin(); it != headerDec.end(); ++it ) {
      if ( !it.key().isEmpty() )
        newClass.addInclude( it.key(), it.data() );

      if ( it.data().isEmpty() )
        newClass.addHeaderInclude( it.key() );
    }
  }

  // attributes
  Schema::Attribute::List attributes = type->attributes();
  Schema::Attribute::List::ConstIterator attrIt;
  for ( attrIt = attributes.begin(); attrIt != attributes.end(); ++attrIt ) {
    const QString typeName = mTypeMapper.type( &*attrIt );

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

    ctorCode += variable.name() + " = 0;";
    dtorCode += "delete " + variable.name() + ";";
    dtorCode += variable.name() + " = 0;";

    QString upperName = (*attrIt).name();
    QString lowerName = (*attrIt).name();
    upperName[ 0 ] = upperName[ 0 ].upper();
    lowerName[ 0 ] = lowerName[ 0 ].lower();

    // setter method
    KODE::Function setter( "set" + upperName, "void" );
    setter.addArgument( mTypeMapper.argument( mNameMapper.escape( lowerName ), &*attrIt ) );
    setter.setBody( variable.name() + " = " + mNameMapper.escape( lowerName ) + ";" );

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

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

    // include header
    QMap<QString, QString> headerDec = mTypeMapper.headerDec( &*attrIt);
    QMap<QString, QString>::ConstIterator it;
    for ( it = headerDec.begin(); it != headerDec.end(); ++it ) {
      if ( !it.key().isEmpty() )
        newClass.addInclude( it.key(), it.data() );

      if ( it.data().isEmpty() )
        newClass.addHeaderInclude( it.key() );
    }
  }

  createComplexTypeSerializer( type );

  KODE::Function ctor( capitalize( newClass.name() ) );
  KODE::Function dtor( "~" + capitalize( newClass.name() ) );

  ctor.setBody( ctorCode );
  dtor.setBody( dtorCode );

  newClass.addFunction( ctor );
  newClass.addFunction( dtor );

  mClasses.append( newClass );
}