1 /** 2 * This file is part of TelepathyQt 3 * 4 * @copyright Copyright (C) 2008-2009 Collabora Ltd. <http://www.collabora.co.uk/> 5 * @copyright Copyright (C) 2008-2009 Nokia Corporation 6 * @license LGPL 2.1 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #ifndef _TelepathyQt_optional_interface_factory_h_HEADER_GUARD_ 24 #define _TelepathyQt_optional_interface_factory_h_HEADER_GUARD_ 25 26 #ifndef IN_TP_QT_HEADER 27 #error IN_TP_QT_HEADER 28 #endif 29 30 #include <TelepathyQt/Global> 31 32 #include <QObject> 33 #include <QStringList> 34 #include <QtGlobal> 35 36 namespace Tp 37 { 38 39 class AbstractInterface; 40 41 #ifndef DOXYGEN_SHOULD_SKIP_THIS 42 43 class TP_QT_EXPORT OptionalInterfaceCache 44 { 45 Q_DISABLE_COPY(OptionalInterfaceCache) 46 47 public: 48 explicit OptionalInterfaceCache(QObject *proxy); 49 50 ~OptionalInterfaceCache(); 51 52 protected: 53 AbstractInterface *getCached(const QString &name) const; 54 void cache(AbstractInterface *interface) const; 55 QObject *proxy() const; 56 57 private: 58 struct Private; 59 friend struct Private; 60 Private *mPriv; 61 }; 62 63 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 64 65 template <typename DBusProxySubclass> class OptionalInterfaceFactory 66 #ifndef DOXYGEN_SHOULD_SKIP_THIS 67 : private OptionalInterfaceCache 68 #endif 69 { 70 Q_DISABLE_COPY(OptionalInterfaceFactory) 71 72 public: 73 enum InterfaceSupportedChecking 74 { 75 CheckInterfaceSupported, 76 BypassInterfaceCheck 77 }; 78 OptionalInterfaceFactory(DBusProxySubclass * this_)79 inline OptionalInterfaceFactory(DBusProxySubclass *this_) 80 : OptionalInterfaceCache(this_) 81 { 82 } 83 ~OptionalInterfaceFactory()84 inline ~OptionalInterfaceFactory() 85 { 86 } 87 interfaces()88 inline QStringList interfaces() const { return mInterfaces; } 89 hasInterface(const QString & name)90 inline bool hasInterface(const QString &name) const 91 { 92 return mInterfaces.contains(name); 93 } 94 95 template <class Interface> 96 inline Interface *optionalInterface( 97 InterfaceSupportedChecking check = CheckInterfaceSupported) const 98 { 99 // Check for the remote object supporting the interface 100 // Note that extra whitespace on "name" declaration is significant to avoid 101 // vexing-parse 102 QString name( (QLatin1String(Interface::staticInterfaceName())) ); 103 if (check == CheckInterfaceSupported && !mInterfaces.contains(name)) { 104 return 0; 105 } 106 107 // If present or forced, delegate to OptionalInterfaceFactory 108 return interface<Interface>(); 109 } 110 111 template <typename Interface> interface()112 inline Interface *interface() const 113 { 114 AbstractInterface* interfaceMustBeASubclassOfAbstractInterface = static_cast<Interface *>(NULL); 115 Q_UNUSED(interfaceMustBeASubclassOfAbstractInterface); 116 117 // If there is a interface cached already, return it 118 // Note that extra whitespace on "name" declaration is significant to avoid 119 // vexing-parse 120 QString name( (QLatin1String(Interface::staticInterfaceName())) ); 121 AbstractInterface *cached = getCached(name); 122 if (cached) 123 return static_cast<Interface *>(cached); 124 125 // Otherwise, cache and return a newly constructed proxy 126 Interface *interface = new Interface( 127 static_cast<DBusProxySubclass *>(proxy())); 128 cache(interface); 129 return interface; 130 } 131 132 protected: setInterfaces(const QStringList & interfaces)133 inline void setInterfaces(const QStringList &interfaces) 134 { 135 mInterfaces = interfaces; 136 } 137 138 private: 139 QStringList mInterfaces; 140 }; 141 142 } // Tp 143 144 #endif 145