import java.util.Date;\r
import java.util.GregorianCalendar;\r
import java.util.List;\r
+import java.util.TreeSet;\r
import java.util.Vector;\r
import java.util.concurrent.LinkedBlockingQueue;\r
\r
private THttpClient userStoreTrans;\r
private TBinaryProtocol userStoreProt;\r
private AuthenticationResult authResult;\r
+ private AuthenticationResult linkedAuthResult;\r
private User user; \r
private long authTimeRemaining;\r
public long authRefreshTime;\r
public int updateSequenceNumber;\r
private boolean refreshNeeded;\r
private volatile LinkedBlockingQueue<String> workQueue;\r
-// private static int MAX_EMPTY_QUEUE_COUNT = 1;\r
private static int MAX_QUEUED_WAITING = 1000;\r
String dbuid;\r
String dburl;\r
+ String indexUrl;\r
+ String resourceUrl;\r
String dbpswd;\r
String dbcpswd;\r
+ private final TreeSet<String> ignoreTags;\r
+ private final TreeSet<String> ignoreNotebooks;\r
+ private final TreeSet<String> ignoreLinkedNotebooks;\r
\r
\r
\r
- public SyncRunner(String logname, String u, String uid, String pswd, String cpswd) {\r
+ public SyncRunner(String logname, String u, String i, String r, String uid, String pswd, String cpswd) {\r
logger = new ApplicationLogger(logname);\r
\r
noteSignal = new NoteSignal();\r
searchSignal = new SavedSearchSignal();\r
syncSignal = new SyncSignal();\r
resourceSignal = new NoteResourceSignal();\r
+ resourceUrl = r;\r
+ indexUrl = i;\r
dbuid = uid;\r
dburl = u;\r
dbpswd = pswd;\r
authRefreshNeeded = false;\r
keepRunning = true;\r
idle = true;\r
- noteStore = null;\r
- userStore = null;\r
- authToken = null;\r
disableUploads = false;\r
+ ignoreTags = new TreeSet<String>();\r
+ ignoreNotebooks = new TreeSet<String>();\r
+ ignoreLinkedNotebooks = new TreeSet<String>();\r
+ \r
// setAutoDelete(false);\r
workQueue=new LinkedBlockingQueue<String>(MAX_QUEUED_WAITING);\r
}\r
public void run() {\r
try {\r
logger.log(logger.EXTREME, "Starting thread");\r
- conn = new DatabaseConnection(logger, dburl, dbuid, dbpswd, dbcpswd);\r
+ conn = new DatabaseConnection(logger, dburl, indexUrl, resourceUrl, dbuid, dbpswd, dbcpswd, 200);\r
while(keepRunning) {\r
String work = workQueue.take();\r
logger.log(logger.EXTREME, "Work found: " +work);\r
return;\r
idle=false;\r
error=false;\r
- if (authRefreshNeeded == true) {\r
+ if (authRefreshNeeded == true || !isConnected) {\r
logger.log(logger.EXTREME, "Refreshing connection");\r
refreshConnection();\r
}\r
status.message.emit(e.getMessage());\r
}\r
}\r
- dirtyNoteGuids = null;\r
idle=true;\r
logger.log(logger.EXTREME, "Signaling refresh finished. refreshNeeded=" +refreshNeeded);\r
syncSignal.finished.emit(refreshNeeded);\r
+ if (error) {\r
+ syncSignal.errorDisconnect.emit();\r
+ status.message.emit(tr("Error synchronizing - see log for details."));\r
+ }\r
}\r
} \r
catch (InterruptedException e1) {\r
@SuppressWarnings("unused")\r
private void evernoteSync() throws java.net.UnknownHostException {\r
logger.log(logger.HIGH, "Entering SyncRunner.evernoteSync");\r
+ \r
+ // Rebuild list of tags & notebooks to ignore\r
+ ignoreNotebooks.clear();\r
+ List<String> ignore = conn.getSyncTable().getIgnoreRecords("NOTEBOOK");\r
+ for (int i=0; i<ignore.size(); i++) \r
+ ignoreNotebooks.add(ignore.get(i));\r
+ \r
+ ignore.clear();\r
+ ignore = conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK");\r
+ for (int i=0; i<ignore.size(); i++) \r
+ ignoreLinkedNotebooks.add(ignore.get(i));\r
+ \r
+ ignoreTags.clear();\r
+ ignore = conn.getSyncTable().getIgnoreRecords("TAG");\r
+ for (int i=0; i<ignore.size(); i++) \r
+ ignoreTags.add(ignore.get(i));\r
\r
+ // Make sure we are connected & should keep running\r
if (isConnected && keepRunning) {\r
error = false;\r
logger.log(logger.EXTREME, "Synchronizing with Evernote");\r
e1.printStackTrace();\r
status.message.emit(tr("User exception getting user account information. Aborting sync and disconnecting"));\r
syncSignal.errorDisconnect.emit();\r
+ error = true;\r
enDisconnect();\r
return;\r
} catch (EDAMSystemException e1) {\r
e1.printStackTrace();\r
status.message.emit(tr("System error user account information. Aborting sync and disconnecting!"));\r
syncSignal.errorDisconnect.emit();\r
+ error = true;\r
enDisconnect();\r
return;\r
} catch (TException e1) {\r
e1.printStackTrace();\r
syncSignal.errorDisconnect.emit();\r
+ error = true;\r
status.message.emit(tr("Transaction error getting user account information. Aborting sync and disconnecting!"));\r
enDisconnect();\r
return;\r
if (syncInkNoteImages != null) {\r
List<String> guids = conn.getNoteTable().noteResourceTable.findInkNotes();\r
for (int i=0; i<guids.size(); i++) {\r
- downloadInkNoteImage(guids.get(i));\r
+ downloadInkNoteImage(guids.get(i), authToken);\r
}\r
conn.getSyncTable().deleteRecord("FullInkNoteImageSync");\r
}\r
syncRemoteToLocal();\r
}\r
\r
+ //*****************************************\r
+ //* Sync linked/shared notebooks \r
+ //*****************************************\r
+ syncLinkedNotebooks();\r
+ \r
if (!disableUploads) {\r
logger.log(logger.EXTREME, "Uploading changes");\r
// Synchronize remote changes\r
syncLocalTags();\r
if (!error)\r
syncLocalNotebooks();\r
+ if (!error)\r
+ syncLocalLinkedNotebooks();\r
if (!error) \r
syncDeletedNotes();\r
if (!error)\r
if (!error)\r
syncLocalSavedSearches();\r
}\r
+ \r
+ status.message.emit(tr("Cleaning up"));\r
+ List<String> notes = conn.getNoteTable().expungeIgnoreSynchronizedNotes(conn.getSyncTable().getIgnoreRecords("NOTEBOOK"), \r
+ conn.getSyncTable().getIgnoreRecords("TAG"), conn.getSyncTable().getIgnoreRecords("LINKEDNOTEBOOK"));\r
+ if (notes.size() > 0)\r
+ syncSignal.refreshLists.emit();\r
+ \r
+ //*****************************************\r
+ //* End of synchronization\r
+ //*****************************************\r
if (refreshNeeded)\r
syncSignal.refreshLists.emit();\r
\r
for (int i=0; i<expunged.size() && keepRunning; i++) {\r
\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
try {\r
if (expunged.get(i).type.equalsIgnoreCase("TAG")) {\r
for (int i=0; i<notes.size() && keepRunning; i++) {\r
\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
Note enNote = notes.get(i);\r
try {\r
List<Note> notes = conn.getNoteTable().getDirty();\r
// Sync the local notebooks with Evernote's\r
for (int i=0; i<notes.size() && keepRunning; i++) {\r
+ syncLocalNote(notes.get(i), authToken);\r
+ }\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+\r
+ }\r
+ // Sync notes with Evernote\r
+ private void syncLocalNote(Note enNote, String token) {\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+ status.message.emit(tr("Sending local notes."));\r
+\r
+ if (authRefreshNeeded)\r
+ if (!refreshConnection())\r
+ return;\r
\r
- if (authRefreshNeeded)\r
- refreshConnection();\r
- \r
- Note enNote = notes.get(i);\r
- if (enNote.isActive()) {\r
- try {\r
- logger.log(logger.EXTREME, "Active dirty note found - non new");\r
- if (enNote.getUpdateSequenceNum() > 0) {\r
- enNote = getNoteContent(enNote);\r
- logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- enNote = noteStore.updateNote(authToken, enNote);\r
- } else { \r
- logger.log(logger.EXTREME, "Active dirty found - new note");\r
- logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
- String oldGuid = enNote.getGuid();\r
- enNote = getNoteContent(enNote);\r
- enNote = noteStore.createNote(authToken, enNote);\r
- noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());\r
- conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());\r
- }\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Saving note");\r
- conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
- List<Resource> rl = enNote.getResources();\r
- logger.log(logger.EXTREME, "Getting note resources");\r
- for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {\r
- Resource newRes = rl.get(j);\r
- Data d = newRes.getData();\r
- if (d!=null) { \r
- logger.log(logger.EXTREME, "Calculating resource hash");\r
- String hash = byteArrayToHexString(d.getBodyHash());\r
- logger.log(logger.EXTREME, "updating resources by hash");\r
- String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);\r
- conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);\r
- resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());\r
- }\r
+ if (enNote.isActive()) {\r
+ try {\r
+ logger.log(logger.EXTREME, "Active dirty note found - non new");\r
+ if (enNote.getUpdateSequenceNum() > 0) {\r
+ enNote = getNoteContent(enNote);\r
+ logger.log(logger.MEDIUM, "Updating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
+ enNote = noteStore.updateNote(token, enNote);\r
+ } else { \r
+ logger.log(logger.EXTREME, "Active dirty found - new note");\r
+ logger.log(logger.MEDIUM, "Creating note : "+ enNote.getGuid() +" <title>" +enNote.getTitle()+"</title>");\r
+ String oldGuid = enNote.getGuid();\r
+ enNote = getNoteContent(enNote);\r
+ enNote = noteStore.createNote(token, enNote);\r
+ noteSignal.guidChanged.emit(oldGuid, enNote.getGuid());\r
+ conn.getNoteTable().updateNoteGuid(oldGuid, enNote.getGuid());\r
+ }\r
+ updateSequenceNumber = enNote.getUpdateSequenceNum();\r
+ logger.log(logger.EXTREME, "Saving note");\r
+ conn.getNoteTable().updateNoteSequence(enNote.getGuid(), enNote.getUpdateSequenceNum());\r
+ List<Resource> rl = enNote.getResources();\r
+ logger.log(logger.EXTREME, "Getting note resources");\r
+ for (int j=0; j<enNote.getResourcesSize() && keepRunning; j++) {\r
+ Resource newRes = rl.get(j);\r
+ Data d = newRes.getData();\r
+ if (d!=null) { \r
+ logger.log(logger.EXTREME, "Calculating resource hash");\r
+ String hash = byteArrayToHexString(d.getBodyHash());\r
+ logger.log(logger.EXTREME, "updating resources by hash");\r
+ String oldGuid = conn.getNoteTable().noteResourceTable.getNoteResourceGuidByHashHex(enNote.getGuid(), hash);\r
+ conn.getNoteTable().updateNoteResourceGuidbyHash(enNote.getGuid(), newRes.getGuid(), hash);\r
+ resourceSignal.resourceGuidChanged.emit(enNote.getGuid(), oldGuid, newRes.getGuid());\r
}\r
- logger.log(logger.EXTREME, "Resetting note dirty flag");\r
- conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
- updateSequenceNumber = enNote.getUpdateSequenceNum();\r
- logger.log(logger.EXTREME, "Emitting note sequence number change");\r
- conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
-\r
- } catch (EDAMUserException e) {\r
- logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e.getParameter());\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMSystemException e) {\r
- logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (EDAMNotFoundException e) {\r
- logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
- } catch (TException e) {\r
- logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
- status.message.emit(tr("Error sending local note: ") +e);\r
- logger.log(logger.LOW, e.toString()); \r
- error = true;\r
}\r
+ logger.log(logger.EXTREME, "Resetting note dirty flag");\r
+ conn.getNoteTable().resetDirtyFlag(enNote.getGuid());\r
+ updateSequenceNumber = enNote.getUpdateSequenceNum();\r
+ logger.log(logger.EXTREME, "Emitting note sequence number change");\r
+ conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
+\r
+ } catch (EDAMUserException e) {\r
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error sending local note: ") +e.getParameter());\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (EDAMSystemException e) {\r
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (EDAMNotFoundException e) {\r
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalNotes " +e);\r
+ status.message.emit(tr("Error sending local note: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ } catch (TException e) {\r
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalNotes "+e);\r
+ status.message.emit(tr("Error sending local note: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
}\r
}\r
- logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalNote");\r
\r
}\r
+\r
// Sync Notebooks with Evernote\r
private void syncLocalNotebooks() {\r
logger.log(logger.HIGH, "Entering SyncRunner.syncLocalNotebooks");\r
for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
Notebook enNotebook = notebooks.get(i);\r
try {\r
Tag enTag = findNextTag();\r
while(enTag!=null) {\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
try {\r
if (enTag.getUpdateSequenceNum() > 0) {\r
}\r
logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalTags");\r
}\r
- // Sync Tags with Evernote\r
+ private void syncLocalLinkedNotebooks() {\r
+ logger.log(logger.HIGH, "Entering SyncRunner.syncLocalLinkedNotebooks");\r
+ \r
+ List<String> list = conn.getLinkedNotebookTable().getDirtyGuids();\r
+ for (int i=0; i<list.size(); i++) {\r
+ LinkedNotebook book = conn.getLinkedNotebookTable().getNotebook(list.get(i));\r
+ try {\r
+ noteStore.updateLinkedNotebook(authToken, book);\r
+ } catch (EDAMUserException e) {\r
+ logger.log(logger.LOW, "*** EDAM User Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ logger.log(logger.LOW, "*** EDAM Not Found Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ logger.log(logger.LOW, "*** EDAM System Excepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ logger.log(logger.LOW, "*** EDAM TExcepton syncLocalLinkedNotebooks");\r
+ status.message.emit(tr("Error: ") +e);\r
+ logger.log(logger.LOW, e.toString()); \r
+ error = true;\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ logger.log(logger.HIGH, "Leaving SyncRunner.syncLocalLinkedNotebooks");\r
+ }\r
+ // Sync Saved Searches with Evernote\r
private void syncLocalSavedSearches() {\r
logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");\r
List<SavedSearch> remoteList = new ArrayList<SavedSearch>();\r
for (int i=0; i<searches.size() && keepRunning; i++) {\r
\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
SavedSearch enSearch = searches.get(i);\r
try {\r
error = true;\r
} \r
}\r
+\r
logger.log(logger.HIGH, "Entering SyncRunner.syncLocalSavedSearches");\r
} \r
\r
while(more && keepRunning) {\r
\r
if (authRefreshNeeded)\r
- refreshConnection();\r
+ if (!refreshConnection())\r
+ return;\r
\r
- chunk = null;\r
int sequence = updateSequenceNumber;\r
try {\r
+// conn.beginTransaction();\r
logger.log(logger.EXTREME, "Getting chunk from Evernote");\r
chunk = noteStore.getSyncChunk(authToken, sequence, chunkSize, fullSync);\r
} catch (EDAMUserException e) {\r
syncRemoteTags(chunk.getTags());\r
syncRemoteSavedSearches(chunk.getSearches());\r
syncRemoteNotebooks(chunk.getNotebooks());\r
- syncRemoteNotes(chunk.getNotes(), fullSync);\r
+ syncRemoteNotes(chunk.getNotes(), fullSync, authToken);\r
syncRemoteResources(chunk.getResources());\r
syncRemoteLinkedNotebooks(chunk.getLinkedNotebooks());\r
+ syncExpungedNotes(chunk);\r
\r
- // Do the local deletes\r
- logger.log(logger.EXTREME, "Doing local deletes");\r
- List<String> guid = chunk.getExpungedNotes();\r
- if (guid != null) {\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- String notebookGuid = "";\r
- Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);\r
- if (localNote != null) {\r
- conn.getNoteTable().updateNoteSequence(guid.get(i), 0);\r
- notebookGuid = localNote.getNotebookGuid();\r
- }\r
- if (!conn.getNotebookTable().isNotebookLocal(notebookGuid)) {\r
- logger.log(logger.EXTREME, "Expunging local note from database");\r
- conn.getNoteTable().expungeNote(guid.get(i), true, false);\r
- }\r
- }\r
- }\r
- guid = chunk.getExpungedNotebooks();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging local notebook from database");\r
- conn.getNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedTags();\r
- if (guid != null)\r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging tags from local database");\r
- conn.getTagTable().expungeTag(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedSearches();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging saved search from local database");\r
- conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);\r
- }\r
- guid = chunk.getExpungedLinkedNotebooks();\r
- if (guid != null) \r
- for (int i=0; i<guid.size() && keepRunning; i++) {\r
- logger.log(logger.EXTREME, "Expunging linked notebook from local database");\r
- conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);\r
- }\r
-\r
\r
// Check for more notes\r
if (chunk.getChunkHighUSN() <= updateSequenceNumber) \r
\r
\r
// Save the chunk sequence number\r
- if (!error && chunk.getChunkHighUSN() > 0) {\r
+ if (!error && chunk.getChunkHighUSN() > 0 && keepRunning) {\r
logger.log(logger.EXTREME, "emitting sequence number to main thread");\r
updateSequenceNumber = chunk.getChunkHighUSN();\r
conn.getSyncTable().setLastSequenceDate(chunk.getCurrentTime());\r
conn.getSyncTable().setUpdateSequenceNumber(updateSequenceNumber);\r
+// conn.commitTransaction();\r
}\r
\r
\r
pct = pct/evernoteUpdateCount;\r
status.message.emit(tr("Downloading ") +new Long(pct).toString()+tr("% complete."));\r
}\r
+// conn.commitTransaction();\r
}\r
-\r
logger.log(logger.HIGH, "Leaving SyncRunner.syncRemoteToLocal");\r
}\r
+ // Sync expunged notes\r
+ private void syncExpungedNotes(SyncChunk chunk) {\r
+ // Do the local deletes\r
+ logger.log(logger.EXTREME, "Doing local deletes");\r
+ List<String> guid = chunk.getExpungedNotes();\r
+ if (guid != null) {\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ String notebookGuid = "";\r
+ Note localNote = conn.getNoteTable().getNote(guid.get(i), false, false, false, false, false);\r
+ if (localNote != null) {\r
+ conn.getNoteTable().updateNoteSequence(guid.get(i), 0);\r
+ notebookGuid = localNote.getNotebookGuid();\r
+ }\r
+ if (!conn.getNotebookTable().isNotebookLocal(notebookGuid)) {\r
+ logger.log(logger.EXTREME, "Expunging local note from database");\r
+ conn.getNoteTable().expungeNote(guid.get(i), true, false);\r
+ }\r
+ }\r
+ }\r
+ guid = chunk.getExpungedNotebooks();\r
+ if (guid != null)\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging local notebook from database");\r
+ conn.getNotebookTable().expungeNotebook(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedTags();\r
+ if (guid != null)\r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging tags from local database");\r
+ conn.getTagTable().expungeTag(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedSearches();\r
+ if (guid != null) \r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging saved search from local database");\r
+ conn.getSavedSearchTable().expungeSavedSearch(guid.get(i), false);\r
+ }\r
+ guid = chunk.getExpungedLinkedNotebooks();\r
+ if (guid != null) \r
+ for (int i=0; i<guid.size() && keepRunning; i++) {\r
+ logger.log(logger.EXTREME, "Expunging linked notebook from local database");\r
+ conn.getLinkedNotebookTable().expungeNotebook(guid.get(i), false);\r
+ }\r
+\r
+ }\r
// Sync remote tags\r
private void syncRemoteTags(List<Tag> tags) {\r
logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
}\r
// Sync remote linked notebooks\r
private void syncRemoteLinkedNotebooks(List<LinkedNotebook> books) {\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncSavedSearches");\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncLinkedNotebooks");\r
if (books != null) {\r
for (int i=0; i<books.size() && keepRunning; i++) {\r
conn.getLinkedNotebookTable().updateNotebook(books.get(i), false); \r
}\r
}\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncSavedSearches");\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncLinkedNotebooks");\r
}\r
// Sync remote Notebooks 2\r
private void syncRemoteNotebooks(List<Notebook> notebooks) {\r
if (oldGuid != null && !conn.getNotebookTable().isNotebookLocal(oldGuid) && !notebooks.get(i).getGuid().equalsIgnoreCase(oldGuid))\r
conn.getNotebookTable().updateNotebookGuid(oldGuid, notebooks.get(i).getGuid());\r
conn.getNotebookTable().syncNotebook(notebooks.get(i), false); \r
+ \r
+ // Synchronize shared notebook information\r
+// if (notebooks.get(i).getSharedNotebookIdsSize() > 0) {\r
+// conn.getSharedNotebookTable().expungeNotebookByGuid(notebooks.get(i).getGuid(), false);\r
+// for (int j=0; j<notebooks.get(i).getSharedNotebookIdsSize(); j++) {\r
+// syncRemoteSharedNotebook(notebooks.get(i).getGuid(), notebooks.get(i).getSharedNotebookIds().get(j), authToken);\r
+// }\r
+// }\r
}\r
} \r
logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
}\r
+ // Sync remote shared notebook\r
+// private void syncRemoteSharedNotebook(String guid, Long id, String token) {\r
+// List<SharedNotebook> books = noteStore.getSharedNotebookByAuth(authToken);\r
+// }\r
// Sync remote Resources\r
private void syncRemoteResources(List<Resource> resource) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");\r
+ if (resource != null) {\r
+ for (int i=0; i<resource.size() && keepRunning; i++) {\r
+ syncRemoteResource(resource.get(i), authToken);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");\r
+ }\r
+ // Sync remote resource\r
+ private void syncRemoteResource(Resource resource, String authToken) {\r
// This is how the logic for this works.\r
// 1.) If the resource is not in the local database, we add it.\r
// 2.) If a copy of the resource is in the local database and the note isn't dirty, we update the local copy\r
// 3.) If a copy of the resource is in the local databbase and it is dirty and the hash doesn't match, we ignore it because there\r
// is a conflict. The note conflict should get a copy of the resource at that time.\r
\r
- logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteResources");\r
- if (resource != null) {\r
- for (int i=0; i<resource.size() && keepRunning; i++) {\r
- boolean saveNeeded = false;\r
-/* #1 */ Resource r = getEvernoteResource(resource.get(i).getGuid(), true,true,true);\r
- Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);\r
- if (l == null) {\r
- saveNeeded = true;\r
- } else {\r
-/* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());\r
- if (!isNoteDirty)\r
- saveNeeded = true;\r
- else {\r
-/* #3 */ String remoteHash = "";\r
- if (r != null && r.getData() != null && r.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(r.getData().getBodyHash());\r
- String localHash = "";\r
- if (l != null && l.getData() != null && l.getData().getBodyHash() != null)\r
- remoteHash = byteArrayToHexString(l.getData().getBodyHash());\r
- \r
- if (localHash.equalsIgnoreCase(remoteHash))\r
+ boolean saveNeeded = false;\r
+ /* #1 */ Resource r = getEvernoteResource(resource.getGuid(), true,true,true, authToken);\r
+ Resource l = conn.getNoteTable().noteResourceTable.getNoteResource(r.getGuid(), false);\r
+ if (l == null) {\r
saveNeeded = true;\r
- }\r
- }\r
- \r
- if (saveNeeded) \r
- conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);\r
+ } else {\r
+ /* #2 */ boolean isNoteDirty = conn.getNoteTable().isNoteDirty(r.getNoteGuid());\r
+ if (!isNoteDirty)\r
+ saveNeeded = true;\r
+ else {\r
+ /* #3 */ String remoteHash = "";\r
+ if (r != null && r.getData() != null && r.getData().getBodyHash() != null)\r
+ remoteHash = byteArrayToHexString(r.getData().getBodyHash());\r
+ String localHash = "";\r
+ if (l != null && l.getData() != null && l.getData().getBodyHash() != null)\r
+ remoteHash = byteArrayToHexString(l.getData().getBodyHash());\r
+ \r
+ if (localHash.equalsIgnoreCase(remoteHash))\r
+ saveNeeded = true;\r
+ }\r
+ }\r
+ \r
+ if (saveNeeded) \r
+ conn.getNoteTable().noteResourceTable.updateNoteResource(r, false);\r
+ if (r.getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
+ downloadInkNoteImage(r.getGuid(), authToken);\r
\r
- }\r
- }\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteResources");\r
}\r
- // Sync remote notebooks\r
- private void syncRemoteNotes(List<Note> note, boolean fullSync) {\r
+ // Sync remote notes\r
+ private void syncRemoteNotes(List<Note> note, boolean fullSync, String token) {\r
logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotes");\r
if (note != null) {\r
for (int i=0; i<note.size() && keepRunning; i++) {\r
- Note n = getEvernoteNote(note.get(i).getGuid(), true, fullSync, true,true);\r
- if (n!=null) {\r
- \r
- // Basically, this is how the sync logic for a note works.\r
- // If the remote note has changed and the local has not, we\r
- // accept the change.\r
- // If both the local & remote have changed but the sequence\r
- // numbers are the same, we don't accept the change. This\r
- // seems to happen when attachments are indexed by the server.\r
- // If both the local & remote have changed and the sequence numbers\r
- // are different we move the local copy to a local notebook (making sure\r
- // to copy all resources) and we accept the new one. \r
- boolean conflictingNote = true;\r
- logger.log(logger.EXTREME, "Checking for duplicate note " +n.getGuid());\r
- if (dirtyNoteGuids.contains(n.getGuid())) { \r
- logger.log(logger.EXTREME, "Conflict check beginning");\r
- conflictingNote = checkForConflict(n);\r
- logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);\r
- if (conflictingNote)\r
- moveConflictingNote(n.getGuid());\r
- }\r
- if (conflictingNote || fullSync) {\r
- logger.log(logger.EXTREME, "Saving Note");\r
- conn.getNoteTable().syncNote(n, false);\r
- noteSignal.noteChanged.emit(n.getGuid(), null); // Signal to ivalidate note cache\r
- noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index\r
- logger.log(logger.EXTREME, "Note Saved");\r
- if (fullSync && n.getResources() != null) {\r
- for (int q=0; q<n.getResources().size() && keepRunning; q++) {\r
- logger.log(logger.EXTREME, "Getting note resources.");\r
- conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);\r
- }\r
- }\r
+ Note n = getEvernoteNote(note.get(i).getGuid(), true, fullSync, true,true, token);\r
+ syncRemoteNote(n, fullSync, token);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");\r
+ }\r
+ private void syncRemoteNote(Note n, boolean fullSync, String token) {\r
+ if (n!=null) {\r
+ \r
+ // Basically, this is how the sync logic for a note works.\r
+ // If the remote note has changed and the local has not, we\r
+ // accept the change.\r
+ // If both the local & remote have changed but the sequence\r
+ // numbers are the same, we don't accept the change. This\r
+ // seems to happen when attachments are indexed by the server.\r
+ // If both the local & remote have changed and the sequence numbers\r
+ // are different we move the local copy to a local notebook (making sure\r
+ // to copy all resources) and we accept the new one. \r
+ boolean conflictingNote = true;\r
+ logger.log(logger.EXTREME, "Checking for duplicate note " +n.getGuid());\r
+ if (dirtyNoteGuids != null && dirtyNoteGuids.contains(n.getGuid())) { \r
+ logger.log(logger.EXTREME, "Conflict check beginning");\r
+ conflictingNote = checkForConflict(n);\r
+ logger.log(logger.EXTREME, "Conflict check results " +conflictingNote);\r
+ if (conflictingNote)\r
+ moveConflictingNote(n.getGuid());\r
+ }\r
+ boolean ignoreNote = false;\r
+ if (ignoreNotebooks.contains(n.getNotebookGuid()))\r
+ ignoreNote = true;\r
+ for (int i=0; i<n.getTagGuidsSize(); i++) {\r
+ if (ignoreTags.contains(n.getTagGuids().get(i))) {\r
+ ignoreNote = true;\r
+ i=n.getTagGuidsSize();\r
+ }\r
+ }\r
+ \r
+ if ((conflictingNote || fullSync) && !ignoreNote) {\r
+ logger.log(logger.EXTREME, "Saving Note");\r
+ conn.getNoteTable().syncNote(n, false);\r
+ noteSignal.noteChanged.emit(n.getGuid(), null); // Signal to ivalidate note cache\r
+ noteSignal.noteDownloaded.emit(n, true); // Signal to add note to index\r
+ logger.log(logger.EXTREME, "Note Saved");\r
+ if (fullSync && n.getResources() != null) {\r
+ for (int q=0; q<n.getResources().size() && keepRunning; q++) {\r
+ logger.log(logger.EXTREME, "Getting note resources.");\r
+ conn.getNoteTable().noteResourceTable.updateNoteResource(n.getResources().get(q), false);\r
+ if (n.getResources().get(q).getMime().equalsIgnoreCase("application/vnd.evernote.ink"))\r
+ downloadInkNoteImage(n.getResources().get(q).getGuid(), token);\r
}\r
}\r
}\r
}\r
- logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotes");\r
}\r
- private Note getEvernoteNote(String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData) { \r
+ private Note getEvernoteNote(String guid, boolean withContent, boolean withResourceData, boolean withResourceRecognition, boolean withResourceAlternateData, String token) { \r
Note n = null;\r
try {\r
logger.log(logger.EXTREME, "Retrieving note " +guid);\r
- n = noteStore.getNote(authToken, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);\r
+ n = noteStore.getNote(token, guid, withContent, withResourceData, withResourceRecognition, withResourceAlternateData);\r
logger.log(logger.EXTREME, "Note " +guid +" has been retrieved.");\r
} catch (EDAMUserException e) {\r
logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
}\r
return n;\r
}\r
- private Resource getEvernoteResource(String guid, boolean withData, boolean withRecognition, boolean withAttributes) { \r
+ private Resource getEvernoteResource(String guid, boolean withData, boolean withRecognition, boolean withAttributes, String token) { \r
Resource n = null;\r
try {\r
logger.log(logger.EXTREME, "Retrieving resource " +guid);\r
- n = noteStore.getResource(authToken, guid, withData, withRecognition, withAttributes, withAttributes);\r
+ n = noteStore.getResource(token, guid, withData, withRecognition, withAttributes, withAttributes);\r
logger.log(logger.EXTREME, "Resource " +guid +" has been retrieved.");\r
} catch (EDAMUserException e) {\r
logger.log(logger.LOW, "*** EDAM User Excepton getEvernoteNote");\r
newBook.setPublished(false);\r
\r
conn.getNotebookTable().addNotebook(newBook, false, true);\r
+ notebookSignal.listChanged.emit();\r
notebookGuid = newBook.getGuid();\r
+ refreshNeeded = true;\r
}\r
\r
// Now that we have a good notebook guid, we need to move the conflicting note\r
conn.getNoteTable().updateNoteGuid(guid, newGuid);\r
conn.getNoteTable().updateNoteNotebook(newGuid, notebookGuid, true);\r
\r
- \r
+ noteSignal.notebookChanged.emit(newGuid, notebookGuid);\r
+ refreshNeeded = true;\r
noteSignal.guidChanged.emit(guid,newGuid);\r
}\r
\r
- \r
+\r
\r
\r
//******************************************************\r
\r
boolean versionOk = false;\r
try {\r
-// versionOk = userStore.checkVersion("Dave's EDAMDemo (Java)", \r
versionOk = userStore.checkVersion("NeverNote", \r
com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR, \r
com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR);\r
isConnected = false;\r
}\r
// Refresh the connection\r
- private synchronized void refreshConnection() {\r
+ private synchronized boolean refreshConnection() {\r
logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()");\r
// Calendar cal = Calendar.getInstance();\r
\r
// If we are not connected let's get out of here\r
if (!isConnected)\r
- return;\r
+ return false;\r
\r
// If we fail too many times, then let's give up.\r
if (failedRefreshes >=5) {\r
logger.log(logger.EXTREME, "Refresh attempts have failed. Disconnecting.");\r
isConnected = false;\r
- return;\r
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
+ return false;\r
}\r
\r
// If this is the first time through, then we need to set this\r
if (userStore != null && authToken != null) \r
newAuth = userStore.refreshAuthentication(authToken); \r
else\r
- return;\r
+ return false;\r
logger.log(logger.EXTREME, "UserStore.refreshAuthentication has succeeded.");\r
} catch (EDAMUserException e) {\r
e.printStackTrace();\r
syncSignal.authRefreshComplete.emit(false);\r
failedRefreshes++;\r
- return;\r
+ return false;\r
} catch (EDAMSystemException e) {\r
e.printStackTrace();\r
syncSignal.authRefreshComplete.emit(false);\r
failedRefreshes++;\r
- return; \r
+ return false; \r
} catch (TException e) { \r
e.printStackTrace();\r
syncSignal.authRefreshComplete.emit(false);\r
failedRefreshes++;\r
- return;\r
+ return false;\r
}\r
\r
// If we didn't get a good auth, then we've failed\r
if (newAuth == null) {\r
failedRefreshes++;\r
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
logger.log(logger.EXTREME, "Authentication failure #" +failedRefreshes);\r
+ status.message.emit(tr("Unable to synchronize - Authentication failed"));\r
syncSignal.authRefreshComplete.emit(false);\r
- return;\r
+ return false;\r
}\r
\r
// We got a good token. Now we need to setup the time to renew it.\r
// failedRefreshes++;\r
// syncSignal.authRefreshComplete.emit(false);\r
// }\r
+ \r
+ return true;\r
}\r
\r
public synchronized boolean addWork(String request) {\r
}\r
\r
\r
- private void downloadInkNoteImage(String guid) {\r
+ private void downloadInkNoteImage(String guid, String authToken) {\r
String urlBase = noteStoreUrl.replace("/edam/note/", "/shard/") + "/res/"+guid+".ink?slice=";\r
// urlBase = "https://www.evernote.com/shard/s1/res/52b567a9-54ae-4a08-afc5-d5bae275b2a8.ink?slice=";\r
Integer slice = 1;\r
return data;\r
}\r
\r
+ \r
+ //******************************************\r
+ //* Begin syncing shared notebooks \r
+ //******************************************\r
+ private void syncLinkedNotebooks() {\r
+ logger.log(logger.MEDIUM, "Authenticating Shared Notebooks");\r
+ status.message.emit(tr("Synchronizing shared notebooks."));\r
+ List<LinkedNotebook> books = conn.getLinkedNotebookTable().getAll();\r
+\r
+ for (int i=0; i<books.size(); i++) {\r
+ try {\r
+ long lastSyncDate = conn.getLinkedNotebookTable().getLastSequenceDate(books.get(i).getGuid());\r
+ int lastSequenceNumber = conn.getLinkedNotebookTable().getLastSequenceNumber(books.get(i).getGuid());\r
+ linkedAuthResult = noteStore.authenticateToSharedNotebook(books.get(i).getShareKey(), authToken);\r
+ SyncState linkedSyncState = \r
+ noteStore.getLinkedNotebookSyncState(linkedAuthResult.getAuthenticationToken(), books.get(i));\r
+ if (linkedSyncState.getUpdateCount() > lastSequenceNumber) {\r
+ if (lastSyncDate < linkedSyncState.getFullSyncBefore()) {\r
+ lastSequenceNumber = 0;\r
+ } \r
+ syncLinkedNotebook(books.get(i), lastSequenceNumber, linkedSyncState.getUpdateCount());\r
+ }\r
+ \r
+ // Synchronize local changes\r
+ syncLocalLinkedNoteChanges(books.get(i));\r
+ \r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ status.message.emit(tr("Error synchronizing \" " +\r
+ books.get(i).getShareName()+"\". Please verify you still have access to that shared notebook."));\r
+ error = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ // Cleanup tags\r
+ conn.getTagTable().removeUnusedLinkedTags();\r
+ conn.getTagTable().cleanupTags();\r
+ tagSignal.listChanged.emit();\r
+ }\r
+\r
+ \r
+ //**************************************************************\r
+ //* Linked notebook contents (from someone else's account)\r
+ //*************************************************************\r
+ private void syncLinkedNotebook(LinkedNotebook book, int usn, int highSequence) {\r
+ \r
+ List<Note> dirtyNotes = conn.getNoteTable().getDirtyLinkedNotes();\r
+ if (dirtyNoteGuids == null) \r
+ dirtyNoteGuids = new Vector<String>();\r
+\r
+ for (int i=0; i<dirtyNotes.size() && keepRunning; i++) {\r
+ dirtyNoteGuids.add(dirtyNotes.get(i).getGuid());\r
+ }\r
+ boolean fullSync = false;\r
+ if (usn == 0)\r
+ fullSync = true;\r
+ while (usn < highSequence) {\r
+ try {\r
+ SyncChunk chunk = \r
+ noteStore.getLinkedNotebookSyncChunk(authToken, book, usn, 10, fullSync);\r
+\r
+ if (!ignoreLinkedNotebooks.contains(book.getGuid()))\r
+ syncRemoteNotes(chunk.getNotes(), fullSync, linkedAuthResult.getAuthenticationToken());\r
+ findNewLinkedTags(chunk.getNotes(), linkedAuthResult.getAuthenticationToken());\r
+ for (int i=0; i<chunk.getResourcesSize(); i++) {\r
+ syncRemoteResource(chunk.getResources().get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ syncRemoteLinkedNotebooks(chunk.getNotebooks(), false, book);\r
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ syncLinkedTags(chunk.getTags(), s.getNotebookGuid());\r
+ \r
+ \r
+ // Expunge records\r
+ for (int i=0; i<chunk.getExpungedLinkedNotebooksSize(); i++) {\r
+ conn.getLinkedNotebookTable().expungeNotebook(chunk.getExpungedLinkedNotebooks().get(i), false);\r
+ }\r
+ usn = chunk.getChunkHighUSN();\r
+ conn.getLinkedNotebookTable().setLastSequenceDate(book.getGuid(),chunk.getCurrentTime());\r
+ conn.getLinkedNotebookTable().setLastSequenceNumber(book.getGuid(),chunk.getChunkHighUSN());\r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ // Sync remote tags\r
+ private void syncLinkedTags(List<Tag> tags, String notebookGuid) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteTags");\r
+ if (tags != null) {\r
+ for (int i=0; i<tags.size() && keepRunning; i++) {\r
+ conn.getTagTable().syncLinkedTag(tags.get(i), notebookGuid, false);\r
+ }\r
+ }\r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteTags");\r
+ }\r
+ \r
+ // Sync notebooks from a linked notebook\r
+ private void syncRemoteLinkedNotebooks(List<Notebook> notebooks, boolean readOnly, LinkedNotebook linked) {\r
+ logger.log(logger.EXTREME, "Entering SyncRunner.syncRemoteNotebooks");\r
+ if (notebooks != null) {\r
+ for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
+ try {\r
+ SharedNotebook s = noteStore.getSharedNotebookByAuth(linkedAuthResult.getAuthenticationToken());\r
+ conn.getLinkedNotebookTable().setNotebookGuid(s.getShareKey(), s.getNotebookGuid());\r
+ readOnly = !s.isNotebookModifiable();\r
+ notebooks.get(i).setName(linked.getShareName());\r
+ notebooks.get(i).setDefaultNotebook(false);\r
+ conn.getNotebookTable().syncLinkedNotebook(notebooks.get(i), false, readOnly); \r
+ } catch (EDAMUserException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ readOnly = true;\r
+ e.printStackTrace();\r
+ }\r
+\r
+ }\r
+ } \r
+ logger.log(logger.EXTREME, "Leaving SyncRunner.syncRemoteNotebooks");\r
+ }\r
+\r
+ private void findNewLinkedTags(List<Note> newNotes, String token) {\r
+ if (newNotes == null)\r
+ return;\r
+ for (int i=0; i<newNotes.size(); i++) {\r
+ Note n = newNotes.get(i);\r
+ for (int j=0; j<n.getTagGuidsSize(); j++) {\r
+ String tag = n.getTagGuids().get(j);\r
+ if (!conn.getTagTable().exists(tag)) {\r
+ Tag newTag;\r
+ try {\r
+ newTag = noteStore.getTag(token, tag);\r
+ conn.getTagTable().addTag(newTag, false);\r
+ } catch (EDAMUserException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMSystemException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (EDAMNotFoundException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ } catch (TException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // Synchronize changes locally done to linked notes\r
+ private void syncLocalLinkedNoteChanges(LinkedNotebook book) {\r
+ String notebookGuid = conn.getLinkedNotebookTable().getNotebookGuid(book.getGuid());\r
+ List<Note> notes = conn.getNoteTable().getDirtyLinked(notebookGuid);\r
+ for (int i=0; i<notes.size(); i++) {\r
+ syncLocalNote(notes.get(i), linkedAuthResult.getAuthenticationToken());\r
+ }\r
+ }\r
+\r
}\r