casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QtDBusXML.h
Go to the documentation of this file.
00001 //# QtDBusXML.h: XML scheme to be used with CASA's Qt DBus communication.
00002 //# Copyright (C) 2009
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: $
00027 #ifndef QTDBUSXML_H_
00028 #define QTDBUSXML_H_
00029 
00030 #include <casa/Containers/Record.h>
00031 
00032 #include <QDomDocument>
00033 #include <QDBusArgument>
00034 #include <QMetaType>
00035 
00036 #include <casa/namespace.h>
00037 
00038 namespace casa {
00039 
00040 // Subclass of QDomDocument that represents an XML scheme that is to be used
00041 // with CASA's Qt dbus communication.
00042 // <casa-dbus>
00043 //   <time>[TIMESTAMP]</time>
00044 //   <from>[NAME]</from>
00045 //   <to>[NAME]</to>
00046 //   <method name="[METHOD]" async="[ISASYNC]">
00047 //     <param name="[NAME]" type="[TYPE]">[VALUE]</param>
00048 //     ...
00049 //   </method>
00050 //   <returned type="[TYPE]">[VALUE]</returned>
00051 // </casa-dbus>
00052 // Currently supported types for parameters and returned values:
00053 //   bool, int, uInt, double, String, Records with these types.
00054 // For a discussion of what these fields mean, see the documentation for
00055 // QtDBusXmlApp.
00056 class QtDBusXML {
00057 public:
00058     // Static Methods //
00059     
00060     // Constructs and returns an XML message using the given parameters.  Only
00061     // uses the non-empty values.  Sets the time to the current.
00062     // <group>
00063     static QtDBusXML constructXML(const String& from = "",
00064             const String& to = "", const String& methodName = "",
00065             bool methodIsAsync = false, const Record& methodParams = Record(),
00066             const Record& retValue = Record()) {
00067         return constructXML(QString(from.c_str()), QString(to.c_str()),
00068                 QString(methodName.c_str()), methodIsAsync, methodParams,
00069                 retValue); }
00070     static QtDBusXML constructXML(const QString& from = "",
00071             const QString& to = "", const QString& methodName = "",
00072             bool methodIsAsync = false, const Record& methodParams = Record(),
00073             const Record& retValue = Record());
00074     // </group>
00075     
00076     // Constructs and returns an XML message from the given XML string.
00077     // <group>
00078     static QtDBusXML fromString(const String& xmlStr) {
00079         return fromString(QString(xmlStr.c_str())); }
00080     static QtDBusXML fromString(const QString& xmlStr);
00081     // </group>
00082     
00083     // Reads the values from the given XML message into the given parameters
00084     // which are not NULL.
00085     // <group>
00086     static void extractXML(const QtDBusXML& xml, String* time = NULL,
00087             String* from = NULL, String* to = NULL, String* methodName = NULL,
00088             Record* methodParams = NULL, Record* retValue = NULL) {
00089         QString* qtime = NULL, *qfrom = NULL, *qto = NULL, *qmethodName = NULL;
00090         if(time != NULL)       qtime       = new QString();
00091         if(from != NULL)       qfrom       = new QString();
00092         if(to != NULL)         qto         = new QString();
00093         if(methodName != NULL) qmethodName = new QString();
00094         extractXML(xml, qtime, qfrom, qto, qmethodName, methodParams,retValue);
00095         if(time != NULL)       { *time = qtime->toStdString(); delete qtime; }
00096         if(from != NULL)       { *from = qfrom->toStdString(); delete qfrom; }
00097         if(to != NULL)         { *to = qto->toStdString(); delete qto; }
00098         if(methodName != NULL) { *methodName = qmethodName->toStdString();
00099                                  delete qmethodName; }
00100     }
00101     static void extractXML(const QtDBusXML& xml, QString* time = NULL,
00102             QString* from = NULL, QString* to = NULL, QString* methodName=NULL,
00103             Record* methodParams = NULL, Record* retValue = NULL);
00104     // </group>
00105     
00106     
00107     // Non-Static Methods //
00108     
00109     // Constructor.
00110     QtDBusXML();
00111     
00112     // Copy constructor, see operator=().
00113     QtDBusXML(const QtDBusXML& copy);
00114     
00115     // Destructor.
00116     virtual ~QtDBusXML();
00117     
00118     
00119     // Gets the value of the time tag, or an empty string if there is none.
00120     // <group>
00121     String time() const { return qtime().toStdString(); }
00122     QString qtime() const;
00123     // </group>
00124     
00125     // Sets the time tag to the current time.
00126     void setTime();
00127     
00128     // Gets/Sets the from tag.
00129     // <group>
00130     String from() const { return qfrom().toStdString(); }
00131     QString qfrom() const;
00132     void setFrom(const String& value) { setFrom(QString(value.c_str())); }
00133     void setFrom(const QString& value);
00134     // </group>
00135     
00136     // Gets/Sets the to tag.
00137     // <group>
00138     String to() const { return qto().toStdString(); }
00139     QString qto() const;
00140     void setTo(const String& value) { setTo(QString(value.c_str())); }
00141     void setTo(const QString& value);
00142     // </group>
00143     
00144     // Gets/Sets the method name and whether the method call is asynchronous or
00145     // not (default is false).
00146     // <group>
00147     String methodName() const { return qmethodName().toStdString(); }
00148     QString qmethodName() const;
00149     bool methodIsAsync() const;
00150     void setMethodName(const String& value, bool isAsync = false) {
00151         setMethodName(QString(value.c_str()), isAsync); }
00152     void setMethodName(const QString& value, bool isAsync = false);
00153     void setMethodIsAsync(bool value);
00154     // </group>
00155     
00156     // Returns the type of the method parameter with the given name, or an
00157     // empty string if there is none.
00158     // <group>
00159     String methodParamType(const String& paramName) const {
00160         return qmethodParamType(QString(paramName.c_str())).toStdString(); }
00161     QString qmethodParamType(const QString& paramName) const;
00162     // </group>
00163     
00164     // Returns whether the method parameter with the given name is the
00165     // specified type or not.
00166     // <group>
00167     bool methodParamIsBool(const String& paramName) const;
00168     bool methodParamIsInt(const String& paramName) const;
00169     bool methodParamIsUInt(const String& paramName) const;
00170     bool methodParamIsDouble(const String& paramName) const;
00171     bool methodParamIsString(const String& paramName) const;
00172     bool methodParamIsRecord(const String& paramName) const;
00173     // </group>
00174     
00175     // Returns the value of the method parameter with the given name as the
00176     // specified type.  Is invalid if that parameter is not of the requested
00177     // type.  Note: the value can always be returned as a string
00178     // representation.
00179     // <group>
00180     bool methodParamBool(const String& paramName) const {
00181         return methodParamBool(QString(paramName.c_str())); }
00182     bool methodParamBool(const QString& paramName) const;
00183     int methodParamInt(const String& paramName) const {
00184         return methodParamInt(QString(paramName.c_str())); }
00185     int methodParamInt(const QString& paramName) const;
00186     uInt methodParamUInt(const String& paramName) const {
00187         return methodParamUInt(QString(paramName.c_str())); }
00188     uInt methodParamUInt(const QString& paramName) const;
00189     double methodParamDouble(const String& paramName) const {
00190         return methodParamDouble(QString(paramName.c_str())); }
00191     double methodParamDouble(const QString& paramName) const;
00192     String methodParamString(const String& paramName) const {
00193         return methodParamQString(QString(paramName.c_str())).toStdString(); }
00194     QString methodParamQString(const QString& paramName) const;
00195     Record methodParamRecord(const String& paramName) const {
00196         return methodParamRecord(QString(paramName.c_str())); }
00197     Record methodParamRecord(const QString& paramName) const;
00198     // </group>
00199     
00200     // Sets the parameter with the given name to the given value (and
00201     // associated type).
00202     // <group>
00203     void setMethodParam(const String& paramName, bool value) {
00204         setMethodParam(QString(paramName.c_str()), value); }
00205     void setMethodParam(const QString& paramName, bool value);
00206     void setMethodParam(const String& paramName, int value) {
00207         setMethodParam(QString(paramName.c_str()), value); }
00208     void setMethodParam(const QString& paramName, int value);
00209     void setMethodParam(const String& paramName, uInt value) {
00210         setMethodParam(QString(paramName.c_str()), value); }
00211     void setMethodParam(const QString& paramName, uInt value);
00212     void setMethodParam(const String& paramName, double value) {
00213         setMethodParam(QString(paramName.c_str()), value); }
00214     void setMethodParam(const QString& paramName, double value);
00215     void setMethodParam(const String& paramName, const String& value) {
00216         setMethodParam(QString(paramName.c_str()), QString(value.c_str())); }
00217     void setMethodParam(const QString& paramName, const QString& value);
00218     void setMethodParam(const String& paramName, const Record& value) {
00219         setMethodParam(QString(paramName.c_str()), value); }
00220     void setMethodParam(const QString& paramName, const Record& value);
00221     // </group>
00222     
00223     // Gets/Sets all method parameter values as a Record.
00224     // <group>
00225     Record methodParams() const;
00226     void setMethodParams(const Record& parameters);
00227     // </group>
00228     
00229     // Returns whether or not a returned value was set.
00230     bool returnedSet() const { return !qreturnedType().isEmpty(); }
00231     
00232     // Returns the type of the returned value, or empty string for none.
00233     // <group>
00234     String returnedType() const { return qreturnedType().toStdString(); }
00235     QString qreturnedType() const;
00236     // </group>
00237     
00238     // Returns whether the returned value is the specified type or not.
00239     // <group>
00240     bool returnedIsBool() const;
00241     bool returnedIsInt() const;
00242     bool returnedIsUInt() const;
00243     bool returnedIsDouble() const;
00244     bool returnedIsString() const;
00245     bool returnedIsRecord() const;
00246     // </group>
00247     
00248     // Returns the returned value as the specified type.  Is invalid if that
00249     // parameter is not of the requested type.  Note: the value can always be
00250     // returned as a string representation.
00251     // <group>
00252     bool returnedBool() const;
00253     int returnedInt() const;
00254     uInt returnedUInt() const;
00255     double returnedDouble() const;
00256     String returnedString() const { return returnedQString().toStdString(); }
00257     QString returnedQString() const;
00258     Record returnedRecord() const;
00259     // </group>
00260     
00261     // Sets the returned value to the given value (and associated type).
00262     // <group>
00263     void setReturnedValue(bool value);
00264     void setReturnedValue(int value);
00265     void setReturnedValue(uInt value);
00266     void setReturnedValue(double value);
00267     void setReturnedValue(const String& value) {
00268         setReturnedValue(QString(value.c_str())); }
00269     void setReturnedValue(const QString& value);
00270     void setReturnedValue(const Record& value);
00271     // </group>
00272     
00273     // Gets/Sets the returned value as a record.  ONLY the first field is used.
00274     // <group>
00275     Record returnedValue() const;
00276     void setReturnedValueRec(const Record& retValue);
00277     // </group>
00278     
00279     
00280     // Returns the whole XML as a string.
00281     // <group>
00282     String toXMLString() const { return toXMLQString().toStdString(); }
00283     QString toXMLQString() const;
00284     // </group>
00285     
00286     // Sets the whole XML as a string, and returns whether the operation
00288     // <group>
00289     bool fromXMLString(const String& value) {
00290         return fromXMLString(QString(value.c_str())); }
00291     bool fromXMLString(const QString& value);
00292     // </group>
00293     
00294     // Returns the underlying QDomDocument.
00295     // <group>
00296     QDomDocument& domDocument();
00297     const QDomDocument& domDocument() const;
00298     // </group>
00299     
00300     
00301     // Copy operator.
00302     QtDBusXML& operator=(const QtDBusXML& copy);
00303     
00304 private:
00305     // XML document.
00306     QDomDocument itsXML_;
00307     
00308     
00309     // Initialize object; meant to be called from constructor.
00310     void initialize();
00311     
00312     // Helper method for elemChildText().
00313     QString elemChildText(const QString& name) const {
00314         return elemChildText(itsXML_, name, false); }
00315     
00316     // Helper method for setElemChildText().
00317     void setElemChildText(const QString& name, const QString& value) {
00318         setElemChildText(itsXML_, name, value, true); }
00319     
00320     // Helper method that returns the element for the method parameter with the
00321     // given name, or a null element if it is not.  See elemChild().
00322     QDomElement methodParam(const QString& paramName,
00323             bool createIfAbsent = false) const;
00324     
00325     // Helper method for setting the method parameter values.
00326     void setMethodParam(const QString& name, const QString& type,
00327             const QString& value);
00328     
00329     // Helper method for setting the returned value.
00330     void setReturnedValue(const QString& type, const QString& value);
00331     
00332     
00333     // Static //
00334     
00335     // Converts between QStrings and bools.
00336     // <group>
00337     static bool qstringToBool(const QString& value);
00338     static QString qstringFromBool(bool value);
00339     // </group>
00340     
00341     // Returns the child of the given element with the given tag name.  If
00342     // createIfAbsent is true, then the element will be created and appended if
00343     // it is not present; otherwise, the returned element will be null if not
00344     // present.  If the given element is null, a null element is returned.
00345     // <group>
00346     static QDomElement elemChild(QDomDocument doc, const QString& name,
00347             bool createIfAbsent = false) {
00348         return elemChild(doc.documentElement(), name, createIfAbsent); }
00349     static QDomElement elemChild(QDomElement elem, const QString& name,
00350             bool createIfAbsent = false);
00351     // </group>
00352     
00353     // Returns the text value of the child of the given element with the given
00354     // tag name.  See elemChild().
00355     // <group>
00356     static QString elemChildText(QDomDocument doc, const QString& name,
00357             bool createIfAbsent = false) {
00358         return elemChildText(doc.documentElement(), name, createIfAbsent); }
00359     static QString elemChildText(QDomElement elem, const QString& name,
00360             bool createIfAbsent = false) {
00361         return elemChild(elem, name, createIfAbsent).text();
00362     }
00363     // </group>
00364     
00365     // Sets the text value of the child of the given element with the given tag
00366     // name to the given value.  See elemChild().
00367     // <group>
00368     static void setElemChildText(QDomDocument doc, const QString& name,
00369             const QString& value, bool createIfAbsent = false) {
00370         setElemChildText(doc.documentElement(), name, value, createIfAbsent); }
00371     static void setElemChildText(QDomElement elem, const QString& name,
00372             const QString& value, bool createIfAbsent = false) {
00373         setElemText(elemChild(elem, name, createIfAbsent), value); }
00374     // </group>
00375     
00376     // Sets the text value of the given element (if it is not null) to the
00377     // given text.
00378     static void setElemText(QDomElement elem, const QString& text);
00379     
00380     // Converts between a QDomElement and Record for values.
00381     // <group>
00382     static Record elemToRecord(QDomElement value);
00383     static void elemToRecord(Record& rec, QDomElement value);
00384     static void elemFromRecord(QDomElement elem, const Record& value);
00385     // </group>
00386 };
00387 
00388 }
00389 
00390 #endif /* QTDBUSXML_H_ */