~ubuntu-branches/ubuntu/jaunty/psi/jaunty

« back to all changes in this revision

Viewing changes to src/capsregistry.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-08-28 18:46:52 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080828184652-iiik12dl91nq7cdi
Tags: 0.12-2
Uploading to unstable (Closes: Bug#494352)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * capsregistry.cpp
3
 
 * Copyright (C) 2006  Remko Troncon
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License
7
 
 * as published by the Free Software Foundation; either version 2
8
 
 * of the License, or (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this library; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 *
19
 
 */
20
 
 
21
 
#include <QApplication>
22
 
#include <QDebug>
23
 
#include <QTextCodec>
24
 
#include <QFile>
25
 
#include <QDomElement>
26
 
 
27
 
#include "xmpp_features.h"
28
 
#include "capsregistry.h"
29
 
 
30
 
using namespace XMPP;
31
 
 
32
 
// -----------------------------------------------------------------------------
33
 
 
34
 
CapsRegistry::CapsInfo::CapsInfo()
35
 
{
36
 
        updateLastSeen();
37
 
}
38
 
 
39
 
const XMPP::Features& CapsRegistry::CapsInfo::features() const
40
 
{
41
 
        return features_;
42
 
}
43
 
 
44
 
const DiscoItem::Identities& CapsRegistry::CapsInfo::identities() const
45
 
{
46
 
        return identities_;
47
 
}
48
 
 
49
 
void CapsRegistry::CapsInfo::setIdentities(const DiscoItem::Identities& i)
50
 
{
51
 
        identities_ = i;
52
 
}
53
 
 
54
 
void CapsRegistry::CapsInfo::setFeatures(const XMPP::Features& f)
55
 
{
56
 
        features_ = f;
57
 
}
58
 
        
59
 
void CapsRegistry::CapsInfo::updateLastSeen()
60
 
{
61
 
        lastSeen_ = QDateTime::currentDateTime();
62
 
}
63
 
 
64
 
QDomElement CapsRegistry::CapsInfo::toXml(QDomDocument *doc) const
65
 
{
66
 
        QDomElement info = doc->createElement("info");
67
 
        info.setAttribute("last-seen",lastSeen_.toString(Qt::ISODate));
68
 
 
69
 
        // Identities
70
 
        for (DiscoItem::Identities::ConstIterator i = identities_.begin(); i != identities_.end(); ++i) {
71
 
                QDomElement identity = doc->createElement("identity");
72
 
                identity.setAttribute("category",(*i).category);
73
 
                identity.setAttribute("name",(*i).name);
74
 
                identity.setAttribute("type",(*i).type);
75
 
                info.appendChild(identity);
76
 
        }
77
 
 
78
 
        // Features
79
 
        foreach(QString f, features_.list()) {
80
 
                QDomElement feature = doc->createElement("feature");
81
 
                feature.setAttribute("node",f);
82
 
                info.appendChild(feature);
83
 
        }
84
 
 
85
 
        return info;
86
 
}
87
 
 
88
 
void CapsRegistry::CapsInfo::fromXml(const QDomElement& e)
89
 
{
90
 
        if (e.tagName() != "info") {
91
 
                qWarning("caps.cpp: Invalid info element");
92
 
                return;
93
 
        }
94
 
        
95
 
        if (!e.attribute("last-seen").isEmpty()) {
96
 
                QDateTime last = QDateTime::fromString(e.attribute("last-seen"),Qt::ISODate);
97
 
                if (last.isValid())
98
 
                        lastSeen_ = last;
99
 
                else
100
 
                        qWarning("Invalid date in caps registry");
101
 
        }
102
 
 
103
 
        for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
104
 
                QDomElement i = n.toElement();
105
 
                if(i.isNull()) {
106
 
                        qWarning("caps.cpp: Null element");
107
 
                        continue;
108
 
                }
109
 
 
110
 
                if(i.tagName() == "identity") {
111
 
                        DiscoItem::Identity id;
112
 
                        id.category = i.attribute("category");
113
 
                        id.name = i.attribute("name");
114
 
                        id.type = i.attribute("type");
115
 
                        identities_ += id;
116
 
                }
117
 
                else if (i.tagName() == "feature") {
118
 
                        features_.addFeature(i.attribute("node"));
119
 
                }
120
 
                else {
121
 
                        qWarning("caps.cpp: Unknown element");
122
 
                }
123
 
        }
124
 
}
125
 
 
126
 
// -----------------------------------------------------------------------------
127
 
/**
128
 
 * \class CapsRegistry
129
 
 * \brief A singleton class managing the capabilities of clients.
130
 
 */
131
 
 
132
 
/**
133
 
 * \brief Default constructor.
134
 
 */
135
 
CapsRegistry::CapsRegistry() : QObject(qApp)
136
 
{
137
 
        connect(QCoreApplication::instance(),SIGNAL(aboutToQuit()),SLOT(save()));
138
 
}
139
 
 
140
 
/**
141
 
 * \brief Destructor. Saves data before exiting.
142
 
 */
143
 
CapsRegistry::~CapsRegistry()
144
 
{
145
 
        save();
146
 
}
147
 
 
148
 
 
149
 
/**
150
 
 * \brief Convert all capabilities info to XML.
151
 
 */
152
 
void CapsRegistry::save()
153
 
{
154
 
        //qDebug() << QString("Saving caps to '%1'").arg(fileName_);
155
 
        
156
 
        if (fileName_.isEmpty())
157
 
                return;
158
 
 
159
 
        // Generate XML
160
 
        QDomDocument doc;
161
 
        QDomElement capabilities = doc.createElement("capabilities");
162
 
        doc.appendChild(capabilities);
163
 
        QMap<CapsSpec,CapsInfo>::ConstIterator i = capsInfo_.begin();
164
 
        for( ; i != capsInfo_.end(); i++) {
165
 
                QDomElement info = i.value().toXml(&doc);
166
 
                info.setAttribute("node",i.key().node());
167
 
                info.setAttribute("ver",i.key().version());
168
 
                info.setAttribute("ext",i.key().extensions());
169
 
                capabilities.appendChild(info);
170
 
        }
171
 
 
172
 
        // Save
173
 
        QFile f(fileName_);
174
 
        if(!f.open(QIODevice::WriteOnly)) {
175
 
                qWarning("caps.cpp: Unable to open caps file");
176
 
                return;
177
 
        }
178
 
        QTextStream t;
179
 
        t.setDevice(&f);
180
 
        t.setCodec(QTextCodec::codecForName("UTF-8"));
181
 
        t << doc.toString();
182
 
        f.close();
183
 
}
184
 
 
185
 
/**
186
 
 * \brief Sets the file to save the capabilities info to
187
 
 */
188
 
void CapsRegistry::setFile(const QString& fileName)
189
 
{
190
 
        fileName_ = fileName;
191
 
        
192
 
        // Load settings
193
 
        //qDebug() << "Loading " << fileName;
194
 
        QDomDocument doc;
195
 
        QFile f(fileName_);
196
 
        if (!f.open(QIODevice::ReadOnly))
197
 
                return;
198
 
        if (!doc.setContent(&f))
199
 
                return;
200
 
        f.close();
201
 
 
202
 
        QDomElement caps = doc.documentElement();
203
 
        if (caps.tagName() != "capabilities") {
204
 
                qWarning("caps.cpp: Invalid capabilities element");
205
 
                return;
206
 
        }
207
 
                
208
 
        for(QDomNode n = caps.firstChild(); !n.isNull(); n = n.nextSibling()) {
209
 
                QDomElement i = n.toElement();
210
 
                if(i.isNull()) {
211
 
                        qWarning("capsregistry.cpp: Null element");
212
 
                        continue;
213
 
                }
214
 
 
215
 
                if(i.tagName() == "info") {
216
 
                        CapsInfo info;
217
 
                        info.fromXml(i);
218
 
                        CapsSpec spec(i.attribute("node"),i.attribute("ver"),i.attribute("ext"));
219
 
                        capsInfo_[spec] = info;
220
 
                        //qDebug() << QString("Read %1 %2 %3").arg(spec.node()).arg(spec.version()).arg(spec.extensions());
221
 
                }
222
 
                else {
223
 
                        qWarning("capsregistry.cpp: Unknown element");
224
 
                }
225
 
        }
226
 
}
227
 
 
228
 
/**
229
 
 * \brief Registers capabilities of a client.
230
 
 */
231
 
void CapsRegistry::registerCaps(const CapsSpec& spec,const XMPP::DiscoItem::Identities& identities,const XMPP::Features& features)
232
 
{
233
 
        if (!isRegistered(spec)) {
234
 
                CapsInfo info;
235
 
                info.setIdentities(identities);
236
 
                info.setFeatures(features);
237
 
                capsInfo_[spec] = info;
238
 
                save();
239
 
                emit registered(spec);
240
 
        }
241
 
}
242
 
 
243
 
/**
244
 
 * \brief Checks if capabilities have been registered.
245
 
 */
246
 
bool CapsRegistry::isRegistered(const CapsSpec& spec) const
247
 
{
248
 
        return capsInfo_.contains(spec);
249
 
}
250
 
 
251
 
 
252
 
/**
253
 
 * \brief Retrieves the features of a given caps spec.
254
 
 */
255
 
XMPP::Features CapsRegistry::features(const CapsSpec& spec) const
256
 
{
257
 
        return capsInfo_[spec].features();
258
 
}
259
 
 
260
 
/**
261
 
 * \brief Retrieves the identities of a given caps spec.
262
 
 */
263
 
XMPP::DiscoItem::Identities CapsRegistry::identities(const CapsSpec& spec) const
264
 
{
265
 
        return capsInfo_[spec].identities();
266
 
}
267
 
 
268
 
/**
269
 
 * \brief Retrieves the instance of the CapsRegistry.
270
 
 * If no instance existed, a new one is created.
271
 
 */
272
 
CapsRegistry* CapsRegistry::instance()
273
 
{
274
 
        if (!instance_) {
275
 
                instance_ = new CapsRegistry();
276
 
        }
277
 
        return instance_;
278
 
}
279
 
 
280
 
/**
281
 
 * \brief The instance of the CapsRegistry.
282
 
 */
283
 
CapsRegistry* CapsRegistry::instance_ = NULL;
284