updated new xml philosophy

This commit is contained in:
Guido Ranzuglia granzuglia 2010-11-17 10:45:26 +00:00
parent 845bf3a2f0
commit 9511bf41d6
5 changed files with 154 additions and 60 deletions

View File

@ -1,32 +1,45 @@
#ifndef ML_EXCEPTION
#define ML_EXCEPTION
class ParsingException : public std::exception
class MeshLabException : public std::exception
{
public:
MeshLabException(const QString& text)
:std::exception(),excText(text){_ba = excText.toLocal8Bit();}
~MeshLabException() throw() {}
inline const char* what() const throw() {return _ba.constData();}
protected:
QString excText;
QByteArray _ba;
};
class ParsingException : public MeshLabException
{
public:
ParsingException(const QString& text)
:excText(text){excText = QString("Parsing Error: ") + excText;_ba = excText.toLocal8Bit();}
:MeshLabException(QString("Parsing Error: ") + text){}
~ParsingException() throw() {}
inline const char* what() const throw() {return _ba.constData();}
private:
QString excText;
QByteArray _ba;
};
class ValueNotFoundException : public std::exception
class ValueNotFoundException : public MeshLabException
{
public:
ValueNotFoundException(const QString& valName)
:valNM(valName){valNM = QString("Value Name: ") + valNM + QString(" has not been found in current environment.");_ba = valNM.toLocal8Bit();}
:MeshLabException(QString("Value Name: ") + valName + QString(" has not been found in current environment.")){}
~ValueNotFoundException() throw() {}
inline const char* what() const throw() { return _ba.constData();}
private:
QString valNM;
QByteArray _ba;
};
class QueryException : public MeshLabException
{
public:
QueryException(const QString& syntaxError)
:MeshLabException(QString("Query Error: ") + syntaxError){}
~QueryException() throw() {}
};
#endif

View File

@ -64,8 +64,7 @@ void PluginManager::loadPlugins(RichParameterSet& defaultGlobal)
fc.xmlInfo = XMLFilterInfo::createXMLFileInfo(xmlFile,xmlSchemaFile(),xmlErr);
if (fc.xmlInfo != NULL)
{
XMLMessageHandler errQuery;
QStringList fn = fc.xmlInfo->filterNames(errQuery);
QStringList fn = fc.xmlInfo->filterNames();
foreach(QString filtName,fn)
{
fc.act = new QAction(filtName,plugin);
@ -78,7 +77,7 @@ void PluginManager::loadPlugins(RichParameterSet& defaultGlobal)
else
{
QString err = xmlErr.statusMessage();
qDebug("Error in XMLFile: %s - %s",qPrintable(xmlFile),qPrintable(err));
qDebug("Error in XMLFile: %s - line: %d, column: %d - %s",qPrintable(xmlFile),xmlErr.line(),xmlErr.column(),qPrintable(err));
}
}
@ -253,7 +252,7 @@ void PluginManager::LoadFormats(QStringList &filters, QHash<QString, MeshIOInter
void PluginManager::updateDocumentScriptBindings(MeshDocument& doc )
{
//delete currentDocInterface;
//WARNING!
//all the currentDocInterface created will be destroyed by QT when the MeshDocument destructor has been called
currentDocInterface = new MeshDocumentScriptInterface(&doc);
QScriptValue val = env.newQObject(currentDocInterface);

View File

@ -58,6 +58,7 @@ class MeshDocumentScriptInterface : public QObject
public:
MeshDocumentScriptInterface(MeshDocument* doc);
~MeshDocumentScriptInterface(){}
Q_INVOKABLE MeshModelScriptInterface* getMesh(const int meshId);
Q_INVOKABLE MeshModelScriptInterface* current();

View File

@ -5,6 +5,7 @@
#include <QUrl>
#include <QtXmlPatterns/QXmlQuery>
#include <QStringList>
#include "mlexception.h"
XMLFilterInfo* XMLFilterInfo::createXMLFileInfo( const QString& XMLFileName,const QString& XMLSchemaFileName,XMLMessageHandler& errXML)
{
@ -33,51 +34,61 @@ XMLFilterInfo* XMLFilterInfo::createXMLFileInfo( const QString& XMLFileName,cons
}
file.close();
validator.setMessageHandler(oldHandler);
return new XMLFilterInfo(XMLFileName);
}
return new XMLFilterInfo(XMLFileName);
return NULL;
}
QStringList XMLFilterInfo::filterNames(XMLMessageHandler& errQuery) const
QStringList XMLFilterInfo::filterNames() const
{
QString namesQuery = "doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER/<p>{data(@name)}</p>/string()";
return query(namesQuery,errQuery);
try
{
return query(namesQuery);
}
catch(QueryException e)
{
qDebug(e.what());
}
}
QString XMLFilterInfo::filterHelp( const QString& filterName,bool& isValid,XMLMessageHandler& errQuery) const
QString XMLFilterInfo::filterHelp( const QString& filterName) const
{
QString namesQuery = "doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER[@name = \"" + filterName + "\"]/FILTER_HELP/string()";
QStringList res = query(namesQuery,errQuery);
if (res.size() != 1)
try
{
isValid = false;
return QString();
}
else
{
isValid = true;
QStringList res = query(namesQuery);
if (res.size() != 1)
throw ParsingException("There is not help tag for filter " + filterName);
return res[0];
}
catch(QueryException q)
{
qDebug(q.what());
}
}
QString XMLFilterInfo::filterAttribute( const QString& filterName,const QString& attribute,bool& isValid,XMLMessageHandler& errQuery) const
QString XMLFilterInfo::filterAttribute( const QString& filterName,const QString& attribute) const
{
QString namesQuery = "doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER[@name = \"" + filterName + "\"]/@" + attribute + "/string()";
QStringList res = query(namesQuery,errQuery);
if (res.size() != 1)
try
{
isValid = false;
return QString();
}
else
QStringList res = query(namesQuery);
if (res.size() != 1)
throw ParsingException("Attribute " + attribute + " has not been specified for filter " + filterName);
return res[0];
}
catch (QueryException e)
{
isValid = true;
return res[0];
qDebug(e.what());
}
}
QStringList XMLFilterInfo::query( const QString& qry,XMLMessageHandler& errQuery ) const
QStringList XMLFilterInfo::query( const QString& qry) const
{
XMLMessageHandler errQuery;
QXmlQuery xmlq;
xmlq.setQuery(qry);
QAbstractMessageHandler * oldHandler = xmlq.messageHandler();
@ -88,21 +99,83 @@ QStringList XMLFilterInfo::query( const QString& qry,XMLMessageHandler& errQuery
{
//errQuery = xmlq.messageHandler();
xmlq.setMessageHandler(oldHandler);
QString mes = errQuery.statusMessage();
return result;
throw QueryException(QString("line: ") + errQuery.line() + " column: " + errQuery.column() + " - " + errQuery.statusMessage());
}
xmlq.evaluateTo(&result);
QString res;
xmlq.evaluateTo(&res);
xmlq.setMessageHandler(oldHandler);
return result;
}
QStringList XMLFilterInfo::filterParameters( const QString& filterName,bool& isValid,XMLMessageHandler& errQuery) const
XMLFilterInfo::MapList XMLFilterInfo::filterParameters( const QString& filterName) const
{
QString namesQuery = "doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER[@name = \"" + filterName + "\"]/PARAM/<p>{data(@type)},{data(@name)},{data(@defaultExpression)}</p>/string()";
QStringList res = query(namesQuery,errQuery);
if (res.size() == 0)
isValid = false;
else
isValid = true;
return res;
QString namesQuery = "doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER[@name = \"" + filterName + "\"]/PARAM/<p>type={data(@type)}|name={data(@name)}|defaultExpression={data(@defaultExpression)}</p>/string()";
try
{
QStringList res = query(namesQuery);
return mapListFromStringList(res);
}
catch (QueryException e)
{
throw e;
}
}
XMLFilterInfo::MapList XMLFilterInfo::mapListFromStringList( const QStringList& list )
{
MapList result;
//"attribute0=value0|attribute1=value1|...|attributeN=valueN" "attribute0=value0|attribute1=value1|...|attributeN=valueN" "attribute0=value0|attribute1=value1|...|attributeN=valueN"
foreach(QString st, list)
{
QStringList coupleList = st.split('|');
QMap<QString,QString> attrValue;
foreach(QString couple,coupleList)
{
QStringList cl = couple.split('=');
if (cl.size() == 2)
attrValue[cl[0]]=cl[1];
}
result.push_back(attrValue);
}
return result;
}
QString XMLFilterInfo::defaultGuiInfo(const QString& guiType,const QString& xmlvariable)
{
return QString("type=" + guiType + "|label={data(" + xmlvariable + "/@label)}");
}
QString XMLFilterInfo::floatGuiInfo(const QString& guiType,const QString& xmlvariable)
{
return defaultGuiInfo(guiType,xmlvariable) + "|minExpr={data(" + xmlvariable + "/@minExpr)}|maxExpr={data(" + xmlvariable + "/@maxExpr)}";
}
QMap<QString,QString> XMLFilterInfo::filterParameterGui( const QString& filterName,const QString& parameterName) const
{
QString var("$gui");
QString queryBase("for " + var + " in doc(\"" + this->fileName + "\")/MESHLAB_FILTER_INTERFACE/PLUGIN/FILTER[@name = " + filterName + "]/PARAM[@name =" + parameterName + "]/(* except PARAM_HELP) return typeswitch($gui)\n");
QString caseABS("element (ABSPERC_GUI) return <p>" + defaultGuiInfo("ABSPERC_GUI",var) + "</p>/string()\n");
QString caseFLOAT("element (CHECKBOX_GUI) return <p>" + defaultGuiInfo("CHECKBOX_GUI",var) + "</p>/string()\n");
QString errorMsg("Error: Unknown GUI widget requested");
QString defaultCase("default return " + errorMsg);
QString totQuery = queryBase + caseABS + caseFLOAT + defaultCase;
QMap<QString,QString> mp;
try
{
QStringList res = query(totQuery);
XMLFilterInfo::MapList tmp = mapListFromStringList(res);
//MUST BE FOR EACH PARAMETER ONLY ONE GUI DECLARATION
if (tmp.size() != 1)
throw ParsingException("In filter " + filterName + " more than a single GUI declaration has been found for parameter " + parameterName);
else if (res[0] == errorMsg)
//GUI NOT DEFINED
throw ParsingException("In filter " + filterName + " no valid GUI declaration has been found for parameter " + parameterName);
else return tmp[0];
}
catch(QueryException e)
{
qDebug(e.what());
}
}

View File

@ -47,28 +47,36 @@ private:
};
//Query Exception should be managed by the XMLFilterInfo class (XMLFilterInfo is the class devoted to compose queries)
//Parsing Exception instead should be managed by the code calling the XMLFilterInfo's functions.
//A Parsing Exception is raised every time an unexpected and/or missing tag or attribute in an XML has been encountered.
//So this kind of info it's sensible for the plugin's programmer.
class XMLFilterInfo
{
private:
XMLFilterInfo(const QString& file)
:fileName(file){}
static QString defaultGuiInfo(const QString& guiType,const QString& xmlvariable);
static QString floatGuiInfo(const QString& guiType,const QString& xmlvariable);
QString fileName;
public:
typedef QList< QMap<QString,QString> > MapList;
static MapList mapListFromStringList(const QStringList& list);
static XMLFilterInfo* createXMLFileInfo(const QString& XMLFileName,const QString& XMLSchemaFileName,XMLMessageHandler& errXML);
inline static void deleteXMLFileInfo(XMLFilterInfo* xmlInfo) {delete xmlInfo;}
QStringList filterNames(XMLMessageHandler& errXML) const;
QString filterHelp(const QString& filterName,bool& isValid,XMLMessageHandler& errXML) const;
QStringList filterNames() const;
QString filterHelp(const QString& filterName) const;
//The function returns a string list of all parameters for filterName. Each string in the list is a triple param_type,param_name,param_defaultExpression
//In order to parse each triple component is sufficient to call split(',')
QStringList filterParameters(const QString& filterName,bool& isValid,XMLMessageHandler& errXML) const;
QString filterAttribute(const QString& filterName,const QString& attribute,bool& isValid,XMLMessageHandler& errXML) const;
//The function returns a QList<QMap<QString,QString>>. Each map contains "type", "name" and "defaultExpression" of a single parameter.
MapList filterParameters(const QString& filterName) const;
/*QStringList filterParameters(const QString& filter);
QStringList filterParametersAndGui(const QString& filter);*/
QStringList query(const QString& qry,XMLMessageHandler& errQuery) const;
QMap<QString,QString> filterParameterGui(const QString& filter,const QString& parameter) const;
QString filterAttribute(const QString& filterName,const QString& attribute) const;
QStringList query(const QString& qry) const;
};
struct MeshLabXMLFilterContainer