/***************************************************************************
* Copyright (C) 2004 - 2005 by Raphael Langerhorst *
* raphael-langerhorst@gmx.at *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: *
* *
* The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
* OTHER DEALINGS IN THE SOFTWARE. *
***************************************************************************/
#include "GCoreXmlSerializer.h"
#include <GweController.h>
#include <GweSimpleController.h>
#include <GDataController.h>
#include <GWorldData.h>
#include <GAttractAgent.h>
#include <GDynamicGeneratorAgent.h>
#include <GEnergyFormAgent.h>
#include <GMoveAgent.h>
#include <GRadiatingAgent.h>
#include <qstring.h>
#include <qdom.h>
#include <iostream>
using namespace std;
using namespace GCS;
using namespace GBE;
namespace GWE
{
GCoreXmlSerializer::GCoreXmlSerializer(const GCS::GWorldData* world_data, QObject *parent, const char *name)
: QObject(parent,name),
WorldData(world_data)
{
}
/*!
\fn GWE::GCoreXmlSerializer::~GCoreXmlSerializer()
*/
GCoreXmlSerializer::~GCoreXmlSerializer()
{
}
/*!
\fn GWE::GCoreXmlSerializer::createAgent(QDomElement data)
*/
GCS::GAgent* GCoreXmlSerializer::createAgent(QDomElement data)
{
//@todo for 0.6 release: temporary function till we get an agent factory to create the appropriate subagent
QString name = data.namedItem("name").toElement().text();
if (name.isEmpty())
{
qWarning("Agent name is empty!");
}
/*
GAttractAgent
GDynamicGeneratorAgent
GMoveAgent
GRadiatingAgent
*/
if (name == "GBE::GAttractAgent")
{
return new GAttractAgent();
}
else if (name == "GBE::GDynamicGeneratorAgent")
{
return new GDynamicGeneratorAgent();
}
else if (name == "GBE::GEnergyFormAgent")
{
return new GEnergyFormAgent();
}
else if (name == "GBE::GMoveAgent")
{
return new GMoveAgent();
}
else if (name == "GBE::GRadiatingAgent")
{
return new GRadiatingAgent();
}
else
{
qWarning(QString("Couldn't determine appropriate agent for given agent name: %1").arg(name));
return NULL;
}
}
/*!
\fn GWE::GCoreXmlSerializer::createAgent(QDomElement data)
*/
QPtrList<GCS::GAgent>* GCoreXmlSerializer::createAgents(QDomElement data)
{
if (data.isNull())
return NULL;
QPtrList<GCS::GAgent>* agents = new QPtrList<GCS::GAgent>;
QDomNode agentNode = data.firstChild();
while( !agentNode.isNull() )
{
if(agentNode.isElement())
{
agents->append(createAgent(agentNode.toElement()));
}
agentNode = agentNode.nextSibling();
}
return agents;
}
/*!
\fn GWE::GCoreXmlSerializer::createElementData(QDomElement data)
*/
QDomDocument* GCoreXmlSerializer::createElementData(QDomElement data)
{
if (data.isNull())
{
qWarning("Element Data to deserialize is NULL! Returning NULL.");
return NULL;
}
// else
// {
// qDebug("deserializing element data:");
// qDebug(data.ownerDocument().toString());
// }
QDomDocument* NewDocument = new QDomDocument();
QDomNode child = data.firstChild();
while (!child.isNull())
{
if (child.isElement())
NewDocument->appendChild(NewDocument->importNode(child,true));
child = child.nextSibling();
}
// if (!NewDocument->isNull())
// {
// qDebug("deserialized element data:");
// qDebug(NewDocument->toString());
// }
return NewDocument;
// @todo remove, GElementData is now a QDomDocument
// GCS::GElementData* elementData = new GCS::GElementData();
// elementData->setDomDocument(*NewDocument);
// return elementData;
}
/*!
\fn GWE::GCoreXmlSerializer::createElement(QDomElement data)
*/
GCS::GElement* GCoreXmlSerializer::createElement(QDomElement data)
{
if (data.isNull())
return NULL;
QPtrList<GCS::GAgent>* Agents = createAgents(data.namedItem("Agents").toElement());
if (Agents==NULL)
{
return NULL;
}
GCS::GObject * object = createObject(data.namedItem("Object").toElement());
if (object==NULL)
{
delete Agents;
return NULL;
}
GCS::GElement * element = new GCS::GElement(object);
if (element==NULL)
{
delete Agents;
delete object;
return NULL;
}
GCS::GAgent *Agent;
for ( Agent = Agents->first(); Agent; Agent = Agents->next() )
{
element->addAgent(Agent);
}
return element;
}
GCS::GElementID GCoreXmlSerializer::createElementID(QDomElement data, bool* ok)
{
if (ok!=NULL)
*ok=true;
if (data.isNull())
{
if (ok!=NULL)
*ok=false;
return GCS::GElementID(0);
}
else
return GCS::GElementID(data.text().toULong());
}
/*!
\fn GWE::GCoreXmlSerializer::createEnergy(QDomElement data)
*/
GCS::GEnergy* GCoreXmlSerializer::createEnergy(QDomElement data)
{
if (data.isNull())
return NULL;
bool ok=false;
double level = data.namedItem("Level").toElement().text().toDouble(&ok);
if (!ok)
return NULL;
double amount = data.namedItem("Amount").toElement().text().toDouble(&ok);
if (!ok)
return NULL;
double sigma = data.namedItem("Sigma").toElement().text().toDouble(&ok);
if (!ok)
return NULL;
return new GCS::GEnergy(level,amount,sigma);
}
/*!
\fn GWE::GCoreXmlSerializer::createForm(QDomElement data)
*/
GCS::GForm* GCoreXmlSerializer::createForm(QDomElement data)
{
QDomElement DomPosition = data.namedItem("Position").toElement();
QDomElement DomRotation = data.namedItem("Rotation").toElement();
QDomElement DomEllipsoid = data.namedItem("Ellipsoid").toElement();
if (DomPosition.isNull() || DomRotation.isNull() || DomEllipsoid.isNull())
return NULL;
bool ok;
//More efficient than making an extra function call to createVector3???
GCS::GVector3 position(this->createVector3(DomPosition,&ok));
if (!ok)
return NULL;
GCS::GVector3 rotation(this->createVector3(DomRotation,&ok));
if (!ok)
return NULL;
GCS::GVector3 ellipsoid(this->createVector3(DomEllipsoid,&ok));
if (!ok)
return NULL;
return new GCS::GForm(
position,
rotation,
ellipsoid);
}
/*!
\fn GWE::GCoreXmlSerializer::createVector3(QDomElement data)
*/
GCS::GVector3 GCoreXmlSerializer::createVector3(QDomElement data, bool* ok)
{
if (ok!=NULL)
*ok=true;
bool ok_private=false;
double x = data.namedItem("x").toElement().text().toDouble(&ok_private);
if (!ok_private)
{
if (ok!=NULL)
*ok=false;
}
double y = data.namedItem("y").toElement().text().toDouble(&ok_private);
if (!ok_private)
{
if (ok!=NULL)
*ok=false;
}
double z = data.namedItem("z").toElement().text().toDouble(&ok_private);
if (!ok_private)
{
if (ok!=NULL)
*ok=false;
}
return GCS::GVector3(x,y,z);
}
/*!
\fn GWE::GCoreXmlSerializer::createObject(QDomElement data)
*/
GCS::GObject* GCoreXmlSerializer::createObject(QDomElement data)
{
GCS::GEnergy * energy = createEnergy(data.namedItem("Energy").toElement());
if (energy==NULL)
return NULL;
GCS::GForm * form = createForm(data.namedItem("Form").toElement());
if (form==NULL)
{
delete energy;
return NULL;
}
bool ok=false;
GCS::GElementID parent = createElementID(data.namedItem("Parent").toElement(),&ok);
if (!ok)
{
delete energy;
delete form;
return NULL;
}
GCS::GElementID ID = createElementID(data.namedItem("ID").toElement(),&ok);
if (!ok)
{
delete energy;
delete form;
return NULL;
}
GCS::GElementID connection = createElementID(data.namedItem("Connection").toElement(),&ok);
if (!ok)
{
delete energy;
delete form;
return NULL;
}
QDomDocument * mydata = createElementData(data.namedItem("Data").toElement());
if (mydata == NULL)
{
delete energy;
delete form;
return NULL;
}
GCS::GObject* object = new GCS::GObject(energy,form,parent,ID,connection,mydata,WorldData);
if (object == NULL)
{
delete energy;
delete form;
delete mydata;
return NULL;
}
return object;
}
GCS::GMatrix44 GCoreXmlSerializer::createMatrix44(QDomElement data, bool* ok)
{
if (ok!=NULL)
*ok=true;
bool ok_private=false;
double m[4][4];
for (int i = 0; i<4; i++)
{
for (int j = 0; j<4; j++)
{
m[i][j] = data.namedItem(QString("m%1%2").arg(QString::number(i+1)).arg(QString::number(j+1))).toElement().text().toDouble(&ok_private);
if (!ok_private)
{
if (ok!=NULL)
*ok=false;
}
}
}
return GCS::GMatrix44(m[0][0],m[0][1],m[0][2],m[0][3],
m[1][0],m[1][1],m[1][2],m[1][3],
m[2][0],m[2][1],m[2][2],m[2][3],
m[3][0],m[3][1],m[3][2],m[3][3]);
}
GCS::GElementInfluence GCoreXmlSerializer::createElementInfluence(QDomElement data, bool* ok)
{
if (ok!=NULL)
*ok=true;
GCS::GEnergy* e = this->createEnergy(data.namedItem("Energy").toElement());
GCS::GEnergy energy;
if (e==NULL)
{
if (ok!=NULL)
*ok=false;
}
else
{
energy.set(*e);
}
delete e;
e=NULL;
GCS::GElementID id = this->createElementID(data.namedItem("Source").toElement(),ok);
return GCS::GElementInfluence(id,energy);
}
GCS::GElementID GCoreXmlSerializer::getInfluenceTarget(QDomElement data, bool* ok)
{
return GCS::GElementID(data.attribute("target","0").toULong(ok));
}
/*!
\fn GWE::GCoreXmlSerializer::serializeAgent(GCS::GAgent* agent, QString TagName, QDomDocument* document)
*/
QDomElement GCoreXmlSerializer::serializeAgent(const GCS::GAgent* agent, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
QDomElement Name = document->createElement( "name" );
root.appendChild( Name );
Name.appendChild( document->createTextNode( agent->className() ) );
return root;
}
/*!
\fn GWE::GCoreXmlSerializer::serializeElementData(GCS::GElementData* data)
*/
QDomElement GCoreXmlSerializer::serializeElementData(const QDomDocument* data, QString TagName, QDomDocument* document)
{
if (data->isNull())
{
qWarning("Element Data to serialize is NULL!");
}
Q_CHECK_PTR(data);
QDomElement e = document->createElement(TagName);
document->appendChild(e);
QDomNode child = data->firstChild();
while (!child.isNull())
{
if (child.isElement())
e.appendChild(document->importNode(child,true));
child = child.nextSibling();
}
// if (!data->isNull())
// {
// qDebug("original element data:");
// qDebug(data->toString());
// qDebug("serialized element data:");
// qDebug(document->toString());
// }
return e;
}
/*!
\fn GWE::GCoreXmlSerializer::serializeElement(GCS::GElement* element)
*/
QDomElement GCoreXmlSerializer::serializeElement(const GCS::GElement* element, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
root.appendChild(serializeObject(element->getObject(),QString("Object"),document));
root.appendChild(serializeAgents(element->getAgents(),QString("Agents"),document));
root.setAttribute(QString("ParkTime"),element->getParkTime().toString());
return root;
}
QDomElement GCoreXmlSerializer::serializeElementID(const GCS::GElementID& element_id, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
root.appendChild(document->createTextNode(QString::number(element_id.getID())));
return root;
}
/*!
\fn GWE::GCoreXmlSerializer::serializeEnergy(GCS::GEnergy* energy)
*/
QDomElement GCoreXmlSerializer::serializeEnergy(const GCS::GEnergy* energy, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
QString LevelString;
QString AmountString;
QString SigmaString;
LevelString.setNum(energy->level());
AmountString.setNum(energy->amount());
SigmaString.setNum(energy->sigma());
QDomElement Level = document->createElement( "Level" );
root.appendChild( Level );
Level.appendChild( document->createTextNode( LevelString ) );
QDomElement Amount = document->createElement( "Amount" );
root.appendChild( Amount );
Amount.appendChild( document->createTextNode( AmountString ) );
QDomElement Sigma = document->createElement( "Sigma" );
root.appendChild( Sigma );
Sigma.appendChild( document->createTextNode( SigmaString ) );
return root;
}
/*!
\fn GWE::GCoreXmlSerializer::serializeForm(GCS::GForm* form)
*/
QDomElement GCoreXmlSerializer::serializeForm(const GCS::GForm* form, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
root.appendChild( serializeVector3(&(form->Position),QString("Position"),document));
root.appendChild( serializeVector3(&(form->Rotation),QString("Rotation"),document));
root.appendChild( serializeVector3(&(form->Ellipsoid),QString("Ellipsoid"),document));
return root;
}
/*!
\fn GWE::GCoreXmlSerializer::serializeVector3(GCS::GVector3* vector3)
*/
QDomElement GCoreXmlSerializer::serializeVector3(const GCS::GVector3* vector3, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
QString XString;
QString YString;
QString ZString;
XString.setNum(vector3->x);
YString.setNum(vector3->y);
ZString.setNum(vector3->z);
QDomElement X = document->createElement( "x" );
root.appendChild( X );
X.appendChild( document->createTextNode( XString ) );
QDomElement Y = document->createElement( "y" );
root.appendChild( Y );
Y.appendChild( document->createTextNode( YString ) );
QDomElement Z = document->createElement( "z" );
root.appendChild( Z );
Z.appendChild( document->createTextNode( ZString ) );
return root;
}
QDomElement GCoreXmlSerializer::serializeObject(const GCS::GObject* object, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
root.appendChild(serializeEnergy(object->getEnergy(),QString("Energy"),document));
root.appendChild(serializeForm(object->getForm(),QString("Form"),document));
root.appendChild(serializeElementID(object->getParent(),QString("Parent"),document));
root.appendChild(serializeElementID(object->getID(),QString("ID"),document));
root.appendChild(serializeElementID(object->getConnection(),QString("Connection"),document));
root.appendChild(serializeElementData(object->getElementData(),QString("Data"),document));
return root;
}
QDomElement GCoreXmlSerializer::serializeAgents(QValueList<const GCS::GAgent*> Agents, QString TagName, QDomDocument* document)
{
QDomElement root = document->createElement( TagName );
document->appendChild( root );
QValueList<const GCS::GAgent*>::iterator it;
for ( it = Agents.begin(); it != Agents.end(); ++it )
{
root.appendChild(serializeAgent(*it,QString("Agent"),document));
}
return root;
}
QDomElement GCoreXmlSerializer::serializeMatrix44(const GCS::GMatrix44& matrix, QString TagName, QDomDocument* document)
{
//@todo implement
QDomElement root = document->createElement(TagName);
document->appendChild(root);
for (int i=0; i<4; i++)
{
for (int j=0; j<4; j++)
{
QDomElement e = document->createElement(QString("m")+QString::number(i+1)+QString::number(j+1));
root.appendChild(e);
e.appendChild(document->createTextNode(QString::number(matrix.m[i][j])));
}
}
return root;
}
QDomElement GCoreXmlSerializer::serializeElementInfluence(const GCS::GElementInfluence& influence, const GCS::GElementID& target_element, QString TagName, QDomDocument* document)
{
//@todo implement
// IMPORTANT: the target_element should be modelled as an "attribute" of the root DOM element;
// the GElementInfluence class does not hold any target IDs, thus we need to provide
// this additional info to be able to reconstruct the target at other servers (in createElementInfluence())
QDomElement root = document->createElement(TagName);
document->appendChild(root);
root.setAttribute("target",QString::number(target_element.getID()));
root.appendChild(this->serializeElementID(influence.source(),"Source",document));
root.appendChild(this->serializeEnergy(&influence.Energy,"Energy",document));
return root;
}
}
syntax highlighted by Code2HTML, v. 0.9.1