|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU Lesser General Public License as published by |
|
7 * the Free Software Foundation, version 2.1 of the License. |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU Lesser General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU Lesser General Public License |
|
15 * along with this program. If not, |
|
16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". |
|
17 * |
|
18 */ |
|
19 #include <QXmlStreamReader> |
|
20 #include <QIODevice> |
|
21 #include <QList> |
|
22 |
|
23 #include "xbelreader.h" |
|
24 #include "BookmarksManager.h" |
|
25 |
|
26 XbelReader::XbelReader(BookmarksManager *bmgr) : |
|
27 m_bmgr(bmgr), m_xml(new QXmlStreamReader) |
|
28 { |
|
29 } |
|
30 |
|
31 XbelReader::~XbelReader() { |
|
32 if(m_xml) delete m_xml; |
|
33 } |
|
34 |
|
35 bool XbelReader::read(QIODevice *device) |
|
36 { |
|
37 if(!device) { |
|
38 m_xml->raiseError(QObject::tr("Invalid Device passed into XBEL Reader.")); |
|
39 } |
|
40 if(!m_bmgr) { |
|
41 m_xml->raiseError(QObject::tr("Invalid BookmarkManager passed into XBEL Reader.")); |
|
42 } else { |
|
43 m_xml->setDevice(device); |
|
44 if(m_xml->readNextStartElement()) { |
|
45 if(m_xml->name() == "xbel" && |
|
46 m_xml->attributes().value("version") == "1.0") |
|
47 readXBEL(); |
|
48 else |
|
49 m_xml->raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); |
|
50 } else |
|
51 m_xml->raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); |
|
52 } |
|
53 |
|
54 return !m_xml->error(); |
|
55 } |
|
56 |
|
57 /** |
|
58 * This function should be called before reading any xml elements |
|
59 * It attempts to validate that the file being read is actually an |
|
60 * xbel file. |
|
61 * @return whether the file is an XBEL file. |
|
62 */ |
|
63 bool XbelReader::isValidXbel() |
|
64 { |
|
65 // The xbel element must exist and must be version 1.0 |
|
66 return true; |
|
67 } |
|
68 |
|
69 QString XbelReader::errorString() const |
|
70 { |
|
71 return QObject::tr("%1\nLine %2, column %3") |
|
72 .arg(m_xml->errorString()) |
|
73 .arg(m_xml->lineNumber()) |
|
74 .arg(m_xml->columnNumber()); |
|
75 } |
|
76 |
|
77 void XbelReader::readXBEL() |
|
78 { |
|
79 QString folder = ""; |
|
80 QList<QString> folders; |
|
81 while (m_xml->readNextStartElement()) { |
|
82 if (m_xml->name() == "folder") |
|
83 readFolder(folders); |
|
84 else if (m_xml->name() == "bookmark") |
|
85 readBookmark(folders); |
|
86 else |
|
87 m_xml->skipCurrentElement(); |
|
88 } |
|
89 } |
|
90 |
|
91 QString XbelReader::readFolder(QList<QString>& parentFolders) |
|
92 { |
|
93 QString folderName = ""; |
|
94 |
|
95 while (m_xml->readNextStartElement()) { |
|
96 if (m_xml->name() == "title") |
|
97 folderName = m_xml->readElementText(); |
|
98 else if (m_xml->name() == "folder") { |
|
99 QList<QString> folders; |
|
100 folders = folders + parentFolders; |
|
101 if(!folderName.isEmpty()) |
|
102 folders.append(folderName); |
|
103 readFolder(folders); |
|
104 } else if (m_xml->name() == "bookmark") { |
|
105 QList<QString> folders; |
|
106 folders = folders + parentFolders; |
|
107 if(!folderName.isEmpty()) |
|
108 folders.append(folderName); |
|
109 readBookmark(folders); |
|
110 } else |
|
111 m_xml->skipCurrentElement(); |
|
112 } |
|
113 return folderName; |
|
114 } |
|
115 |
|
116 void XbelReader::readBookmark(QList<QString>& parentFolders) |
|
117 { |
|
118 QXmlStreamAttributes attrs = m_xml->attributes(); |
|
119 |
|
120 // if there is no URL attribute skip this bookmark. |
|
121 if(!attrs.hasAttribute("href")) { |
|
122 m_xml->skipCurrentElement(); |
|
123 return; |
|
124 } |
|
125 |
|
126 QString url = attrs.value("href").toString(); |
|
127 QString title = "Untitled"; |
|
128 QString desc = ""; |
|
129 QList<QString> tags; |
|
130 tags = tags + parentFolders; |
|
131 |
|
132 while (m_xml->readNextStartElement()) { |
|
133 if (m_xml->name() == "title") |
|
134 title = m_xml->readElementText(); |
|
135 else if(m_xml->name() == "desc") |
|
136 desc = m_xml->readElementText(); |
|
137 else if(m_xml->name() == "info") |
|
138 readInfo(tags); |
|
139 else |
|
140 m_xml->skipCurrentElement(); |
|
141 } |
|
142 |
|
143 int bmID = m_bmgr->addBookmark(title, url); |
|
144 if (bmID > 0) { |
|
145 QList<QString>::iterator iter; |
|
146 for (iter = tags.begin(); iter != tags.end(); ++iter) |
|
147 m_bmgr->addTag(bmID, *iter); |
|
148 } |
|
149 } |
|
150 |
|
151 /** |
|
152 * Reads the info element. |
|
153 * @param tags - A reference to a list of string tags |
|
154 */ |
|
155 void XbelReader::readInfo(QList<QString>& tags) |
|
156 { |
|
157 QString owner = "http://www.nokia.com"; |
|
158 while(m_xml->readNextStartElement()) { |
|
159 if(m_xml->name() == "metadata") |
|
160 readMetadata(tags, owner); |
|
161 else |
|
162 m_xml->skipCurrentElement(); |
|
163 } |
|
164 } |
|
165 |
|
166 /** |
|
167 * This function reads the metadata XBEL tag. |
|
168 * @param tags - A reference to a list of strings. This is passed into |
|
169 * readTags. |
|
170 * @param owner - A reference to the owner string. This is to allow for |
|
171 * future support for this attribute. |
|
172 */ |
|
173 void XbelReader::readMetadata(QList<QString>& tags, QString &owner) |
|
174 { |
|
175 if(m_xml->attributes().hasAttribute("owner")) |
|
176 owner = m_xml->attributes().value("owner").toString(); |
|
177 while(m_xml->readNextStartElement()) { |
|
178 if(m_xml->name() == "tags") |
|
179 readTags(tags); |
|
180 else |
|
181 m_xml->skipCurrentElement(); |
|
182 } |
|
183 |
|
184 } |
|
185 |
|
186 /** |
|
187 * Reads the tags and tag attributes, adding all tags found to |
|
188 * the list of string tags passed into the function. |
|
189 * @param tags - Reference to a list of string tags. |
|
190 */ |
|
191 void XbelReader::readTags(QList<QString>& tags) |
|
192 { |
|
193 while(m_xml->readNextStartElement()) { |
|
194 if(m_xml->name() == "tag") |
|
195 tags.append(m_xml->readElementText()); |
|
196 else |
|
197 m_xml->skipCurrentElement(); |
|
198 } |
|
199 |
|
200 } |
|
201 |