OSDN Git Service

Save non-standard metadata to note attribute.sourceApplication for DB restores.
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / xml / ExportData.java
1 /*\r
2  * This file is part of NixNote \r
3  * Copyright 2009 Randy Baumgarte\r
4  * \r
5  * This file may be licensed under the terms of of the\r
6  * GNU General Public License Version 2 (the ``GPL'').\r
7  *\r
8  * Software distributed under the License is distributed\r
9  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
10  * express or implied. See the GPL for the specific language\r
11  * governing rights and limitations.\r
12  *\r
13  * You should have received a copy of the GPL along with this\r
14  * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
15  * or write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
17  *\r
18 */\r
19 \r
20 package cx.fbn.nevernote.xml;\r
21 \r
22 import java.util.ArrayList;\r
23 import java.util.HashMap;\r
24 import java.util.List;\r
25 \r
26 import com.evernote.edam.type.Data;\r
27 import com.evernote.edam.type.LinkedNotebook;\r
28 import com.evernote.edam.type.Note;\r
29 import com.evernote.edam.type.NoteAttributes;\r
30 import com.evernote.edam.type.Notebook;\r
31 import com.evernote.edam.type.Publishing;\r
32 import com.evernote.edam.type.Resource;\r
33 import com.evernote.edam.type.SavedSearch;\r
34 import com.evernote.edam.type.SharedNotebook;\r
35 import com.evernote.edam.type.Tag;\r
36 import com.trolltech.qt.core.QByteArray;\r
37 import com.trolltech.qt.core.QFile;\r
38 import com.trolltech.qt.core.QIODevice;\r
39 import com.trolltech.qt.xml.QXmlStreamWriter;\r
40 \r
41 import cx.fbn.nevernote.Global;\r
42 import cx.fbn.nevernote.evernote.NoteMetadata;\r
43 import cx.fbn.nevernote.sql.DatabaseConnection;\r
44 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
45 \r
46 public class ExportData {\r
47         \r
48         private List<Notebook>                                          notebooks;\r
49         private final HashMap<String,String>            localNotebooks;\r
50         private final HashMap<String,String>            dirtyNotebooks;\r
51         private final ApplicationLogger                         logger;\r
52         \r
53         private List<SavedSearch>                                       searches;\r
54         private List<LinkedNotebook>                            linkedNotebooks;\r
55         private List<SharedNotebook>                            sharedNotebooks;\r
56         private final HashMap<String,String>            dirtySearches;\r
57 \r
58         private List<Tag>                                                       tags;\r
59         private final HashMap<String,String>            dirtyTags;\r
60 \r
61         private final HashMap<String, String>           exportableNotebooks;\r
62         private final HashMap<String, String>           exportableTags;\r
63         private List<Note>                                                      notes;\r
64         private final HashMap<String,String>            dirtyNotes;\r
65         private final HashMap<String,String>            dirtyLinkedNotebooks;\r
66         private final HashMap<Long,String>                      dirtySharedNotebooks;\r
67         private HashMap<String, NoteMetadata>                   noteMeta;\r
68         private final boolean                                           fullBackup;\r
69         private final DatabaseConnection                        conn;\r
70         private QXmlStreamWriter                                        writer;         \r
71         \r
72         private String                                                          errorMessage;\r
73         public int                                                                      lastError;\r
74         \r
75         public ExportData(DatabaseConnection conn2, boolean full) {\r
76                 conn = conn2;\r
77                 logger = new ApplicationLogger("export.log");\r
78                 notebooks = new ArrayList<Notebook>();\r
79                 tags = new ArrayList<Tag>();\r
80                 notes = new ArrayList<Note>();\r
81                 sharedNotebooks = new ArrayList<SharedNotebook>();\r
82                 linkedNotebooks = new ArrayList<LinkedNotebook>();\r
83                 dirtyNotebooks = new HashMap<String,String>();\r
84                 localNotebooks = new HashMap<String,String>();\r
85                 dirtyLinkedNotebooks = new HashMap<String,String>();\r
86                 dirtySharedNotebooks = new HashMap<Long,String>();\r
87                 dirtyTags = new HashMap<String,String>();\r
88                 fullBackup = full;\r
89                 \r
90                 dirtyNotes = new HashMap<String, String>();\r
91                 dirtySearches = new HashMap<String, String>();\r
92                 searches = new ArrayList<SavedSearch>();\r
93                 \r
94                 exportableNotebooks = new HashMap<String, String>();\r
95                 exportableTags = new HashMap<String, String>();\r
96         }\r
97         \r
98         \r
99         public ExportData(DatabaseConnection conn2, boolean full, List<String> guids) {\r
100                 conn = conn2;\r
101                 logger = new ApplicationLogger("export.log");\r
102                 notebooks = new ArrayList<Notebook>();\r
103                 tags = new ArrayList<Tag>();\r
104                 notes = new ArrayList<Note>();\r
105                 for (int i=0; i<guids.size(); i++) {\r
106                         notes.add(conn.getNoteTable().getNote(guids.get(i), true, true, true, true, true));\r
107                 }\r
108                 dirtyNotebooks = new HashMap<String,String>();\r
109                 localNotebooks = new HashMap<String,String>();\r
110                 dirtyTags = new HashMap<String,String>();\r
111                 fullBackup = full;\r
112                 \r
113                 dirtyNotes = new HashMap<String, String>();\r
114                 dirtyLinkedNotebooks = new HashMap<String,String>();\r
115                 dirtySharedNotebooks = new HashMap<Long,String>();\r
116                 dirtySearches = new HashMap<String, String>();\r
117                 searches = new ArrayList<SavedSearch>();\r
118                 \r
119                 exportableNotebooks = new HashMap<String, String>();\r
120                 exportableTags = new HashMap<String, String>();\r
121         }\r
122         \r
123         \r
124         public void exportData(String filename) {\r
125                 \r
126         notebooks = conn.getNotebookTable().getAll();           \r
127         tags = conn.getTagTable().getAll();\r
128         List<Notebook> books = conn.getNotebookTable().getAllLocal();\r
129         for (int i=0; i<books.size(); i++) {\r
130                 localNotebooks.put(books.get(i).getGuid(), "");\r
131         }\r
132         \r
133         books = conn.getNotebookTable().getDirty();\r
134         for (int i=0; i<books.size(); i++) {\r
135                 dirtyNotebooks.put(books.get(i).getGuid(), "");\r
136         }\r
137 \r
138         List<Tag> d= conn.getTagTable().getDirty();\r
139         for (int i=0; i<d.size(); i++) {\r
140                 dirtyTags.put(d.get(i).getGuid(), "");\r
141         }\r
142         \r
143         if (fullBackup)\r
144                 notes = conn.getNoteTable().getAllNotes();\r
145         \r
146         List<Note> dn = conn.getNoteTable().getDirty();\r
147         for (int i=0; i<dn.size(); i++) {\r
148                 dirtyNotes.put(dn.get(i).getGuid(), "");\r
149         }\r
150         \r
151         noteMeta = conn.getNoteTable().getNotesMetaInformation();\r
152 \r
153         \r
154         searches = conn.getSavedSearchTable().getAll();\r
155         \r
156         List<SavedSearch> ds = conn.getSavedSearchTable().getDirty();\r
157         for (int i=0; i<ds.size(); i++) {\r
158                 dirtySearches.put(ds.get(i).getGuid(), "");\r
159         }\r
160                 \r
161         linkedNotebooks = conn.getLinkedNotebookTable().getAll();\r
162         List<String> dln = conn.getLinkedNotebookTable().getDirtyGuids();\r
163         for (int i=0; i<dln.size(); i++) {\r
164                 dirtyLinkedNotebooks.put(dln.get(i), "");\r
165         }\r
166         \r
167         sharedNotebooks = conn.getSharedNotebookTable().getAll();\r
168         List<Long> dsn = conn.getSharedNotebookTable().getDirtyIds();\r
169         for (int i=0; i<dsn.size(); i++) {\r
170                 dirtySharedNotebooks.put(dsn.get(i), "");\r
171         }\r
172                 \r
173                 lastError = 0;\r
174                 errorMessage = "";\r
175                 QFile xmlFile = new QFile(filename);\r
176                 if (!xmlFile.open(QIODevice.OpenModeFlag.WriteOnly, QIODevice.OpenModeFlag.Truncate)) {\r
177                         lastError = 16;\r
178                         errorMessage = "Cannot open file.";\r
179                 }\r
180                         \r
181                 writer = new QXmlStreamWriter(xmlFile); \r
182                 writer.setAutoFormatting(true);\r
183                 writer.setCodec("UTF-8");\r
184                 writer.writeStartDocument();\r
185                 writer.writeDTD("<!DOCTYPE NeverNote-Export>");\r
186                 writer.writeStartElement("nevernote-export");\r
187                 writer.writeAttribute("version", "0.95");\r
188                 if (fullBackup)\r
189                         writer.writeAttribute("exportType", "backup");\r
190                 else\r
191                         writer.writeAttribute("exportType", "export");                  \r
192                 writer.writeAttribute("application", "NeverNote");\r
193                 writer.writeAttribute("applicationVersion", Global.version);\r
194                 if (fullBackup) {\r
195                         writer.writeStartElement("Synchronization");\r
196                         long sequenceDate = conn.getSyncTable().getLastSequenceDate();\r
197                         int number = conn.getSyncTable().getUpdateSequenceNumber();\r
198                         createTextNode("UpdateSequenceNumber", new Long(number).toString());\r
199                         createTextNode("LastSequenceDate", new Long(sequenceDate).toString());\r
200                         writer.writeEndElement();\r
201                 }\r
202                 \r
203                 for (int i=0; i<notes.size(); i++) {\r
204                         String guid = notes.get(i).getGuid();\r
205                         logger.log(logger.EXTREME, "Getting note " +guid +" : " +notes.get(i).getTitle());\r
206                         Note note = conn.getNoteTable().getNote(guid, true, true, true, true, true);\r
207                         logger.log(logger.EXTREME, "Writing note XML");\r
208                         writeNote(note);\r
209                 }\r
210                 \r
211                 writeNotebooks();\r
212                 writeTags();\r
213                 writeSavedSearches();\r
214                 writeLinkedNotebooks();\r
215                 writeSharedNotebooks();\r
216 \r
217                 \r
218                 writer.writeEndElement();\r
219                 writer.writeEndDocument();\r
220 \r
221                 \r
222                 \r
223                 writer.dispose();\r
224 \r
225                 \r
226                 xmlFile.close();\r
227                 xmlFile.dispose();\r
228 \r
229         }\r
230         \r
231         \r
232         private void writeSavedSearches() {\r
233                 if (!fullBackup)\r
234                         return;\r
235                 for (int i=0; i<searches.size(); i++) {\r
236                         writer.writeStartElement("SavedSearch");\r
237                         createTextNode("Guid", searches.get(i).getGuid());\r
238                         createTextNode("Name", searches.get(i).getName());\r
239                         createTextNode("Query", searches.get(i).getQuery());\r
240                         createTextNode("Format", new Integer(searches.get(i).getFormat().getValue()).toString());\r
241                         if (dirtySearches.containsKey(searches.get(i).getGuid()))\r
242                                 createTextNode("Dirty","true");\r
243                         else\r
244                                 createTextNode("Dirty","false");\r
245                         writer.writeEndElement();\r
246                 }\r
247         }\r
248         \r
249         \r
250         private void writeLinkedNotebooks() {\r
251                 if (!fullBackup)\r
252                         return;\r
253                 for (int i=0; i<linkedNotebooks.size(); i++) {\r
254                         writer.writeStartElement("LinkedNotebook");\r
255                         createTextNode("Guid", linkedNotebooks.get(i).getGuid());\r
256                         createTextNode("ShardID", linkedNotebooks.get(i).getShardId());\r
257                         createTextNode("ShareKey", linkedNotebooks.get(i).getShareKey());\r
258                         createTextNode("ShareName", linkedNotebooks.get(i).getShareName());\r
259                         createTextNode("Uri", linkedNotebooks.get(i).getUri());\r
260                         createTextNode("Username", linkedNotebooks.get(i).getUsername());\r
261                         createTextNode("UpdateSequenceNumber", new Long(linkedNotebooks.get(i).getUpdateSequenceNum()).toString());\r
262                         if (dirtyLinkedNotebooks.containsKey(linkedNotebooks.get(i).getGuid()))\r
263                                 createTextNode("Dirty", "true");\r
264                         else\r
265                                 createTextNode("Dirty", "false");\r
266                         writer.writeEndElement();\r
267                 }\r
268         }\r
269 \r
270                 \r
271         \r
272         private void writeSharedNotebooks() {\r
273                 if (!fullBackup)\r
274                         return;\r
275                 for (int i=0; i<linkedNotebooks.size(); i++) {\r
276                         writer.writeStartElement("SharedNotebook");\r
277                         createTextNode("Id", new Long(sharedNotebooks.get(i).getId()).toString());\r
278                         createTextNode("Userid", new Integer(sharedNotebooks.get(i).getUserId()).toString());\r
279                         createTextNode("Email", sharedNotebooks.get(i).getEmail());\r
280                         createTextNode("NotebookGuid", sharedNotebooks.get(i).getNotebookGuid());\r
281                         createTextNode("ShareKey", sharedNotebooks.get(i).getShareKey());\r
282                         createTextNode("Username", sharedNotebooks.get(i).getUsername());\r
283                         createTextNode("ServiceCreated", new Long(sharedNotebooks.get(i).getServiceCreated()).toString());\r
284                         if (dirtySharedNotebooks.containsKey(sharedNotebooks.get(i).getId()))\r
285                                 createTextNode("Dirty", "true");\r
286                         else\r
287                                 createTextNode("Dirty", "false");\r
288                         writer.writeEndElement();\r
289                 }\r
290         }\r
291 \r
292 \r
293         \r
294         private void writeNote(Note note) {\r
295                 \r
296                 writer.writeStartElement("Note");\r
297                 createTextNode("Guid", note.getGuid());\r
298                 createTextNode("UpdateSequenceNumber", new Long(note.getUpdateSequenceNum()).toString());\r
299                 createTextNode("Title", note.getTitle());\r
300                 createTextNode("Created", new Long(note.getCreated()).toString());\r
301                 createTextNode("Updated", new Long(note.getUpdated()).toString());\r
302                 createTextNode("Deleted", new Long(note.getDeleted()).toString());\r
303                 createTextNode("Active", new Boolean(note.isActive()).toString());\r
304                 createTextNode("NotebookGuid", note.getNotebookGuid());\r
305                 if (dirtyNotes.containsKey(note.getGuid()))\r
306                         createTextNode("Dirty", "true");\r
307                 else\r
308                         createTextNode("Dirty", "false");\r
309                 if (noteMeta.containsKey(note.getGuid())) {\r
310                         Integer color = new Integer(noteMeta.get(note.getGuid()).getColor());\r
311                         createTextNode("TitleColor", color.toString());\r
312                 }\r
313                 exportableNotebooks.put(note.getNotebookGuid(), "");\r
314                 \r
315                 if (note.getTagGuidsSize() > 0) {\r
316                         writer.writeStartElement("NoteTags");\r
317                         for (int i=0; i<note.getTagGuidsSize(); i++) {\r
318                                 createTextNode("Guid", note.getTagGuids().get(i));\r
319                                 exportableTags.put(note.getTagGuids().get(i), "");\r
320                         }\r
321                         writer.writeEndElement();\r
322                 }\r
323                 \r
324                 NoteAttributes noteAttributes = note.getAttributes();\r
325                 if (noteAttributes != null) {\r
326                         writer.writeStartElement("NoteAttributes");\r
327                         createTextNode("Author", noteAttributes.getAuthor());\r
328                         createTextNode("Source", noteAttributes.getSource());\r
329                         createTextNode("SourceApplication", noteAttributes.getSourceApplication());\r
330                         createTextNode("SourceURL", noteAttributes.getSourceURL());\r
331                         createTextNode("Altitude", new Double(noteAttributes.getAltitude()).toString());\r
332                         createTextNode("Longitude", new Double(noteAttributes.getLongitude()).toString());\r
333                         createTextNode("Latitude", new Double(noteAttributes.getLatitude()).toString());\r
334                         createTextNode("SubjectDate", new Long(noteAttributes.getSubjectDate()).toString());\r
335                         writer.writeEndElement();\r
336                 }\r
337                 \r
338 //              writeResources(conn.getNoteTable().noteResourceTable.getNoteResources(note.getGuid(), true));\r
339                 writeResources(note.getResources());\r
340                 \r
341                 logger.log(logger.EXTREME, "Writing content");\r
342                 writer.writeStartElement("Content");\r
343                 writer.writeCDATA(conn.getNoteTable().getNoteContentNoUTFConversion(note.getGuid()));\r
344                 writer.writeEndElement();\r
345                 writer.writeEndElement();\r
346         }\r
347 \r
348         \r
349         private void writeResources(List<Resource> resourceTable) {\r
350                 Resource resource;\r
351                 if (resourceTable.size() == 0)\r
352                         return;\r
353                 for (int i=0; i<resourceTable.size(); i++) {\r
354                         resource = resourceTable.get(i);\r
355                         writer.writeStartElement("NoteResource");\r
356                         createTextNode("Guid", resource.getGuid());\r
357                         createTextNode("NoteGuid", resource.getNoteGuid());\r
358                         createTextNode("UpdateSequenceNumber", new Integer(resource.getUpdateSequenceNum()).toString());\r
359                         createTextNode("Mime", resource.getMime());\r
360                         createTextNode("Duration", new Integer(resource.getDuration()).toString());\r
361                         createTextNode("Height", new Integer(resource.getHeight()).toString());\r
362                         createTextNode("Width", new Integer(resource.getWidth()).toString());\r
363                         logger.log(logger.EXTREME, "Checking for data node");\r
364                         if (resource.getData() != null)\r
365                                 writeDataNode("Data", resource.getData());\r
366                         logger.log(logger.EXTREME, "Checking for alternate data node");\r
367                         if (resource.getAlternateData() != null)\r
368                                 writeDataNode("AlternateData", resource.getAlternateData());\r
369                         logger.log(logger.EXTREME, "Checking for recognition");\r
370                         if (resource.getRecognition() != null)\r
371                                 writeRecognitionNode("Recognition", resource.getRecognition());\r
372                         if (resource.isActive())\r
373                                 createTextNode("Active", "true");\r
374                         else\r
375                                 createTextNode("Active", "false");\r
376                                 logger.log(logger.EXTREME, "Checking resource attributes");\r
377                         if (resource.getAttributes() != null) {\r
378                                 writer.writeStartElement("NoteResourceAttribute");\r
379                                 createTextNode("CameraMake", resource.getAttributes().getCameraMake());\r
380                                 createTextNode("CameraModel", resource.getAttributes().getCameraModel());\r
381                                 createTextNode("FileName", resource.getAttributes().getFileName());\r
382                                 createTextNode("RecoType", resource.getAttributes().getRecoType());\r
383                                 createTextNode("SourceURL", resource.getAttributes().getSourceURL());\r
384                                 createTextNode("Altitude", new Double(resource.getAttributes().getAltitude()).toString());\r
385                                 createTextNode("Longitude", new Double(resource.getAttributes().getLongitude()).toString());\r
386                                 createTextNode("Latitude", new Double(resource.getAttributes().getLatitude()).toString());\r
387                                 createTextNode("Timestamp", new Long(resource.getAttributes().getTimestamp()).toString());\r
388                                 if (resource.getAttributes().isAttachment())\r
389                                         createTextNode("Attachment", "true");\r
390                                 else    \r
391                                         createTextNode("Attachment", "false");\r
392                                 if (resource.getAttributes().isClientWillIndex())\r
393                                         createTextNode("ClientWillIndex", "true");\r
394                                 else\r
395                                         createTextNode("ClientWillIndex", "false");\r
396                                 writer.writeEndElement();\r
397                         }\r
398                         writer.writeEndElement();\r
399                 }\r
400                 logger.log(logger.EXTREME, "Ending resource node");\r
401 //              writer.writeEndElement();\r
402         }\r
403         \r
404         \r
405         private void writeDataNode(String name, Data data) {\r
406                 writer.writeStartElement(name);\r
407                 createTextNode("Size", new Integer(data.getSize()).toString());\r
408                 if (data.getBody() != null && data.getBody().length > 0)\r
409                         createBinaryNode("Body", new QByteArray(data.getBody()).toHex().toString());\r
410                 else\r
411                         createBinaryNode("Body", "");\r
412                 if (data.getBodyHash() != null && data.getBodyHash().length > 0)\r
413                         createTextNode("BodyHash", new QByteArray(data.getBodyHash()).toHex().toString());\r
414                 else\r
415                         createTextNode("BodyHash", "");\r
416                 writer.writeEndElement();               \r
417         }\r
418 \r
419         \r
420         \r
421         \r
422         private void writeRecognitionNode(String name, Data data) {\r
423                 writer.writeStartElement(name);\r
424                 createTextNode("Size", new Integer(data.getSize()).toString());\r
425                 if (data.getBody() != null && data.getBody().length > 0) {\r
426                         writer.writeStartElement("Body");\r
427                         writer.writeCDATA(new QByteArray(data.getBody()).toString());\r
428 //                      writer.writeCDATA(new QByteArray(data.getBody()).toHex().toString());\r
429                         writer.writeEndElement();\r
430                 }  else\r
431                         createBinaryNode("Body", "");\r
432                 \r
433                 if (data.getBodyHash() != null && data.getBodyHash().length > 0)\r
434                         createTextNode("BodyHash", new QByteArray(data.getBodyHash()).toHex().toString());\r
435                 else\r
436                         createTextNode("BodyHash", "");\r
437                 writer.writeEndElement();               \r
438         }\r
439 \r
440         \r
441         private void writeNotebooks() {\r
442                 for (int i=0; i<notebooks.size(); i++) {\r
443                         if (exportableNotebooks.containsKey(notebooks.get(i).getGuid()) || fullBackup) {\r
444                                 writer.writeStartElement("Notebook");\r
445                                 createTextNode("Guid", notebooks.get(i).getGuid());\r
446                                 createTextNode("Name", notebooks.get(i).getName());\r
447                                 createTextNode("UpdateSequenceNumber", new Long(notebooks.get(i).getUpdateSequenceNum()).toString());\r
448                                 if (notebooks.get(i).isDefaultNotebook())\r
449                                         createTextNode("DefaultNotebook", "true");\r
450                                 else\r
451                                         createTextNode("DefaultNotebook", "false");\r
452                                 createTextNode("ServiceCreated", new Long(notebooks.get(i).getServiceCreated()).toString());\r
453                                 createTextNode("ServiceUpdated", new Long(notebooks.get(i).getServiceUpdated()).toString());\r
454                                 if (localNotebooks.containsKey(notebooks.get(i).getGuid()))\r
455                                         createTextNode("Local","true");\r
456                                 else\r
457                                         createTextNode("Local","false");\r
458                                 if (dirtyNotebooks.containsKey(notebooks.get(i).getGuid()))\r
459                                         createTextNode("Dirty","true");\r
460                                 else\r
461                                         createTextNode("Dirty","false");\r
462                                 if (conn.getNotebookTable().isReadOnly(notebooks.get(i).getGuid()))\r
463                                         createTextNode("ReadOnly", "true");\r
464                                 else\r
465                                         createTextNode("ReadOnly", "false");\r
466                                 if (notebooks.get(i).getPublishing() != null) {\r
467                                         Publishing p = notebooks.get(i).getPublishing();\r
468                                         createTextNode("PublishingPublicDescription", p.getPublicDescription());\r
469                                         createTextNode("PublishingUri", p.getUri());\r
470                                         createTextNode("PublishingOrder", new Integer(p.getOrder().getValue()).toString());\r
471                                         if (p.isAscending())\r
472                                                 createTextNode("PublishingAscending", "true");\r
473                                         else\r
474                                                 createTextNode("PublishingAscending", "false");\r
475                                 }\r
476                                 QByteArray b = conn.getNotebookTable().getIconAsByteArray(notebooks.get(i).getGuid());\r
477                                 if (b != null) \r
478                                         createBinaryNode("Icon", b.toHex().toString());\r
479                                 if (notebooks.get(i).getStack() != null && !notebooks.get(i).getStack().trim().equals(""))\r
480                                         createTextNode("Stack", notebooks.get(i).getStack());\r
481                                 writer.writeEndElement();       \r
482                         }\r
483                 }\r
484         }\r
485 \r
486 \r
487         private void writeTags() {\r
488                 for (int i=0; i<tags.size(); i++) {\r
489                         if (exportableTags.containsKey(tags.get(i).getGuid()) || fullBackup) {\r
490                                 writer.writeStartElement("Tag");\r
491                                 createTextNode("Guid", tags.get(i).getGuid());\r
492                                 createTextNode("Name", tags.get(i).getName());\r
493                                 createTextNode("ParentGuid", tags.get(i).getParentGuid());\r
494                                 createTextNode("UpdateSequenceNumber", new Long(tags.get(i).getUpdateSequenceNum()).toString());\r
495                                 if (dirtyTags.containsKey(tags.get(i).getGuid()))\r
496                                         createTextNode("Dirty","true");\r
497                                 else\r
498                                         createTextNode("Dirty","false");\r
499                                 writer.writeEndElement();       \r
500                         }\r
501                 }\r
502         }\r
503         \r
504         \r
505         private void createTextNode(String nodeName, String value) {\r
506                 if (value == null)\r
507                         value = "";\r
508                 writer.writeTextElement(nodeName, value);\r
509                 return;\r
510         }\r
511 \r
512         private void createBinaryNode(String nodeName, String value) {\r
513                 if (value == null)\r
514                         value = "";\r
515                 logger.log(logger.EXTREME, "Writing binary node");\r
516                 writer.writeStartElement(nodeName);\r
517 /*              int i=0;\r
518                 for (; i<value.length(); i+=80) \r
519                 {\r
520                         writer.writeCharacters("\n"+value.substring(i,i+80));\r
521                 }\r
522                 writer.writeCharacters("\n"+value.substring(i)+"\n");\r
523 */              writer.writeCharacters(value);\r
524                 writer.writeEndElement();\r
525                 return;\r
526         }\r
527 \r
528         \r
529         public String getErrorMessage() {\r
530                 return errorMessage;\r
531         }\r
532         \r
533         \r
534 }\r