casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
QtDBusXmlApp.qo.h
Go to the documentation of this file.
00001 //# QtDBusXmlApp.qo.h: Abstract parent to use the CASA DBus server.
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 QTDBUSXMLAPP_QO_H_
00028 #define QTDBUSXMLAPP_QO_H_
00029 
00030 #include <casaqt/QtUtilities/QtDBusApp.h>
00031 #include <casaqt/QtUtilities/QtDBusXML.h>
00032 
00033 #include <QDBusAbstractAdaptor>
00034 #include <QDBusConnection>
00035 
00036 #include <casa/namespace.h>
00037 
00038 namespace casa {
00039 
00040 //# Forward Declarations.
00041 class QtDBusXmlAppAdaptor;
00042 
00043 
00044 // Abstract parent of classes that want to register themselves with CASA's
00045 // DBus server.  The class also provides public static methods for other code
00046 // to send DBus messages without needing to subclass and register.  This class
00047 // hides the details of how the DBus communication happens behind the scenes
00048 // and presents an interface using CASA objects like Records.  Applications
00049 // that want to use this DBus communication layer need to know about the
00050 // following for each method call:
00051 // * The object name.  Each object that registers with CASA's DBus server must
00052 //   do so with a unique name.  Outside objects then can send messages to that
00053 //   object by using its name.  Names have some restrictions; see
00054 //   dbusRegisterSelf().  You can check if a certain name is currently
00055 //   registered using dbusNameIsRegistered().
00056 // * The method name.  Each object keeps track of what methods it supports, and
00057 //   this process happens dynamically on a per-message basis.
00058 // * Whether to call asynchronously or not.  See dbusXmlCallNoRet().
00059 // * The method parameters.  The parameters are set using name/value pairs in a
00060 //   Record.  Like the method name, this is on a dynamic, per-object basis.
00061 //   IMPORTANT: not all types are currently supported; see QtDBusXML
00062 //   documentation to see what is currently implemented.
00063 // * The method return value.  IMPORTANT: not all types are currently
00064 //   supported; see QtDBusXML documentation to see what is currently
00065 //   implemented.
00066 //
00067 // If a class wants to receive DBus communications, it must take the following
00068 // steps:
00069 // 1) Subclass QtDBusXmlApp.
00070 // 2) Implement the dbusRunXmlMethod() method, which is called when a DBus method
00071 //    call is received.  For a discussion of the parameters to this method, see
00072 //    above.
00073 // 3) Call dbusRegisterSelf() with a unique name.
00074 //
00075 // Classes that wish to send but not receive messages do NOT need to subclass
00076 // QtDBusXmlApp and can just use the public static methods to call methods on
00077 // DBus-registered objects.  For a discussion of the parameters to these
00078 // static methods, see above.
00079 class QtDBusXmlApp : public QtDBusApp {
00080     
00081     //# Friend class declarations.
00082     friend class QtDBusXmlAppAdaptor;
00083 
00084 public:
00085     
00086     // Calls the given method on the object with the given name that is
00087     // registered with CASA's DBus server, using the given parameters.  The
00088     // given from name is sent to the remote object, but not used otherwise. If
00089     // isAsync is true, then the remote method runs asynchronously, which means
00090     // that control returns immediately after sending the message.  This method
00091     // does NOT give a return value, even if the remote method does.  Returns
00092     // true for success, false for failure.  Will fail if the given object
00093     // name is not registered with CASA's DBus server.
00094     static bool dbusXmlCallNoRet(const String& fromName,
00095             const String& objectName, const String& methodName,
00096             const Record& parameters, bool isAsync = false);
00097     
00098     // Like dbusXmlCallNoRet(), except that if the remote method has a
00099     // return value of the given type, then the value is set accordingly.  If
00100     // there is no return value or it is a different type, the value is not
00101     // set.  If retValueSet is given, it will be set to true if the return
00102     // value was set and false otherwise.
00103     // <group>
00104     static bool dbusXmlCall(const String& fromName,
00105             const String& objectName, const String& methodName,
00106             const Record& parameters, bool& retValue,
00107             bool* retValueSet = NULL);
00108     static bool dbusXmlCall(const String& fromName,
00109             const String& objectName, const String& methodName,
00110             const Record& parameters, int& retValue,
00111             bool* retValueSet = NULL);
00112     static bool dbusXmlCall(const String& fromName,
00113             const String& objectName, const String& methodName,
00114             const Record& parameters, uInt& retValue,
00115             bool* retValueSet = NULL);
00116     static bool dbusXmlCall(const String& fromName,
00117             const String& objectName, const String& methodName,
00118             const Record& parameters, double& retValue,
00119             bool* retValueSet = NULL);
00120     static bool dbusXmlCall(const String& fromName,
00121             const String& objectName, const String& methodName,
00122             const Record& parameters, String& retValue,
00123             bool* retValueSet = NULL);
00124     static bool dbusXmlCall(const String& fromName,
00125             const String& objectName, const String& methodName,
00126             const Record& parameters, Record& retValue,
00127             bool* retValueSet = NULL);
00128     // </group>
00129     
00130 protected:
00131     // Constructor.
00132     QtDBusXmlApp();
00133     
00134     // Destructor.  Unregisters from the CASA DBus server if needed.
00135     virtual ~QtDBusXmlApp();
00136     
00137     
00138     // ABSTRACT METHODS //
00139     
00140     // Runs the method with the specified name using the given parameters and
00141     // placing the return value, if any, into the given retValue record.  NOTE:
00142     // when defining the return value, the name doesn't matter because the
00143     // first entry is used.  The caller name, and whether this is an
00144     // asynchronous call or not, are also provided but do not need to be used.
00145     // Note, however, that asynchronous method calls will NOT use a return
00146     // value even if one is set.
00147     virtual void dbusRunXmlMethod(const String& methodName,
00148             const Record& parameters, Record& retValue,
00149             const String& callerName, bool isAsync) = 0;
00150     
00151     
00152     // VIRTUAL METHODS //
00153     
00154     // Method that can be overridden if the subclass wants to be informed
00155     // whenever ANY dbus message is received, even if this object is not the
00156     // intended recipient.  Note that most applications won't need to do this
00157     // (and probably shouldn't) since dbusRunXmlMethod() will be called with the
00158     // appropriate parameters if this object is the intended recipient.
00159     virtual void dbusXmlReceived(const QtDBusXML& xml) { (void)xml; }
00160     
00161     
00162     // IMPLEMENTED METHODS //
00163     
00164     // Registers this object with CASA's DBus server, if it is not already,
00165     // with the given name and returns whether or not the registration
00166     // succeeded.  If the name is blank, then the last set name is used, UNLESS
00167     // this is the first time registering in which case the registration will
00168     // fail.  The registration name MUST contain only numbers, letters, and
00169     // underscores, and MUST be unique for the DBus server; trying to register
00170     // with a name that is already in use will result in registration failure.
00171     // (Note, however, that the name needs ONLY to be unique within the CASA
00172     // DBus application names rather than all system-wide DBus application
00173     // names.)  Trying to register when already registered (see
00174     // dbusSelfIsRegistered()) will result in registration failure; to change
00175     // names, you must unregister and then reregister with the new name.
00176     bool dbusRegisterSelf(const String& name = "");
00177     
00178     // Unregisters this object with CASA's DBus server, if it is registered.
00179     void dbusUnregisterSelf();
00180     
00181     // Returns true if this object is currently registered with CASA's DBus
00182     // server, false otherwise.
00183     bool dbusSelfIsRegistered() const;
00184     
00185     // Returns the name that this object is registered with with CASA's DBus
00186     // server, or an empty String if this application is not currently
00187     // registered.
00188     String dbusSelfRegisteredName() const;
00189     
00190     // Calls the static version of the method with this application's name.
00191     // <group>
00192     bool dbusXmlCallNoRet(const String& objectName,
00193             const String& methodName, const Record& parameters,
00194             bool isAsync = false) {
00195         return dbusXmlCallNoRet(dbusSelfRegisteredName(), objectName,
00196                                    methodName, parameters, isAsync); }
00197     bool dbusXmlCall(const String& objectName, const String& methodName,
00198             const Record& parameters, bool& retValue,
00199             bool* retValueSet = NULL) {
00200         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00201                               parameters, retValue, retValueSet); }
00202     bool dbusXmlCall(const String& objectName, const String& methodName,
00203             const Record& parameters, int& retValue,
00204             bool* retValueSet = NULL) {
00205         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00206                               parameters, retValue, retValueSet); }
00207     bool dbusXmlCall(const String& objectName, const String& methodName,
00208             const Record& parameters, uInt& retValue,
00209             bool* retValueSet = NULL) {
00210         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00211                               parameters, retValue, retValueSet); }
00212     bool dbusXmlCall(const String& objectName, const String& methodName,
00213             const Record& parameters, double& retValue,
00214             bool* retValueSet = NULL) {
00215         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00216                               parameters, retValue, retValueSet); }
00217     bool dbusXmlCall(const String& objectName, const String& methodName,
00218             const Record& parameters, String& retValue,
00219             bool* retValueSet = NULL) {
00220         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00221                               parameters, retValue, retValueSet); }
00222     bool dbusXmlCall(const String& objectName, const String& methodName,
00223             const Record& parameters, Record& retValue,
00224             bool* retValueSet = NULL) {
00225         return dbusXmlCall(dbusSelfRegisteredName(), objectName, methodName,
00226                               parameters, retValue, retValueSet); }
00227     // </group>
00228     
00229 private:
00230     
00231     // Flag for whether the application is currently registered or not.
00232     bool dbusRegistered_;
00233     
00234     // Name that the application is registered with.
00235     QString dbusName_;
00236     
00237     // DBus adaptor.
00238     QtDBusXmlAppAdaptor* dbusAdaptor_;
00239 
00240     
00241     // Method for when one of the slots in the adaptor is activated.  First
00242     // sends to dbusXmlReceived(), then to dbusRunXmlMethod().
00243     void dbusSlot(QtDBusXML& xml);
00244     
00245     
00246     // Private Static Methods //
00247     
00248     // Helper method for calling remote methods.
00249     static bool dbusXmlCall(const String& from, const String& to,
00250             const String& methodName, bool methodIsAsync,
00251             const Record& parameters, Record* retValue);
00252 };
00253 
00254 
00255 // Subclass of QDBusAbstractAdaptor for use with CASA's QtDBusXmlApp class.  This
00256 // class is a very thin layer on top of QtDBusXmlApp.
00257 class QtDBusXmlAppAdaptor : public QDBusAbstractAdaptor {
00258      Q_OBJECT
00259     
00260     // Interface name definition.
00261     // <group>
00262     #define CASA_DBUS_XML_INTERFACE "edu.nrao.casa.QtDBusXmlApp"
00263     Q_CLASSINFO("D-Bus Interface", "edu.nrao.casa.QtDBusXmlApp")
00264     // </group>
00265     
00266     //# Friend class declarations.
00267     friend class QtDBusXmlApp;
00268     
00269 public slots:
00270     // Slot for receiving messages.  If its name is changed,
00271     // QtDBusXmlApp::DBUS_MESSAGE_SLOT must be updated.
00272     QString xmlSlot(const QString& xml);
00273     
00274 private:
00275     // Constructor which takes the application.
00276     QtDBusXmlAppAdaptor(QtDBusXmlApp& app);
00277     
00278     // Destructor.
00279     ~QtDBusXmlAppAdaptor();
00280     
00281     
00282     // Application.
00283     QtDBusXmlApp& itsApp_;
00284     
00285     // Dummy object.
00286     QObject* itsObject_;
00287 };
00288 
00289 }
00290 
00291 #endif /* QTDBUSAPP_QO_H_ */