1/*
2 This file is part of libkabc.
3 Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
4 Copyright (c) 2008 Kevin Krammer <kevin.krammer@gmx.at>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "contactgrouptool.h"
23#include "contactgroup.h"
24
25#include <QtCore/QIODevice>
26#include <QtCore/QString>
27#include <QtCore/QDebug>
28
29#include <QtCore/QXmlStreamReader>
30#include <QtCore/QXmlStreamWriter>
31
32using namespace KABC;
33
34class XmlContactGroupWriter : public QXmlStreamWriter
35{
36 public:
37 XmlContactGroupWriter();
38
39 void write( const ContactGroup &group, QIODevice *device );
40 void write( const QList<ContactGroup> &groupLis, QIODevice *device );
41
42 private:
43 void writeGroup( const ContactGroup &group );
44 void writeContactReference( const ContactGroup::ContactReference & );
45 void writeContactGroupReference( const ContactGroup::ContactGroupReference & );
46 void writeData( const ContactGroup::Data & );
47};
48
49XmlContactGroupWriter::XmlContactGroupWriter()
50{
51 setAutoFormatting( true );
52}
53
54void XmlContactGroupWriter::write( const ContactGroup &group, QIODevice *device )
55{
56 setDevice( device );
57
58 writeStartDocument();
59
60 writeGroup( group );
61
62 writeEndDocument();
63}
64
65void XmlContactGroupWriter::write( const QList<ContactGroup> &groupList, QIODevice *device )
66{
67 setDevice( device );
68
69 writeStartDocument();
70
71 writeStartElement( QLatin1String( "contactGroupList" ) );
72
73 foreach ( const ContactGroup & group, groupList ) {
74 writeGroup( group );
75 }
76
77 writeEndElement();
78
79 writeEndDocument();
80}
81
82void XmlContactGroupWriter::writeGroup( const ContactGroup &group )
83{
84 writeStartElement( QLatin1String( "contactGroup" ) );
85 writeAttribute( QLatin1String( "uid" ), group.id() );
86 writeAttribute( QLatin1String( "name" ), group.name() );
87
88 for ( uint i = 0; i < group.contactReferenceCount(); ++i ) {
89 writeContactReference( group.contactReference( i ) );
90 }
91
92 for ( uint i = 0; i < group.contactGroupReferenceCount(); ++i ) {
93 writeContactGroupReference( group.contactGroupReference( i ) );
94 }
95
96 for ( uint i = 0; i < group.dataCount(); ++i ) {
97 writeData( group.data( i ) );
98 }
99
100 writeEndElement();
101}
102
103void XmlContactGroupWriter::writeContactReference( const ContactGroup::ContactReference &reference )
104{
105 writeStartElement( QLatin1String( "contactReference" ) );
106 writeAttribute( QLatin1String( "uid" ), reference.uid() );
107 writeAttribute( QLatin1String( "gid" ), reference.gid() );
108 if ( !reference.preferredEmail().isEmpty() ) {
109 writeAttribute( QLatin1String( "preferredEmail" ), reference.preferredEmail() );
110 }
111
112 // TODO: customs
113
114 writeEndElement();
115}
116
117void XmlContactGroupWriter::writeContactGroupReference(
118 const ContactGroup::ContactGroupReference &reference )
119{
120 writeStartElement( QLatin1String( "contactGroupReference" ) );
121 writeAttribute( QLatin1String( "uid" ), reference.uid() );
122
123 // TODO: customs
124
125 writeEndElement();
126}
127
128void XmlContactGroupWriter::writeData( const ContactGroup::Data &data )
129{
130 writeStartElement( QLatin1String( "contactData" ) );
131 writeAttribute( QLatin1String( "name" ), data.name() );
132 writeAttribute( QLatin1String( "email" ), data.email() );
133
134 // TODO: customs
135
136 writeEndElement();
137}
138
139class XmlContactGroupReader : public QXmlStreamReader
140{
141 public:
142 XmlContactGroupReader();
143
144 bool read( QIODevice *device, ContactGroup &group );
145 bool read( QIODevice *device, QList<ContactGroup> &groupList );
146
147 private:
148 bool readGroup( ContactGroup &group );
149 bool readContactReference( ContactGroup::ContactReference &reference );
150 bool readContactGroupReference( ContactGroup::ContactGroupReference &reference );
151 bool readData( ContactGroup::Data &data );
152};
153
154XmlContactGroupReader::XmlContactGroupReader()
155{
156}
157
158bool XmlContactGroupReader::read( QIODevice *device, ContactGroup &group )
159{
160 setDevice( device );
161
162 while ( !atEnd() ) {
163 readNext();
164 if ( isStartElement() ) {
165 if ( name() == QLatin1String( "contactGroup" ) ) {
166 return readGroup( group );
167 } else {
168 raiseError( QLatin1String( "The document does not describe a ContactGroup" ) );
169 }
170 }
171 }
172
173 return error() == NoError;
174}
175
176bool XmlContactGroupReader::read( QIODevice *device, QList<ContactGroup> &groupList )
177{
178 setDevice( device );
179
180 int depth = 0;
181
182 while ( !atEnd() ) {
183 readNext();
184 if ( isStartElement() ) {
185 ++depth;
186 if ( depth == 1 ) {
187 if ( name() == QLatin1String( "contactGroupList" ) ) {
188 continue;
189 } else {
190 raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) );
191 }
192 } else if ( depth == 2 ) {
193 if ( name() == QLatin1String( "contactGroup" ) ) {
194 ContactGroup group;
195 if ( !readGroup( group ) ) {
196 return false;
197 }
198
199 groupList.append( group );
200 } else {
201 raiseError( QLatin1String( "The document does not describe a list of ContactGroup" ) );
202 }
203 }
204 }
205
206 if ( isEndElement() ) {
207 --depth;
208 }
209 }
210
211 return error() == NoError;
212}
213
214bool XmlContactGroupReader::readGroup( ContactGroup &group )
215{
216 const QXmlStreamAttributes elementAttributes = attributes();
217 const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
218 if ( uid.isEmpty() ) {
219 raiseError( QLatin1String( "ContactGroup is missing a uid" ) );
220 return false;
221 }
222
223 const QStringRef groupName = elementAttributes.value( QLatin1String( "name" ) );
224 if ( groupName.isEmpty() ) {
225 raiseError( QLatin1String( "ContactGroup is missing a name" ) );
226 return false;
227 }
228
229 group.setId( uid.toString() );
230 group.setName( groupName.toString() );
231
232 while ( !atEnd() ) {
233 readNext();
234 if ( isStartElement() ) {
235 if ( name() == QLatin1String( "contactData" ) ) {
236 ContactGroup::Data data;
237 if ( !readData( data ) ) {
238 return false;
239 }
240 group.append( data );
241 } else if ( name() == QLatin1String( "contactReference" ) ) {
242 ContactGroup::ContactReference reference;
243 if ( !readContactReference( reference ) ) {
244 return false;
245 }
246 group.append( reference );
247 } else if ( name() == QLatin1String( "contactGroupReference" ) ) {
248 ContactGroup::ContactGroupReference reference;
249 if ( !readContactGroupReference( reference ) ) {
250 return false;
251 }
252 group.append( reference );
253 } else {
254 raiseError( QLatin1String( "The document does not describe a ContactGroup" ) );
255 }
256 }
257
258 if ( isEndElement() ) {
259 if ( name() == QLatin1String( "contactGroup" ) ) {
260 return true;
261 }
262 }
263 }
264
265 return false;
266}
267
268bool XmlContactGroupReader::readData( ContactGroup::Data &data )
269{
270 const QXmlStreamAttributes elementAttributes = attributes();
271 const QStringRef email = elementAttributes.value( QLatin1String( "email" ) );
272 if ( email.isEmpty() ) {
273 raiseError( QLatin1String( "ContactData is missing an email address" ) );
274 return false;
275 }
276
277 const QStringRef name = elementAttributes.value( QLatin1String( "name" ) );
278
279 data.setName( name.toString() );
280 data.setEmail( email.toString() );
281
282 return true;
283}
284
285bool XmlContactGroupReader::readContactReference( ContactGroup::ContactReference &reference )
286{
287 const QXmlStreamAttributes elementAttributes = attributes();
288 const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
289 const QStringRef gid = elementAttributes.value( QLatin1String( "gid" ) );
290 if ( uid.isEmpty() && gid.isEmpty() ) {
291 raiseError( QLatin1String( "ContactReference is missing both uid and gid" ) );
292 return false;
293 }
294 const QStringRef preferredEmail = elementAttributes.value( QLatin1String( "preferredEmail" ) );
295
296 reference.setUid( uid.toString() );
297 reference.setGid( gid.toString() );
298 reference.setPreferredEmail( preferredEmail.toString() );
299
300 return true;
301}
302
303bool XmlContactGroupReader::readContactGroupReference(
304 ContactGroup::ContactGroupReference &reference )
305{
306 const QXmlStreamAttributes elementAttributes = attributes();
307 const QStringRef uid = elementAttributes.value( QLatin1String( "uid" ) );
308 if ( uid.isEmpty() ) {
309 raiseError( QLatin1String( "ContactGroupReference is missing a uid" ) );
310 return false;
311 }
312
313 reference.setUid( uid.toString() );
314
315 return true;
316}
317
318bool ContactGroupTool::convertFromXml( QIODevice *device, ContactGroup &group,
319 QString *errorMessage )
320{
321 Q_UNUSED( errorMessage );
322
323 XmlContactGroupReader reader;
324
325 bool ok = reader.read( device, group );
326
327 if ( !ok && errorMessage != 0 ) {
328 *errorMessage = reader.errorString();
329 }
330
331 return ok;
332}
333
334bool ContactGroupTool::convertToXml( const ContactGroup &group, QIODevice *device,
335 QString *errorMessage )
336{
337 Q_UNUSED( errorMessage );
338
339 XmlContactGroupWriter writer;
340 writer.write( group, device );
341
342 return true;
343}
344
345bool ContactGroupTool::convertFromXml( QIODevice *device, QList<ContactGroup> &groupList,
346 QString *errorMessage )
347{
348 Q_UNUSED( errorMessage );
349
350 XmlContactGroupReader reader;
351
352 bool ok = reader.read( device, groupList );
353
354 if ( !ok && errorMessage != 0 ) {
355 *errorMessage = reader.errorString();
356 }
357
358 return ok;
359}
360
361bool ContactGroupTool::convertToXml( const QList<ContactGroup> &groupList,
362 QIODevice *device, QString *errorMessage )
363{
364 Q_UNUSED( errorMessage );
365
366 XmlContactGroupWriter writer;
367 writer.write( groupList, device );
368
369 return true;
370}
371