OSDN Git Service

2c36707ad8811b2e683ffb681520b57811e8e1fe
[neighbornote/NeighborNote.git] / src / cx / fbn / nevernote / xml / ExportData.java
1 /*\r
2  * This file is part of NeverNote \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.Note;\r
28 import com.evernote.edam.type.NoteAttributes;\r
29 import com.evernote.edam.type.Notebook;\r
30 import com.evernote.edam.type.Resource;\r
31 import com.evernote.edam.type.SavedSearch;\r
32 import com.evernote.edam.type.Tag;\r
33 import com.trolltech.qt.core.QByteArray;\r
34 import com.trolltech.qt.core.QFile;\r
35 import com.trolltech.qt.core.QIODevice;\r
36 import com.trolltech.qt.xml.QXmlStreamWriter;\r
37 \r
38 import cx.fbn.nevernote.Global;\r
39 import cx.fbn.nevernote.sql.DatabaseConnection;\r
40 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
41 import cx.fbn.nevernote.utilities.Pair;\r
42 \r
43 public class ExportData {\r
44         \r
45         private List<Notebook>                                          notebooks;\r
46         private final HashMap<String,String>            localNotebooks;\r
47         private final HashMap<String,String>            dirtyNotebooks;\r
48         private final ApplicationLogger                         logger;\r
49         \r
50         private List<SavedSearch>                                       searches;\r
51         private final HashMap<String,String>            dirtySearches;\r
52 \r
53         private List<Tag>                                                       tags;\r
54         private final HashMap<String,String>            dirtyTags;\r
55 \r
56         private final HashMap<String, String>           exportableNotebooks;\r
57         private final HashMap<String, String>           exportableTags;\r
58         private List<Note>                                                      notes;\r
59         private final HashMap<String,String>            dirtyNotes;\r
60         private HashMap<String,Integer>         titleColors;\r
61         private final boolean                                           fullBackup;\r
62         private final DatabaseConnection                        conn;\r
63         private QXmlStreamWriter                                        writer;         \r
64         \r
65         private String                                                          errorMessage;\r
66         public int                                                                      lastError;\r
67         \r
68         public ExportData(DatabaseConnection conn2, boolean full) {\r
69                 conn = conn2;\r
70                 logger = new ApplicationLogger("export.log");\r
71                 notebooks = new ArrayList<Notebook>();\r
72                 tags = new ArrayList<Tag>();\r
73                 notes = new ArrayList<Note>();\r
74                 dirtyNotebooks = new HashMap<String,String>();\r
75                 localNotebooks = new HashMap<String,String>();\r
76                 dirtyTags = new HashMap<String,String>();\r
77                 fullBackup = full;\r
78                 \r
79                 dirtyNotes = new HashMap<String, String>();\r
80                 dirtySearches = new HashMap<String, String>();\r
81                 searches = new ArrayList<SavedSearch>();\r
82                 \r
83                 exportableNotebooks = new HashMap<String, String>();\r
84                 exportableTags = new HashMap<String, String>();\r
85         }\r
86         \r
87         \r
88         public ExportData(DatabaseConnection conn2, boolean full, List<String> guids) {\r
89                 conn = conn2;\r
90                 logger = new ApplicationLogger("export.log");\r
91                 notebooks = new ArrayList<Notebook>();\r
92                 tags = new ArrayList<Tag>();\r
93                 notes = new ArrayList<Note>();\r
94                 for (int i=0; i<guids.size(); i++) {\r
95                         notes.add(conn.getNoteTable().getNote(guids.get(i), true, true, true, true, true));\r
96                 }\r
97                 dirtyNotebooks = new HashMap<String,String>();\r
98                 localNotebooks = new HashMap<String,String>();\r
99                 dirtyTags = new HashMap<String,String>();\r
100                 fullBackup = full;\r
101                 \r
102                 dirtyNotes = new HashMap<String, String>();\r
103                 dirtySearches = new HashMap<String, String>();\r
104                 searches = new ArrayList<SavedSearch>();\r
105                 \r
106                 exportableNotebooks = new HashMap<String, String>();\r
107                 exportableTags = new HashMap<String, String>();\r
108         }\r
109         \r
110         \r
111         public void exportData(String filename) {\r
112                 \r
113         notebooks = conn.getNotebookTable().getAll();           \r
114         tags = conn.getTagTable().getAll();\r
115         List<Notebook> books = conn.getNotebookTable().getAllLocal();\r
116         for (int i=0; i<books.size(); i++) {\r
117                 localNotebooks.put(books.get(i).getGuid(), "");\r
118         }\r
119         \r
120         books = conn.getNotebookTable().getDirty();\r
121         for (int i=0; i<books.size(); i++) {\r
122                 dirtyNotebooks.put(books.get(i).getGuid(), "");\r
123         }\r
124 \r
125         List<Tag> d= conn.getTagTable().getDirty();\r
126         for (int i=0; i<d.size(); i++) {\r
127                 dirtyTags.put(d.get(i).getGuid(), "");\r
128         }\r
129         \r
130         if (fullBackup)\r
131                 notes = conn.getNoteTable().getAllNotes();\r
132         \r
133         List<Note> dn = conn.getNoteTable().getDirty();\r
134         for (int i=0; i<dn.size(); i++) {\r
135                 dirtyNotes.put(dn.get(i).getGuid(), "");\r
136         }\r
137         \r
138         List<Pair<String,Integer>> tColors = conn.getNoteTable().getNoteTitleColors();\r
139         titleColors = new HashMap<String,Integer>();\r
140         for (int i=0; i<tColors.size(); i++) {\r
141                 titleColors.put(tColors.get(i).getFirst(), tColors.get(i).getSecond());\r
142         }\r
143         \r
144         searches = conn.getSavedSearchTable().getAll();\r
145         \r
146         List<SavedSearch> ds = conn.getSavedSearchTable().getDirty();\r
147         for (int i=0; i<ds.size(); i++) {\r
148                 dirtySearches.put(ds.get(i).getGuid(), "");\r
149         }\r
150                 \r
151                 \r
152                 \r
153                 lastError = 0;\r
154                 errorMessage = "";\r
155                 QFile xmlFile = new QFile(filename);\r
156                 if (!xmlFile.open(QIODevice.OpenModeFlag.WriteOnly, QIODevice.OpenModeFlag.Truncate)) {\r
157                         lastError = 16;\r
158                         errorMessage = "Cannot open file.";\r
159                 }\r
160                         \r
161                 writer = new QXmlStreamWriter(xmlFile); \r
162                 writer.setAutoFormatting(true);\r
163                 writer.setCodec("UTF-8");\r
164                 writer.writeStartDocument();\r
165                 writer.writeDTD("<!DOCTYPE NeverNote-Export>");\r
166                 writer.writeStartElement("nevernote-export");\r
167                 writer.writeAttribute("version", "0.86");\r
168                 if (fullBackup)\r
169                         writer.writeAttribute("exportType", "backup");\r
170                 else\r
171                         writer.writeAttribute("exportType", "export");                  \r
172                 writer.writeAttribute("application", "NeverNote");\r
173                 writer.writeAttribute("applicationVersion", Global.version);\r
174                 if (fullBackup) {\r
175                         writer.writeStartElement("Synchronization");\r
176                         long sequenceDate = conn.getSyncTable().getLastSequenceDate();\r
177                         int number = conn.getSyncTable().getUpdateSequenceNumber();\r
178                         createTextNode("UpdateSequenceNumber", new Long(number).toString());\r
179                         createTextNode("LastSequenceDate", new Long(sequenceDate).toString());\r
180                         writer.writeEndElement();\r
181                 }\r
182                 \r
183                 for (int i=0; i<notes.size(); i++) {\r
184                         String guid = notes.get(i).getGuid();\r
185                         logger.log(logger.EXTREME, "Getting note " +guid +" : " +notes.get(i).getTitle());\r
186                         Note note = conn.getNoteTable().getNote(guid, true, true, true, true, true);\r
187                         logger.log(logger.EXTREME, "Writing note XML");\r
188                         writeNote(note);\r
189                 }\r
190                 \r
191                 writeNotebooks();\r
192                 writeTags();\r
193                 writeSavedSearches();\r
194 \r
195                 \r
196                 writer.writeEndElement();\r
197                 writer.writeEndDocument();\r
198 \r
199                 \r
200                 \r
201                 writer.dispose();\r
202 \r
203                 \r
204                 xmlFile.close();\r
205                 xmlFile.dispose();\r
206 \r
207         }\r
208         \r
209         \r
210         private void writeSavedSearches() {\r
211                 if (!fullBackup)\r
212                         return;\r
213                 for (int i=0; i<searches.size(); i++) {\r
214                         writer.writeStartElement("SavedSearch");\r
215                         createTextNode("Guid", searches.get(i).getGuid());\r
216                         createTextNode("Name", searches.get(i).getName());\r
217                         createTextNode("Query", searches.get(i).getQuery());\r
218                         createTextNode("Format", new Integer(searches.get(i).getFormat().getValue()).toString());\r
219                         if (dirtySearches.containsKey(searches.get(i).getGuid()))\r
220                                 createTextNode("Dirty","true");\r
221                         else\r
222                                 createTextNode("Dirty","false");\r
223                         writer.writeEndElement();\r
224                 }\r
225         }\r
226         \r
227                 \r
228         \r
229         private void writeNote(Note note) {\r
230                 \r
231                 writer.writeStartElement("Note");\r
232                 createTextNode("Guid", note.getGuid());\r
233                 createTextNode("UpdateSequenceNumber", new Long(note.getUpdateSequenceNum()).toString());\r
234                 createTextNode("Title", note.getTitle());\r
235                 createTextNode("Created", new Long(note.getCreated()).toString());\r
236                 createTextNode("Updated", new Long(note.getUpdated()).toString());\r
237                 createTextNode("Deleted", new Long(note.getDeleted()).toString());\r
238                 createTextNode("Active", new Boolean(note.isActive()).toString());\r
239                 createTextNode("NotebookGuid", note.getNotebookGuid());\r
240                 if (dirtyNotes.containsKey(note.getGuid()))\r
241                         createTextNode("Dirty", "true");\r
242                 else\r
243                         createTextNode("Dirty", "false");\r
244                 if (titleColors.containsKey(note.getGuid()))\r
245                         createTextNode("TitleColor", new String(titleColors.get(note.getGuid()).toString()));\r
246                 exportableNotebooks.put(note.getNotebookGuid(), "");\r
247                 \r
248                 if (note.getTagGuidsSize() > 0) {\r
249                         writer.writeStartElement("NoteTags");\r
250                         for (int i=0; i<note.getTagGuidsSize(); i++) {\r
251                                 createTextNode("Guid", note.getTagGuids().get(i));\r
252                                 exportableTags.put(note.getTagGuids().get(i), "");\r
253                         }\r
254                         writer.writeEndElement();\r
255                 }\r
256                 \r
257                 NoteAttributes noteAttributes = note.getAttributes();\r
258                 if (noteAttributes != null) {\r
259                         writer.writeStartElement("NoteAttributes");\r
260                         createTextNode("Author", noteAttributes.getAuthor());\r
261                         createTextNode("Source", noteAttributes.getSource());\r
262                         createTextNode("SourceApplication", noteAttributes.getSourceApplication());\r
263                         createTextNode("SourceURL", noteAttributes.getSourceURL());\r
264                         createTextNode("Altitude", new Double(noteAttributes.getAltitude()).toString());\r
265                         createTextNode("Longitude", new Double(noteAttributes.getLongitude()).toString());\r
266                         createTextNode("Latitude", new Double(noteAttributes.getLatitude()).toString());\r
267                         createTextNode("SubjectDate", new Long(noteAttributes.getSubjectDate()).toString());\r
268                         writer.writeEndElement();\r
269                 }\r
270                 \r
271 //              writeResources(conn.getNoteTable().noteResourceTable.getNoteResources(note.getGuid(), true));\r
272                 writeResources(note.getResources());\r
273                 \r
274                 logger.log(logger.EXTREME, "Writing content");\r
275                 writer.writeStartElement("Content");\r
276                 writer.writeCDATA(conn.getNoteTable().getNoteContentBinary(note.getGuid()));\r
277                 writer.writeEndElement();\r
278                 writer.writeEndElement();\r
279         }\r
280 \r
281         \r
282         private void writeResources(List<Resource> resourceTable) {\r
283                 Resource resource;\r
284                 if (resourceTable.size() == 0)\r
285                         return;\r
286                 for (int i=0; i<resourceTable.size(); i++) {\r
287                         resource = resourceTable.get(i);\r
288                         writer.writeStartElement("NoteResource");\r
289                         createTextNode("Guid", resource.getGuid());\r
290                         createTextNode("NoteGuid", resource.getNoteGuid());\r
291                         createTextNode("UpdateSequenceNumber", new Integer(resource.getUpdateSequenceNum()).toString());\r
292                         createTextNode("Mime", resource.getMime());\r
293                         createTextNode("Duration", new Integer(resource.getDuration()).toString());\r
294                         createTextNode("Height", new Integer(resource.getHeight()).toString());\r
295                         createTextNode("Width", new Integer(resource.getWidth()).toString());\r
296                         logger.log(logger.EXTREME, "Checking for data node");\r
297                         if (resource.getData() != null)\r
298                                 writeDataNode("Data", resource.getData());\r
299                         logger.log(logger.EXTREME, "Checking for alternate data node");\r
300                         if (resource.getAlternateData() != null)\r
301                                 writeDataNode("AlternateData", resource.getAlternateData());\r
302                         logger.log(logger.EXTREME, "Checking for recognition");\r
303                         if (resource.getRecognition() != null)\r
304                                 writeRecognitionNode("Recognition", resource.getRecognition());\r
305                         if (resource.isActive())\r
306                                 createTextNode("Active", "true");\r
307                         else\r
308                                 createTextNode("Active", "false");\r
309                                 logger.log(logger.EXTREME, "Checking resource attributes");\r
310                         if (resource.getAttributes() != null) {\r
311                                 writer.writeStartElement("NoteResourceAttribute");\r
312                                 createTextNode("CameraMake", resource.getAttributes().getCameraMake());\r
313                                 createTextNode("CameraModel", resource.getAttributes().getCameraModel());\r
314                                 createTextNode("FileName", resource.getAttributes().getFileName());\r
315                                 createTextNode("RecoType", resource.getAttributes().getRecoType());\r
316                                 createTextNode("SourceURL", resource.getAttributes().getSourceURL());\r
317                                 createTextNode("Altitude", new Double(resource.getAttributes().getAltitude()).toString());\r
318                                 createTextNode("Longitude", new Double(resource.getAttributes().getLongitude()).toString());\r
319                                 createTextNode("Latitude", new Double(resource.getAttributes().getLatitude()).toString());\r
320                                 createTextNode("Timestamp", new Long(resource.getAttributes().getTimestamp()).toString());\r
321                                 if (resource.getAttributes().isAttachment())\r
322                                         createTextNode("Attachment", "true");\r
323                                 else    \r
324                                         createTextNode("Attachment", "false");\r
325                                 if (resource.getAttributes().isClientWillIndex())\r
326                                         createTextNode("ClientWillIndex", "true");\r
327                                 else\r
328                                         createTextNode("ClientWillIndex", "false");\r
329                                 writer.writeEndElement();\r
330                         }\r
331                         writer.writeEndElement();\r
332                 }\r
333                 logger.log(logger.EXTREME, "Ending resource node");\r
334 //              writer.writeEndElement();\r
335         }\r
336         \r
337         \r
338         private void writeDataNode(String name, Data data) {\r
339                 writer.writeStartElement(name);\r
340                 createTextNode("Size", new Integer(data.getSize()).toString());\r
341                 if (data.getBody() != null && data.getBody().length > 0)\r
342                         createBinaryNode("Body", new QByteArray(data.getBody()).toHex().toString());\r
343                 else\r
344                         createBinaryNode("Body", "");\r
345                 if (data.getBodyHash() != null && data.getBodyHash().length > 0)\r
346                         createTextNode("BodyHash", new QByteArray(data.getBodyHash()).toHex().toString());\r
347                 else\r
348                         createTextNode("BodyHash", "");\r
349                 writer.writeEndElement();               \r
350         }\r
351 \r
352         \r
353         \r
354         \r
355         private void writeRecognitionNode(String name, Data data) {\r
356                 writer.writeStartElement(name);\r
357                 createTextNode("Size", new Integer(data.getSize()).toString());\r
358                 if (data.getBody() != null && data.getBody().length > 0) {\r
359                         writer.writeStartElement("Body");\r
360                         writer.writeCDATA(new QByteArray(data.getBody()).toString());\r
361 //                      writer.writeCDATA(new QByteArray(data.getBody()).toHex().toString());\r
362                         writer.writeEndElement();\r
363                 }  else\r
364                         createBinaryNode("Body", "");\r
365                 \r
366                 if (data.getBodyHash() != null && data.getBodyHash().length > 0)\r
367                         createTextNode("BodyHash", new QByteArray(data.getBodyHash()).toHex().toString());\r
368                 else\r
369                         createTextNode("BodyHash", "");\r
370                 writer.writeEndElement();               \r
371         }\r
372 \r
373         \r
374         private void writeNotebooks() {\r
375                 for (int i=0; i<notebooks.size(); i++) {\r
376                         if (exportableNotebooks.containsKey(notebooks.get(i).getGuid()) || fullBackup) {\r
377                                 writer.writeStartElement("Notebook");\r
378                                 createTextNode("Guid", notebooks.get(i).getGuid());\r
379                                 createTextNode("Name", notebooks.get(i).getName());\r
380                                 createTextNode("UpdateSequenceNumber", new Long(notebooks.get(i).getUpdateSequenceNum()).toString());\r
381                                 if (notebooks.get(i).isDefaultNotebook())\r
382                                         createTextNode("DefaultNotebook", "true");\r
383                                 else\r
384                                         createTextNode("DefaultNotebook", "false");\r
385                                 createTextNode("ServiceCreated", new Long(notebooks.get(i).getServiceCreated()).toString());\r
386                                 createTextNode("ServiceUpdated", new Long(notebooks.get(i).getServiceUpdated()).toString());\r
387                                 if (localNotebooks.containsKey(notebooks.get(i).getGuid()))\r
388                                         createTextNode("Local","true");\r
389                                 else\r
390                                         createTextNode("Local","false");\r
391                                 if (dirtyNotebooks.containsKey(notebooks.get(i).getGuid()))\r
392                                         createTextNode("Dirty","true");\r
393                                 else\r
394                                         createTextNode("Dirty","false");\r
395                                 writer.writeEndElement();       \r
396                         }\r
397                 }\r
398         }\r
399 \r
400 \r
401         private void writeTags() {\r
402                 for (int i=0; i<tags.size(); i++) {\r
403                         if (exportableTags.containsKey(tags.get(i).getGuid()) || fullBackup) {\r
404                                 writer.writeStartElement("Tag");\r
405                                 createTextNode("Guid", tags.get(i).getGuid());\r
406                                 createTextNode("Name", tags.get(i).getName());\r
407                                 createTextNode("ParentGuid", tags.get(i).getParentGuid());\r
408                                 createTextNode("UpdateSequenceNumber", new Long(tags.get(i).getUpdateSequenceNum()).toString());\r
409                                 if (dirtyTags.containsKey(tags.get(i).getGuid()))\r
410                                         createTextNode("Dirty","true");\r
411                                 else\r
412                                         createTextNode("Dirty","false");\r
413                                 writer.writeEndElement();       \r
414                         }\r
415                 }\r
416         }\r
417         \r
418         \r
419         private void createTextNode(String nodeName, String value) {\r
420                 if (value == null)\r
421                         value = "";\r
422                 writer.writeTextElement(nodeName, value);\r
423                 return;\r
424         }\r
425 \r
426         private void createBinaryNode(String nodeName, String value) {\r
427                 if (value == null)\r
428                         value = "";\r
429                 logger.log(logger.EXTREME, "Writing binary node");\r
430                 writer.writeStartElement(nodeName);\r
431 /*              int i=0;\r
432                 for (; i<value.length(); i+=80) \r
433                 {\r
434                         writer.writeCharacters("\n"+value.substring(i,i+80));\r
435                 }\r
436                 writer.writeCharacters("\n"+value.substring(i)+"\n");\r
437 */              writer.writeCharacters(value);\r
438                 writer.writeEndElement();\r
439                 return;\r
440         }\r
441 \r
442         \r
443         public String getErrorMessage() {\r
444                 return errorMessage;\r
445         }\r
446         \r
447         \r
448 }\r