00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #include "xmlSerializer.h"
00014
00015 #include <QMetaClassInfo>
00016 #include <QDateTime>
00017
00018
00019
00020
00021
00022
00023 #define XML_SERIALIZER_VERSION "1.1"
00024
00026
00028
00029 XmlSerializer::XmlSerializer( QIODevice *pDevice, const QString &sRequestName )
00030 : m_bIsRoot( true ), PropertiesAsAttributes( true )
00031 {
00032 m_pXmlWriter = new QXmlStreamWriter( pDevice );
00033 m_sRequestName = sRequestName;
00034 }
00035
00037
00039
00040 XmlSerializer::~XmlSerializer()
00041 {
00042 if (m_pXmlWriter != NULL)
00043 {
00044 delete m_pXmlWriter;
00045 m_pXmlWriter = NULL;
00046 }
00047 }
00048
00050
00052
00053 QString XmlSerializer::GetContentType()
00054 {
00055 return "text/xml";
00056 }
00057
00059
00061
00062 void XmlSerializer::BeginSerialize( QString &sName )
00063 {
00064 m_pXmlWriter->writeStartDocument( "1.0" );
00065
00066 }
00067
00069
00071
00072 void XmlSerializer::EndSerialize()
00073 {
00074 m_pXmlWriter->writeEndDocument();
00075 }
00076
00078
00080
00081 void XmlSerializer::BeginObject( const QString &sName, const QObject *pObject )
00082 {
00083 m_pXmlWriter->writeStartElement( sName );
00084
00085 if (m_bIsRoot)
00086 {
00087 m_pXmlWriter->writeAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
00088
00089 m_bIsRoot = false;
00090 }
00091
00092 const QMetaObject *pMeta = pObject->metaObject();
00093
00094 int nIdx = pMeta->indexOfClassInfo( "version" );
00095
00096 if (nIdx >=0)
00097 m_pXmlWriter->writeAttribute( "version", pMeta->classInfo( nIdx ).value() );
00098
00099 m_pXmlWriter->writeAttribute( "serializerVersion", XML_SERIALIZER_VERSION );
00100
00101 }
00102
00104
00106
00107 void XmlSerializer::EndObject ( const QString &sName, const QObject *pObject )
00108 {
00109 m_pXmlWriter->writeEndElement();
00110 }
00111
00113
00115
00116 void XmlSerializer::AddProperty( const QString &sName,
00117 const QVariant &vValue,
00118 const QMetaObject *pMetaParent,
00119 const QMetaProperty *pMetaProp )
00120 {
00121 m_pXmlWriter->writeStartElement( sName );
00122 RenderValue( GetContentName( sName, pMetaParent, pMetaProp ), vValue );
00123 m_pXmlWriter->writeEndElement();
00124 }
00125
00127
00129
00130 void XmlSerializer::RenderValue( const QString &sName, const QVariant &vValue )
00131 {
00132
00133
00134
00135
00136
00137 if ( vValue.canConvert< QObject* >())
00138 {
00139 const QObject *pObject = vValue.value< QObject* >();
00140
00141 SerializeObjectProperties( pObject );
00142 return;
00143 }
00144
00145
00146
00147
00148
00149 switch( vValue.type() )
00150 {
00151 case QVariant::List:
00152 {
00153 RenderList( sName, vValue.toList() );
00154 break;
00155 }
00156
00157 case QVariant::StringList:
00158 {
00159 RenderStringList( sName, vValue.toStringList() );
00160 break;
00161 }
00162
00163 case QVariant::Map:
00164 {
00165 RenderMap( sName, vValue.toMap() );
00166 break;
00167 }
00168
00169 case QVariant::DateTime:
00170 {
00171 QDateTime dt( vValue.toDateTime() );
00172
00173 if (dt.isNull())
00174 m_pXmlWriter->writeAttribute( "xsi:nil", "true" );
00175
00176 m_pXmlWriter->writeCharacters( dt.toUTC().toString(Qt::ISODate) );
00177 break;
00178 }
00179
00180 default:
00181 {
00182 m_pXmlWriter->writeCharacters( vValue.toString() );
00183 break;
00184 }
00185 }
00186
00187 }
00188
00190
00192
00193 void XmlSerializer::RenderList( const QString &sName, const QVariantList &list )
00194 {
00195
00196
00197 QListIterator< QVariant > it( list );
00198
00199 while (it.hasNext())
00200 {
00201 QVariant vValue = it.next();
00202
00203
00204
00205
00206 m_pXmlWriter->writeStartElement( sName );
00207 RenderValue( sName, vValue );
00208 m_pXmlWriter->writeEndElement();
00209 }
00210 }
00211
00213
00215
00216 void XmlSerializer::RenderStringList( const QString &sName, const QStringList &list )
00217 {
00218 QString sItemName = GetItemName( sName );
00219
00220 QListIterator< QString > it( list );
00221
00222 while (it.hasNext())
00223 {
00224 m_pXmlWriter->writeStartElement( "String" );
00225 m_pXmlWriter->writeCharacters ( it.next() );
00226 m_pXmlWriter->writeEndElement();
00227 }
00228 }
00229
00231
00233
00234 void XmlSerializer::RenderMap( const QString &sName, const QVariantMap &map )
00235 {
00236
00237 QMapIterator< QString, QVariant > it( map );
00238
00239 QString sItemName = GetItemName( sName );
00240
00241 while (it.hasNext())
00242 {
00243 it.next();
00244
00245 m_pXmlWriter->writeStartElement( sItemName );
00246
00247 m_pXmlWriter->writeStartElement( "Key" );
00248 m_pXmlWriter->writeCharacters( it.key() );
00249 m_pXmlWriter->writeEndElement();
00250
00251 m_pXmlWriter->writeStartElement( "Value" );
00252 RenderValue( sItemName, it.value() );
00253 m_pXmlWriter->writeEndElement();
00254
00255
00256
00257
00258
00259
00260 m_pXmlWriter->writeEndElement();
00261 }
00262 }
00263
00265
00266
00268
00269 QString XmlSerializer::GetItemName( const QString &sName )
00270 {
00271 QString sTypeName( sName );
00272
00273 if (sName.at(0) == 'Q')
00274 sTypeName = sName.mid( 1 );
00275
00276 sTypeName.remove( "DTC::" );
00277 sTypeName.remove( QChar('*') );
00278
00279 return sTypeName;
00280 }
00281
00283
00285
00286 QString XmlSerializer::GetContentName( const QString &sName,
00287 const QMetaObject *pMetaObject,
00288 const QMetaProperty *pMetaProp )
00289 {
00290
00291
00292 int nClassIdx = pMetaObject->indexOfClassInfo( sName.toAscii() );
00293
00294 if (nClassIdx >=0)
00295 {
00296 QString sOptionData = pMetaObject->classInfo( nClassIdx ).value();
00297 QStringList sOptions = sOptionData.split( ';' );
00298
00299 QString sNameOption = FindOptionValue( sOptions, "name" );
00300
00301 if (sNameOption.isEmpty())
00302 sNameOption = FindOptionValue( sOptions, "type" );
00303
00304 if (!sNameOption.isEmpty())
00305 return GetItemName( sNameOption );
00306 }
00307
00308
00309
00310 QString sTypeName( sName );
00311
00312 if (sName.at(0) == 'Q')
00313 sTypeName = sName.mid( 1 );
00314
00315 sTypeName.remove( "DTC::" );
00316 sTypeName.remove( QChar('*') );
00317
00318 return sTypeName;
00319 }
00320
00322
00324
00325 QString XmlSerializer::FindOptionValue( const QStringList &sOptions, const QString &sName )
00326 {
00327 QString sKey = sName + "=";
00328
00329 for (int nIdx = 0; nIdx < sOptions.size(); ++nIdx)
00330 {
00331 if (sOptions.at( nIdx ).startsWith( sKey ))
00332 return sOptions.at( nIdx ).mid( sKey.length() );
00333 }
00334
00335 return QString();
00336 }