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 ); }
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); }