casa
$Rev:20696$
|
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_ */