OSDN Git Service

Save non-standard metadata to note attribute.sourceApplication for DB restores.
authorRandy Baumgarte <randy@fbn.cx>
Sun, 28 Aug 2011 12:35:08 +0000 (08:35 -0400)
committerRandy Baumgarte <randy@fbn.cx>
Sun, 28 Aug 2011 12:35:08 +0000 (08:35 -0400)
src/cx/fbn/nevernote/evernote/NoteMetadata.java
src/cx/fbn/nevernote/sql/NoteTable.java
src/cx/fbn/nevernote/threads/SyncRunner.java
src/cx/fbn/nevernote/utilities/ListManager.java
src/cx/fbn/nevernote/xml/ExportData.java
src/cx/fbn/nevernote/xml/ImportData.java

index 3bec18a..a6139b1 100644 (file)
@@ -1,6 +1,5 @@
 package cx.fbn.nevernote.evernote;\r
 \r
-import com.trolltech.qt.gui.QColor;\r
 \r
 public class NoteMetadata {\r
        private String guid;\r
@@ -9,7 +8,7 @@ public class NoteMetadata {
        private boolean dirty;\r
        \r
        public NoteMetadata() {\r
-               color = QColor.white.rgb();\r
+               color = -1;\r
                pinned = false;\r
                dirty = false;\r
        }\r
index 264ae7a..ac0aeb1 100644 (file)
@@ -43,7 +43,6 @@ import cx.fbn.nevernote.evernote.EnmlConverter;
 import cx.fbn.nevernote.evernote.NoteMetadata;\r
 import cx.fbn.nevernote.sql.driver.NSqlQuery;\r
 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
-import cx.fbn.nevernote.utilities.Pair;\r
 \r
 public class NoteTable {\r
        private final ApplicationLogger                 logger;\r
@@ -223,6 +222,8 @@ public class NoteTable {
        }\r
        // Get a note by Guid\r
        public Note getNote(String noteGuid, boolean loadContent, boolean loadResources, boolean loadRecognition, boolean loadBinary, boolean loadTags) {\r
+\r
+//             extractMetadata("otherKey:{values};baumgarte:{titleColor=fff;pinned=true;};finalKey:{values1);");\r
                if (noteGuid == null)\r
                        return null;\r
                if (noteGuid.trim().equals(""))\r
@@ -747,13 +748,14 @@ public class NoteTable {
                }\r
        }\r
        // Update a note\r
-       public void updateNote(Note n, boolean isNew) {\r
-               int titleColor = getNoteTitleColor(n.getGuid());\r
+       public void updateNote(Note n) {\r
+               NoteMetadata meta = getNoteMetaInformation(n.getGuid());\r
                String originalGuid = findAlternateGuid(n.getGuid());\r
                expungeNote(n.getGuid(), true, false);\r
                addNote(n, false);\r
-               if (titleColor != -1)\r
-                       setNoteTitleColor(n.getGuid(), titleColor);\r
+               if (n!=null) {\r
+                       updateNoteMetadata(meta);\r
+               }\r
                if (originalGuid != null) {\r
                        updateNoteGuid(n.getGuid(), originalGuid);\r
                        updateNoteGuid(originalGuid, n.getGuid());\r
@@ -787,12 +789,29 @@ public class NoteTable {
                boolean retVal = query.next();\r
                return retVal;\r
        }\r
-       // This is a convience method to check if a tag exists & update/create based upon it\r
-       public void syncNote(Note tag, boolean isDirty) {\r
-               if (exists(tag.getGuid()))\r
-                       updateNote(tag, isDirty);\r
+       // This is a convience method to check if a note exists & update/create based upon it\r
+       public void syncNote(Note note) {\r
+               // If we got the note from Evernote we use its \r
+               // metadata instead of the local copy.\r
+               NoteMetadata meta = null;\r
+               if (note.getAttributes() != null && note.getAttributes().getSourceApplication() != null) {\r
+                       meta = extractMetadata(note.getAttributes().getSourceApplication());\r
+               } else \r
+                       meta = getNoteMetaInformation(note.getGuid());\r
+               \r
+               // Now, if the note exists we simply update it.  Otherwise we\r
+               // add a new note.\r
+               if (exists(note.getGuid())) {\r
+                       updateNote(note);\r
+               }\r
                else\r
-                       addNote(tag, isDirty);\r
+                       addNote(note, false);\r
+               \r
+               // If we have metadata, we write it out.\r
+               if (meta != null) {\r
+                       meta.setGuid(note.getGuid());\r
+                       updateNoteMetadata(meta);\r
+               }\r
        }\r
        // Get a list of notes that need to be updated\r
        public List <Note> getDirty() {\r
@@ -1189,50 +1208,24 @@ public class NoteTable {
                }       \r
                return guids;   \r
        }\r
-       \r
-       \r
-       //**********************************************************************************\r
-       //* Title color functions\r
-       //**********************************************************************************\r
-       // Get the title color of all notes\r
-/*     public List<Pair<String, Integer>> getNoteTitleColors() {\r
-               List<Pair<String,Integer>> returnValue = new ArrayList<Pair<String,Integer>>();\r
-        NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               \r
-               if (!query.exec("Select guid,titleColor from Note where titleColor != -1"))\r
-                       logger.log(logger.EXTREME, "Note SQL retrieve has failed on getUnindexed().");\r
-\r
-               String guid;\r
-               Integer color;\r
-               \r
-               // Get a list of the notes\r
-               while (query.next()) {\r
-                       Pair<String, Integer> pair = new Pair<String,Integer>();\r
-                       guid = query.valueString(0);\r
-                       color = query.valueInteger(1);\r
-                       pair.setFirst(guid);\r
-                       pair.setSecond(color);\r
-                       returnValue.add(pair); \r
-               }       \r
 \r
-               return returnValue;\r
-       }\r
-       */\r
        \r
        // Get note meta information\r
        public void updateNoteMetadata(NoteMetadata meta) {\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               if (!query.prepare("Update Note set titleColor=:color, pinned=:pinned where guid=:guid"))\r
+               if (!query.prepare("Update Note set titleColor=:color, pinned=:pinned, attributeSourceApplication=:metaString where guid=:guid"))\r
                        logger.log(logger.EXTREME, "Note SQL prepare has failed on updateNoteMetadata.");\r
                query.bindValue(":color", meta.getColor());\r
                query.bindValue(":pinned", meta.isPinned());\r
                query.bindValue(":guid", meta.getGuid());\r
-               query.exec();\r
+               query.bindValue(":metaString", buildMetadataString(meta));\r
+               if (!query.exec()) \r
+                       logger.log(logger.EXTREME, "Note SQL exec has failed on updateNoteMetadata.");\r
                return;\r
        }\r
        \r
-       // Get note meta information\r
-       public HashMap<String, NoteMetadata> getNoteMetaInformation() {\r
+       // Get all note meta information\r
+       public HashMap<String, NoteMetadata> getNotesMetaInformation() {\r
                HashMap<String, NoteMetadata> returnValue = new HashMap<String, NoteMetadata>();\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
@@ -1253,41 +1246,30 @@ public class NoteTable {
 \r
                return returnValue;\r
        }\r
-       // Set a title color\r
-       public void  setNoteTitleColor(String guid, int color) {\r
-               NSqlQuery query = new NSqlQuery(db.getConnection());\r
-               \r
-               query.prepare("Update note set titlecolor=:color where guid=:guid");\r
-               query.bindValue(":guid", guid);\r
-               query.bindValue(":color", color);\r
-               if (!query.exec())\r
-                       logger.log(logger.EXTREME, "Error updating title color.");\r
-       }\r
-       // Get in individual note's title color\r
-       // Get the title color of all notes\r
-       public Integer getNoteTitleColor(String guid) {\r
-               List<Pair<String,Integer>> returnValue = new ArrayList<Pair<String,Integer>>();\r
+       // Get note meta information\r
+       public NoteMetadata getNoteMetaInformation(String guid) {\r
         NSqlQuery query = new NSqlQuery(db.getConnection());\r
                \r
-        query.prepare("Select titleColor from Note where titleColor != -1 and guid=:guid");\r
-        query.bindValue(":guid", guid);\r
-               if (!query.exec())\r
-                       logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteTitleColor(guid).");\r
+               if (!query.prepare("Select guid,titleColor, isDirty, pinned from Note where guid=:guid")) {\r
+                       logger.log(logger.EXTREME, "Note SQL retrieve has failed on getNoteMetaInformation.");\r
+                       return null;\r
+               }\r
+               query.bindValue(":guid", guid);\r
+               query.exec();\r
 \r
-               Integer color = -1;\r
-               \r
                // Get a list of the notes\r
                while (query.next()) {\r
-                       Pair<String, Integer> pair = new Pair<String,Integer>();\r
-                       guid = query.valueString(0);\r
-                       color = query.valueInteger(1);\r
-                       pair.setFirst(guid);\r
-                       pair.setSecond(color);\r
-                       returnValue.add(pair); \r
+                       NoteMetadata note = new NoteMetadata();\r
+                       note.setGuid(query.valueString(0));\r
+                       note.setColor(query.valueInteger(1));\r
+                       note.setDirty(query.valueBoolean(2, false));\r
+                       int pinned = query.valueInteger(3);\r
+                       if (pinned > 0) \r
+                               note.setPinned(true);\r
+                       return note;\r
                }       \r
 \r
-               \r
-               return color;\r
+               return null;\r
        }\r
        \r
        \r
@@ -1494,6 +1476,106 @@ public class NoteTable {
                }\r
        }\r
 \r
+       // Extract metadata from a note's Note.attributes.sourceApplication\r
+       private NoteMetadata extractMetadata(String sourceApplication) {\r
+               String consumerKey = "baumgarte:{";\r
+               int startPos = sourceApplication.indexOf(consumerKey);\r
+               if (startPos < 0 )\r
+                               return null;\r
+               \r
+               NoteMetadata meta = new NoteMetadata();\r
+               startPos = startPos+consumerKey.length();\r
+               \r
+//             String startString = sourceApplication.substring(0,startPos);\r
+               String metaString = sourceApplication.substring(startPos);\r
+//             String endString = metaString.substring(metaString.indexOf("};"));\r
+               int endPos = metaString.indexOf("};");\r
+               if (endPos > 0)\r
+                       metaString = metaString.substring(0,endPos);\r
+               \r
+               String value = parseMetaString(metaString, "titleColor");\r
+               if (value != null)\r
+                       meta.setColor(Integer.parseInt(value));\r
+               \r
+               value = parseMetaString(metaString, "pinned");\r
+               if (value != null && value.equals(true))\r
+                       meta.setPinned(true);\r
+                               \r
+               return meta;\r
+       }\r
+       \r
+       // Given a metadata string from attribute.sourceApplication, we\r
+       // extract the information for a given key.\r
+       private String parseMetaString(String metaString, String key) {\r
+               int startPos = metaString.indexOf(key);\r
+               if (startPos < 0)\r
+                       return null;\r
+               \r
+               String value = metaString.substring(startPos+key.length()+1);\r
+               int endPos = value.indexOf(";");\r
+               if (endPos > 0)\r
+                       value = value.substring(0,endPos);\r
+               \r
+               return value;\r
+       }\r
+       \r
+       // Given a set of metadata, we build a string that can be inserted\r
+       // into the attribute.sourceApplication string.\r
+       private String buildMetadataString(NoteMetadata meta) {\r
+               StringBuffer value = new StringBuffer(removeExistingMetaString(meta.getGuid()));\r
+               StringBuffer metaString = new StringBuffer();\r
+               \r
+               if (meta.isPinned()) {\r
+                       metaString.append("pinned=true;");\r
+               }\r
+               if (meta.getColor() != -1) {\r
+                       metaString.append("titleColor=" +new Integer(meta.getColor()).toString()+";");\r
+               }\r
+               if (metaString.length()>0) {\r
+                       \r
+                       // Adda any missing ";" or " " at the end of the existing \r
+                       // string.\r
+                       if (value.length()>1 && (!value.toString().trim().endsWith(";") || !value.toString().trim().endsWith(";")))   \r
+                               value.append("; ");\r
+                       \r
+                       value.append("baumgarte:{");\r
+                       value.append(metaString);\r
+                       value.append("};");\r
+                       return value.toString();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       // This will remove the existing metadata string from the attribute.sourceApplication string.\r
+       private String removeExistingMetaString(String guid) {\r
+        NSqlQuery query = new NSqlQuery(db.getConnection());\r
+               \r
+               if (!query.prepare("Select attributeSourceApplication from Note where guid=:guid")) {\r
+                       logger.log(logger.EXTREME, "Note SQL retrieve has failed in removeExistingMetaString.");\r
+                       return null;\r
+               }\r
+               query.bindValue(":guid", guid);\r
+               query.exec();\r
+\r
+               // Get the application source string\r
+               String sourceApplication = null;\r
+               while (query.next()) {\r
+                       sourceApplication = query.valueString(0);\r
+               }\r
+               if (sourceApplication == null) \r
+                       return "";\r
+               \r
+               String consumerKey = "baumgarte:{";\r
+               int startPos = sourceApplication.indexOf(consumerKey);\r
+               if (startPos < 0 )\r
+                               return sourceApplication;\r
+               String startString = sourceApplication.substring(0,startPos);\r
+               String metaString = sourceApplication.substring(startPos);\r
+               String endString = metaString.substring(metaString.indexOf("};")+2);\r
+\r
+               return startString+endString;\r
+       }\r
+\r
 }      \r
 \r
 \r
index 16286e6..68dbd02 100644 (file)
@@ -1292,7 +1292,7 @@ public class SyncRunner extends QObject implements Runnable {
                                \r
                        if ((conflictingNote || fullSync) && !ignoreNote) {\r
                                logger.log(logger.EXTREME, "Saving Note");\r
-                               conn.getNoteTable().syncNote(n, false);\r
+                               conn.getNoteTable().syncNote(n);\r
                                // The following was commented out because it caused a race condition on the database where resources \r
                                // may be lost.  We do the same thing elsewhere;.\r
 //                             noteSignal.noteChanged.emit(n.getGuid(), null);   // Signal to ivalidate note cache \r
index 323a861..49036c1 100644 (file)
@@ -372,7 +372,7 @@ public class ListManager  {
                refreshNoteMetadata();\r
        }\r
        public void refreshNoteMetadata() {\r
-               noteModel.setNoteMetadata(conn.getNoteTable().getNoteMetaInformation());\r
+               noteModel.setNoteMetadata(conn.getNoteTable().getNotesMetaInformation());\r
        }\r
        // Update a note's meta data\r
        public void updateNoteMetadata(NoteMetadata meta) {\r
@@ -596,7 +596,7 @@ public class ListManager  {
                                i=getNoteIndex().size();\r
                        }\r
                }\r
-               conn.getNoteTable().updateNote(n, true);\r
+               conn.getNoteTable().updateNote(n);\r
        }\r
        // Add a note.  \r
        public void addNote(Note n, NoteMetadata meta) {\r
@@ -1132,8 +1132,12 @@ public class ListManager  {
        }\r
        \r
        public void updateNoteTitleColor(String guid, Integer color) {\r
-               noteModel.updateNoteTitleColor(guid, color);\r
-               conn.getNoteTable().setNoteTitleColor(guid, color);\r
+               NoteMetadata meta = getNoteMetadata().get(guid);\r
+               if (meta != null) {\r
+                       noteModel.updateNoteTitleColor(guid, color);\r
+                       meta.setColor(color);\r
+                       conn.getNoteTable().updateNoteMetadata(meta);\r
+               }\r
        }\r
        public void loadNoteTitleColors() {\r
                noteModel.setMetaData(getNoteMetadata());\r
index a15ad8d..20161d9 100644 (file)
@@ -148,7 +148,7 @@ public class ExportData {
                dirtyNotes.put(dn.get(i).getGuid(), "");\r
        }\r
        \r
-       noteMeta = conn.getNoteTable().getNoteMetaInformation();\r
+       noteMeta = conn.getNoteTable().getNotesMetaInformation();\r
 \r
        \r
        searches = conn.getSavedSearchTable().getAll();\r
index 8070b9a..9e95bab 100644 (file)
@@ -45,6 +45,7 @@ import com.trolltech.qt.gui.QPixmap;
 import com.trolltech.qt.xml.QXmlStreamAttributes;\r
 import com.trolltech.qt.xml.QXmlStreamReader;\r
 \r
+import cx.fbn.nevernote.evernote.NoteMetadata;\r
 import cx.fbn.nevernote.sql.DatabaseConnection;\r
 import cx.fbn.nevernote.utilities.ApplicationLogger;\r
 \r
@@ -64,7 +65,7 @@ public class ImportData {
        private QIcon                                           notebookIcon;\r
        private Tag                                                     tag;\r
        private boolean                                         tagIsDirty;\r
-       private final HashMap<String,Integer>           titleColors;\r
+//     private final HashMap<String,Integer>           titleColors;\r
        private SavedSearch                                     search;\r
        private boolean                                         searchIsDirty;\r
        public int                                                      highUpdateSequenceNumber;\r
@@ -79,12 +80,13 @@ public class ImportData {
        public final boolean                            importTags = false;\r
        public final boolean                            importNotebooks = false;\r
        private final HashMap<String,String>            noteMap;\r
+       private final HashMap<String, NoteMetadata> metaData;\r
        \r
        public ImportData(DatabaseConnection c, boolean full) {\r
                logger = new ApplicationLogger("import.log");\r
                backup = full;\r
                conn = c;\r
-               titleColors = new HashMap<String,Integer>();\r
+               metaData = new HashMap<String,NoteMetadata>();\r
                noteMap = new HashMap<String,String>();\r
        }\r
        \r
@@ -157,8 +159,8 @@ public class ImportData {
                                        }\r
                                        conn.getNoteTable().addNote(note, true);\r
                                }\r
-                               if (titleColors.containsKey(note.getGuid())) \r
-                                       conn.getNoteTable().setNoteTitleColor(note.getGuid(), titleColors.get(note.getGuid()));\r
+                               if (metaData.containsKey(note.getGuid())) \r
+                                       conn.getNoteTable().updateNoteMetadata(metaData.get(note.getGuid()));\r
                        }\r
                        if (reader.name().equalsIgnoreCase("notebook") && reader.isStartElement() && (backup || importNotebooks)) {\r
                                processNotebookNode();\r
@@ -245,8 +247,14 @@ public class ImportData {
                                        if (booleanValue())\r
                                                noteIsDirty=true;\r
                                }\r
-                               if (reader.name().equalsIgnoreCase("TitleColor")) \r
-                                       titleColors.put(note.getGuid(), intValue());\r
+                               if (reader.name().equalsIgnoreCase("TitleColor")) {\r
+                                       if (metaData.get(note.getGuid()) == null) {\r
+                                               NoteMetadata m = new NoteMetadata();\r
+                                               m.setColor(intValue());\r
+                                               metaData.put(note.getGuid(), m);\r
+                                       } else\r
+                                               metaData.get(note.getGuid()).setColor(intValue());\r
+                               }\r
                        }\r
                        reader.readNext();\r
                        if (reader.name().equalsIgnoreCase("note") && reader.isEndElement())\r