CTypeInfo* CReferenceDataType::CreateTypeInfo(void) { CClassTypeInfo* info = CClassInfoHelper<AnyType>::CreateClassInfo(m_UserTypeName.c_str()); info->SetImplicit(); CMemberInfo* memInfo = info->AddMember("", 0, ResolveOrThrow()->GetTypeInfo()); const CDataMember *mem = GetDataMember(); if (!mem && GetParentType()) { mem = GetParentType()->GetDataMember(); } if (mem) { if (mem->Optional()) { memInfo->SetOptional(); } if (mem->NoPrefix()) { memInfo->SetNoPrefix(); } if (IsNillable()) { memInfo->SetNillable(); } } if ( GetParentType() == 0 ) { // global info->SetModuleName(GetModule()->GetName()); } return info; }
bool Xsd::RenderXSD( HTTPRequest *pRequest, QObject *pClass ) { const QMetaObject *pMetaObject = pClass->metaObject(); QString sClassName = ConvertTypeToXSD( pMetaObject->className(), true); QDomElement oRoot = CreateSchemaRoot(); QMap<QString, TypeInfo> typesToInclude; // ------------------------------------------------------------------ // Create xs:complexType structure // ------------------------------------------------------------------ QDomElement oTypeNode = createElement( "xs:complexType" ); QDomElement oSeqNode = createElement( "xs:sequence" ); oTypeNode.setAttribute( "name", sClassName ); oTypeNode.appendChild( oSeqNode ); // -=>TODO: Add an xs:annotation node with class descriptions // ------------------------------------------------------------------ // Add all properties for this type // // <xs:element minOccurs="0" name="<propName>" type="<propType>"/> // <xs:element minOccurs="0" name="<childName>" nillable="true" // type="tns:<ChildType>"/> // ------------------------------------------------------------------ int nCount = pMetaObject->propertyCount(); for (int nIdx=0; nIdx < nCount; ++nIdx ) { QMetaProperty metaProperty = pMetaObject->property( nIdx ); if (metaProperty.isDesignable( pClass )) { const char *pszPropName = metaProperty.name(); QString sPropName( pszPropName ); if ( sPropName.compare( "objectName" ) == 0) continue; // ---------------------------------------------------------- // Create xs:element for this property // ---------------------------------------------------------- QDomElement oNode = createElement( "xs:element" ); QString sType = metaProperty.typeName(); bool bCustomType = false; QString sCustomAttr = "type"; QString sContentName = QString(); QString sContentType = QString(); // if this is a child object, sType will be QObject* // which we can't use, so we need to read the // properties value, and read it's metaObject data if (sType == "QObject*") { QVariant val = metaProperty.read( pClass ); const QObject *pObject = val.value< QObject* >(); sType = pObject->metaObject()->className(); bCustomType = true; } else if ((sType == "QVariantList" ) || (sType == "QVariantMap")) { sContentType = ReadPropertyMetadata( pClass, sPropName, "type" ); if (sContentType.at(0) == 'Q') sContentType = sContentType.mid( 1 ); sContentType.remove( "DTC::" ); sContentType.remove( QChar('*') ); if (sType == "QVariantMap") { sContentName = ReadPropertyMetadata( pClass, sPropName, "name" ); if (sContentName.isEmpty()) sContentName = sContentType; sType = "MapOfString" + sContentName; } else sType = "ArrayOf" + sContentType; bCustomType = true; } else if (sType == "QStringList") { sType = "ArrayOfString"; bCustomType = true; } else if (metaProperty.isEnumType() || metaProperty.isFlagType() ) { sCustomAttr = "enum"; sType = sClassName + "." + sType; bCustomType = true; } QString sNewPropName( metaProperty.name() ); if (IsNillable( sType )) oNode.setAttribute( "nillable" , true ); if (bCustomType) { TypeInfo info = { sCustomAttr, sContentType }; typesToInclude.insert( sType, info ); } oNode.setAttribute( "type" , (bCustomType ? "tns:" : "xs:") + ConvertTypeToXSD( sType, bCustomType )); oNode.setAttribute( "name" , sNewPropName ); oNode.setAttribute( "minOccurs", 0 ); oSeqNode.appendChild( oNode ); } } // ------------------------------------------------------------------ // Create element for class // // <xs:element name="<className>" nillable="true" type="tns:<className>"/> // ------------------------------------------------------------------ QDomElement oElementNode = createElement( "xs:element" ); oElementNode.setAttribute( "type" , "tns:" + sClassName ); oElementNode.setAttribute( "nillable", "true" ); oElementNode.setAttribute( "name" , sClassName ); // ---------------------------------------------------------------------- // Build xml tree... // ---------------------------------------------------------------------- appendChild( oRoot ); if (typesToInclude.count() > 0) { // ------------------------------------------------------------------ // Create all needed includes // // <xs:include schemaLocation="<path to dependant schema"/> // ------------------------------------------------------------------ QString sBaseUri = "http://" + pRequest->m_mapHeaders[ "host" ] + pRequest->m_sResourceUrl; QMap<QString, TypeInfo >::const_iterator it = typesToInclude.constBegin(); while( it != typesToInclude.constEnd()) { QDomElement oIncNode = createElement( "xs:include" ); QString sType = it.key(); sType.remove( "DTC::" ); TypeInfo info = it.value(); QString sValue = QString( "%1?%2=%3" ).arg( sBaseUri ) .arg( info.sAttrName ) .arg( sType ); if (!info.sContentType.isEmpty()) sValue += "&name=" + info.sContentType; oIncNode.setAttribute( "schemaLocation", sValue ); oRoot.appendChild( oIncNode ); ++it; } } oRoot.appendChild( oTypeNode ); oRoot.appendChild( oElementNode ); // ---------------------------------------------------------------------- // Return xsd doc to caller // ---------------------------------------------------------------------- QTextStream os( &(pRequest->m_response) ); pRequest->m_eResponseType = ResponseTypeXML; save( os, 0 ); return true; }