Skip to content

Commit

Permalink
V2 Services: xsd for enums to treat them as strings
Browse files Browse the repository at this point in the history
There is a bunch of code that is supposed to produce an xsd for enums
that includes a list of possible values. This does not work, so the code
is changed to specify the enum as a string value.
  • Loading branch information
bennettpeter committed Sep 10, 2021
1 parent 0271d20 commit 4c292f5
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 186 deletions.
5 changes: 3 additions & 2 deletions mythtv/libs/libmythbase/http/mythhttpservice.cpp
Expand Up @@ -45,8 +45,9 @@ HTTPResponse MythHTTPService::HTTPRequest(HTTPRequest2 Request)
MythXSD xsd;
if (Request->m_queries.contains( "type" ))
return xsd.GetXSD( Request, Request->m_queries.value("type"));
else
return xsd.GetEnumXSD( Request, Request->m_queries.value("enum"));
// The xsd for enums does not work, so it is commented for now.
// else
// return xsd.GetEnumXSD( Request, Request->m_queries.value("enum"));
}

// Find the method
Expand Down
368 changes: 185 additions & 183 deletions mythtv/libs/libmythbase/http/mythxsd.cpp
Expand Up @@ -24,180 +24,183 @@
//
/////////////////////////////////////////////////////////////////////////////

HTTPResponse MythXSD::GetEnumXSD( HTTPRequest2 pRequest, const QString& sEnumName )
{
if (sEnumName.isEmpty())
return Error(pRequest, QString( "XSD request on empty invalid enum name"));

// ----------------------------------------------------------------------
// sEnumName needs to be in class.enum format
// ----------------------------------------------------------------------

if (sEnumName.count('.') != 1 )
return Error(pRequest, QString( "XSD request invalid enum name %1").arg(sEnumName));

QStringList lstTypeParts = sEnumName.split( '.' );

// ----------------------------------------------------------------------
// Create Parent object so we can get to its metaObject
// ----------------------------------------------------------------------

QString sParentFQN = lstTypeParts[0];
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
int nParentId = QMetaType::type( sParentFQN.toUtf8() );

// ----------------------------------------------------------------------
// Check for things that were formerly registered as both 'Foo' and 'Foo*'
// ----------------------------------------------------------------------
if (nParentId == QMetaType::UnknownType)
{
QString sFQN = sParentFQN + "*";
nParentId = QMetaType::type( sFQN.toUtf8() );
}

// ----------------------------------------------------------------------
// if a DataContract type, we need to prefix name with DTC::
// These types are all pointers to objects, so we also need to add "*"
// ----------------------------------------------------------------------

if (nParentId == QMetaType::UnknownType)
{
QString sFQN = "V2" + sParentFQN + "*";
nParentId = QMetaType::type( sFQN.toUtf8() );
}

if (nParentId == QMetaType::UnknownType)
return Error(pRequest, QString( "XSD request unknown enum name %1").arg(sEnumName));
const QMetaObject *pMetaObject = QMetaType::metaObjectForType(nParentId);
#else
QMetaType metaType = QMetaType::fromName( sParentFQN.toUtf8() );
if (metaType.id() == QMetaType::UnknownType)
metaType = QMetaType::fromName( sParentFQN.toUtf8() + "*" );
if (metaType.id() == QMetaType::UnknownType)
metaType = QMetaType::fromName( "V2" + sParentFQN.toUtf8() + "*" );
if (metaType.id() == QMetaType::UnknownType)
return Error(pRequest, QString( "XSD request unknown enum name %1").arg(sEnumName));
const QMetaObject *pMetaObject = metaType.metaObject();
#endif

if (pMetaObject == nullptr)
return Error(pRequest, QString( "XSD cannot find enum name %1").arg(sEnumName));

// ----------------------------------------------------------------------
// Now look up enum
// ----------------------------------------------------------------------

int nEnumIdx = pMetaObject->indexOfEnumerator( lstTypeParts[1].toUtf8() );

if (nEnumIdx < 0 )
return Error(pRequest, QString( "XSD cannot find values for enum name %1").arg(sEnumName));

QMetaEnum metaEnum = pMetaObject->enumerator( nEnumIdx );

// ----------------------------------------------------------------------
// render xsd for this enum
//
// <xs:simpleType name="RecordingInfo.RecordingDupMethodEnum">
// <xs:restriction base="xs:string">
// <xs:enumeration value="kDupCheckNone">
// <xs:annotation>
// <xs:appinfo>
// <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1</EnumerationValue>
// </xs:appinfo>
// </xs:annotation>
// </xs:enumeration>
// <xs:enumeration value="kDupCheckSub">
// <xs:annotation>
// <xs:appinfo>
// <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">2</EnumerationValue>
// </xs:appinfo>
// </xs:annotation>
// </xs:enumeration>
// </xs:restriction>
// </xs:simpleType>
//
// <xs:element name="RecordingInfo.RecordingDupMethodEnum" type="tns:RecordingInfo.RecordingDupMethodEnum" nillable="true"/>
// ----------------------------------------------------------------------

if (!pRequest->m_queries.contains( "raw" ))
{
appendChild( createProcessingInstruction( "xml-stylesheet",
R"(type="text/xsl" href="/xslt/enum.xslt")" ));
}
// The code for creating the enum in xsd does not work
// Since there is only one enum n the entire system, treat it as a string

// HTTPResponse MythXSD::GetEnumXSD( HTTPRequest2 pRequest, const QString& sEnumName )
// {
// if (sEnumName.isEmpty())
// return Error(pRequest, QString( "XSD request on empty invalid enum name"));

// // ----------------------------------------------------------------------
// // sEnumName needs to be in class.enum format
// // ----------------------------------------------------------------------

// if (sEnumName.count('.') != 1 )
// return Error(pRequest, QString( "XSD request invalid enum name %1").arg(sEnumName));

// QStringList lstTypeParts = sEnumName.split( '.' );

// // ----------------------------------------------------------------------
// // Create Parent object so we can get to its metaObject
// // ----------------------------------------------------------------------

// QString sParentFQN = lstTypeParts[0];
// #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
// int nParentId = QMetaType::type( sParentFQN.toUtf8() );

// // ----------------------------------------------------------------------
// // Check for things that were formerly registered as both 'Foo' and 'Foo*'
// // ----------------------------------------------------------------------
// if (nParentId == QMetaType::UnknownType)
// {
// QString sFQN = sParentFQN + "*";
// nParentId = QMetaType::type( sFQN.toUtf8() );
// }

// // ----------------------------------------------------------------------
// // if a DataContract type, we need to prefix name with DTC::
// // These types are all pointers to objects, so we also need to add "*"
// // ----------------------------------------------------------------------

// if (nParentId == QMetaType::UnknownType)
// {
// QString sFQN = "V2" + sParentFQN + "*";
// nParentId = QMetaType::type( sFQN.toUtf8() );
// }

// if (nParentId == QMetaType::UnknownType)
// return Error(pRequest, QString( "XSD request unknown enum name %1").arg(sEnumName));
// const QMetaObject *pMetaObject = QMetaType::metaObjectForType(nParentId);
// #else
// QMetaType metaType = QMetaType::fromName( sParentFQN.toUtf8() );
// if (metaType.id() == QMetaType::UnknownType)
// metaType = QMetaType::fromName( sParentFQN.toUtf8() + "*" );
// if (metaType.id() == QMetaType::UnknownType)
// metaType = QMetaType::fromName( "V2" + sParentFQN.toUtf8() + "*" );
// if (metaType.id() == QMetaType::UnknownType)
// return Error(pRequest, QString( "XSD request unknown enum name %1").arg(sEnumName));
// const QMetaObject *pMetaObject = metaType.metaObject();
// #endif

// if (pMetaObject == nullptr)
// return Error(pRequest, QString( "XSD cannot find enum name %1").arg(sEnumName));

// // ----------------------------------------------------------------------
// // Now look up enum
// // ----------------------------------------------------------------------

// int nEnumIdx = pMetaObject->indexOfEnumerator( lstTypeParts[1].toUtf8() );

// if (nEnumIdx < 0 )
// return Error(pRequest, QString( "XSD cannot find values for enum name %1").arg(sEnumName));

// QMetaEnum metaEnum = pMetaObject->enumerator( nEnumIdx );

// // ----------------------------------------------------------------------
// // render xsd for this enum
// //
// // <xs:simpleType name="RecordingInfo.RecordingDupMethodEnum">
// // <xs:restriction base="xs:string">
// // <xs:enumeration value="kDupCheckNone">
// // <xs:annotation>
// // <xs:appinfo>
// // <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1</EnumerationValue>
// // </xs:appinfo>
// // </xs:annotation>
// // </xs:enumeration>
// // <xs:enumeration value="kDupCheckSub">
// // <xs:annotation>
// // <xs:appinfo>
// // <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">2</EnumerationValue>
// // </xs:appinfo>
// // </xs:annotation>
// // </xs:enumeration>
// // </xs:restriction>
// // </xs:simpleType>
// //
// // <xs:element name="RecordingInfo.RecordingDupMethodEnum" type="tns:RecordingInfo.RecordingDupMethodEnum" nillable="true"/>
// // ----------------------------------------------------------------------

// if (!pRequest->m_queries.contains( "raw" ))
// {
// appendChild( createProcessingInstruction( "xml-stylesheet",
// R"(type="text/xsl" href="/xslt/enum.xslt")" ));
// }

// // ----------------------------------------------------------------------
// // Create xs:simpleType structure
// // ----------------------------------------------------------------------

// QDomElement oTypeNode = createElement( "xs:simpleType" );
// QDomElement oRestrictNode = createElement( "xs:restriction" );

// oTypeNode .setAttribute( "name", sEnumName );
// oRestrictNode.setAttribute( "base", "xs:string" );

// oTypeNode.appendChild( oRestrictNode );

// for( int nIdx = 0; nIdx < metaEnum.keyCount(); nIdx++)
// {
// QDomElement oEnum = createElement( "xs:enumeration" );

// oEnum.setAttribute( "value", metaEnum.key( nIdx ));

// // ------------------------------------------------------------------
// // Add appInfo to store numerical value & translated text
// // ------------------------------------------------------------------

// QDomElement oAnn = createElement( "xs:annotation" );
// QDomElement oApp = createElement( "xs:appinfo" );
// QDomElement oEnumVal = createElement( "EnumerationValue" );
// QDomElement oEnumDesc = createElement( "EnumerationDesc" );

// // The following namespace is needed for visual studio to generate negative enums correctly.
// oEnumVal.setAttribute("xmlns", "http://schemas.microsoft.com/2003/10/Serialization/");

// oEnum.appendChild( oAnn );
// oAnn .appendChild( oApp );
// oApp .appendChild( oEnumVal );
// oApp .appendChild( oEnumDesc );

// QString sFQNKey = sEnumName + "." + metaEnum.key( nIdx );

// oEnumVal .appendChild( createTextNode( QString::number( metaEnum.value( nIdx ))));
// oEnumDesc.appendChild( createTextNode( QCoreApplication::translate("Enums",
// sFQNKey.toUtf8() )));

// oRestrictNode.appendChild( oEnum );
// }

// // ----------------------------------------------------------------------

// QDomElement oElementNode = createElement( "xs:element" );

// oElementNode.setAttribute( "name" , sEnumName );
// oElementNode.setAttribute( "type" , "tns:" + sEnumName );
// oElementNode.setAttribute( "nillable", "true" );

// ----------------------------------------------------------------------
// Create xs:simpleType structure
// ----------------------------------------------------------------------

QDomElement oTypeNode = createElement( "xs:simpleType" );
QDomElement oRestrictNode = createElement( "xs:restriction" );

oTypeNode .setAttribute( "name", sEnumName );
oRestrictNode.setAttribute( "base", "xs:string" );

oTypeNode.appendChild( oRestrictNode );

for( int nIdx = 0; nIdx < metaEnum.keyCount(); nIdx++)
{
QDomElement oEnum = createElement( "xs:enumeration" );

oEnum.setAttribute( "value", metaEnum.key( nIdx ));

// ------------------------------------------------------------------
// Add appInfo to store numerical value & translated text
// ------------------------------------------------------------------

QDomElement oAnn = createElement( "xs:annotation" );
QDomElement oApp = createElement( "xs:appinfo" );
QDomElement oEnumVal = createElement( "EnumerationValue" );
QDomElement oEnumDesc = createElement( "EnumerationDesc" );

// The following namespace is needed for visual studio to generate negative enums correctly.
oEnumVal.setAttribute("xmlns", "http://schemas.microsoft.com/2003/10/Serialization/");

oEnum.appendChild( oAnn );
oAnn .appendChild( oApp );
oApp .appendChild( oEnumVal );
oApp .appendChild( oEnumDesc );

QString sFQNKey = sEnumName + "." + metaEnum.key( nIdx );

oEnumVal .appendChild( createTextNode( QString::number( metaEnum.value( nIdx ))));
oEnumDesc.appendChild( createTextNode( QCoreApplication::translate("Enums",
sFQNKey.toUtf8() )));

oRestrictNode.appendChild( oEnum );
}

// ----------------------------------------------------------------------

QDomElement oElementNode = createElement( "xs:element" );

oElementNode.setAttribute( "name" , sEnumName );
oElementNode.setAttribute( "type" , "tns:" + sEnumName );
oElementNode.setAttribute( "nillable", "true" );
// // ----------------------------------------------------------------------
// //
// // ----------------------------------------------------------------------

// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------

QDomElement oRoot = CreateSchemaRoot();

oRoot.appendChild( oTypeNode );
oRoot.appendChild( oElementNode );

appendChild( oRoot );
// QDomElement oRoot = CreateSchemaRoot();

// ----------------------------------------------------------------------
// Return xsd doc to caller
// ----------------------------------------------------------------------
// oRoot.appendChild( oTypeNode );
// oRoot.appendChild( oElementNode );

// Create the XML result
auto data = MythHTTPData::Create(toByteArray());
data->m_mimeType = MythMimeDatabase().MimeTypeForName("application/xml");
data->m_cacheType = HTTPETag | HTTPShortLife;
return MythHTTPResponse::DataResponse(pRequest, data);
}
// appendChild( oRoot );

// // ----------------------------------------------------------------------
// // Return xsd doc to caller
// // ----------------------------------------------------------------------

// // Create the XML result
// auto data = MythHTTPData::Create(toByteArray());
// data->m_mimeType = MythMimeDatabase().MimeTypeForName("application/xml");
// data->m_cacheType = HTTPETag | HTTPShortLife;
// return MythHTTPResponse::DataResponse(pRequest, data);
// }

/////////////////////////////////////////////////////////////////////////////
//
Expand Down Expand Up @@ -457,19 +460,18 @@ bool MythXSD::RenderXSD( HTTPRequest2 pRequest, QObject *pClass )
}
else if (IsEnum( metaProperty, sType ))
{
sCustomAttr = "enum";

if (sType.startsWith("V2"))
sType.remove(0,2);

// if sType still contains "::", then no need to prefix with sClassName

if (sType.contains( "::" ))
sType = sType.replace( "::", "." );
else
sType = sClassName + "." + sType;

bCustomType = true;
// The code for creating the enum in xsd does not work
// Since there is only one enum, treat it as a string
// sCustomAttr = "enum";
// if (sType.startsWith("V2"))
// sType.remove(0,2);
// // if sType still contains "::", then no need to prefix with sClassName
// if (sType.contains( "::" ))
// sType = sType.replace( "::", "." );
// else
// sType = sClassName + "." + sType;
// bCustomType = true;
sType="string";
}

QString sNewPropName( metaProperty.name() );
Expand Down

0 comments on commit 4c292f5

Please sign in to comment.