X-Git-Url: http://git.nikiroo.be/?p=jvcard.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Fjvcard%2Fremote%2FSync.java;h=d382a2fc626fae9870648a381793d4a4893d6a1f;hp=9fff9b8985056039e42c14c51dfb7013efb1412f;hb=0b6140e4a200c4952c9dc003d8389f375191564e;hpb=cf77cb3542f2aefbebdb9aa00b358dbeb4489a73 diff --git a/src/be/nikiroo/jvcard/remote/Sync.java b/src/be/nikiroo/jvcard/remote/Sync.java index 9fff9b8..d382a2f 100644 --- a/src/be/nikiroo/jvcard/remote/Sync.java +++ b/src/be/nikiroo/jvcard/remote/Sync.java @@ -12,14 +12,16 @@ import java.io.OutputStreamWriter; import java.net.Socket; import java.net.UnknownHostException; import java.security.InvalidParameterException; -import java.time.LocalDate; +import java.util.LinkedList; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; import be.nikiroo.jvcard.Card; +import be.nikiroo.jvcard.Contact; +import be.nikiroo.jvcard.Data; import be.nikiroo.jvcard.parsers.Format; -import be.nikiroo.jvcard.parsers.Parser; +import be.nikiroo.jvcard.parsers.Vcard21Parser; import be.nikiroo.jvcard.remote.Command.Verb; import be.nikiroo.jvcard.resources.Bundles; import be.nikiroo.jvcard.tui.StringUtils; @@ -189,9 +191,11 @@ public class Sync { // Check changes boolean serverChanges = (tsServer - tsOriginal) > GRACE_TIME; boolean localChanges = false; + Card local = null; + Card original = null; if (tsOriginal != -1) { - Card local = new Card(getCache(cacheDir), Format.VCard21); - Card original = new Card(getCache(cacheDirOrig), Format.VCard21); + local = new Card(getCache(cacheDir), Format.VCard21); + original = new Card(getCache(cacheDirOrig), Format.VCard21); localChanges = !local.isEquals(original, true); } @@ -199,24 +203,28 @@ public class Sync { // Sync to server if: if (localChanges) { - // TODO: sync instead (with PUT) - action = Verb.POST; + action = Verb.PUT_CARD; } - // Sync from server if + // Sync from/to server if if (serverChanges && localChanges) { - // TODO - throw new IOException("Sync operation not supported yet :("); + action = Verb.PUT_CARD; + } + + // Sync from server if: + if (serverChanges) { + // TODO: only sends changed cstate if serverChanges + action = Verb.GET_CARD; } // PUT the whole file if: if (tsServer == -1) { - action = Verb.POST; + action = Verb.POST_CARD; } // GET the whole file if: - if (tsOriginal == -1 || serverChanges) { - action = Verb.GET; + if (tsOriginal == -1) { + action = Verb.GET_CARD; } System.err.println("remote: " + (tsServer / 1000) % 1000 + " (" @@ -229,23 +237,57 @@ public class Sync { if (action != null) { switch (action) { - case GET: - s.sendCommand(Verb.GET, name); + case GET_CARD: + s.sendCommand(Verb.GET_CARD, name); List data = s.receiveBlock(); setLastModified(data.remove(0)); - Card server = new Card(Parser.parse(data, Format.VCard21)); + Card server = new Card(Vcard21Parser.parseContact(data)); card.replaceListContent(server); if (card.isDirty()) card.save(); card.saveAs(getCache(cacheDirOrig), Format.VCard21); break; - case POST: - s.sendCommand(Verb.POST, name); - s.sendLine(card.toString(Format.VCard21)); + case POST_CARD: + s.sendCommand(Verb.POST_CARD, name); + s.sendBlock(Vcard21Parser.toStrings(card)); card.saveAs(getCache(cacheDirOrig), Format.VCard21); setLastModified(s.receiveLine()); break; + case PUT_CARD: + List added = new LinkedList(); + List removed = new LinkedList(); + List from = new LinkedList(); + List to = new LinkedList(); + original.compare(local, added, removed, from, to); + s.sendCommand(Verb.PUT_CARD, name); + for (Contact c : removed) { + s.sendCommand(Verb.DELETE_CONTACT, c.getId()); + } + for (Contact c : added) { + s.sendCommand(Verb.POST_CONTACT, c.getId()); + s.sendBlock(Vcard21Parser.toStrings(c, -1)); + } + if (from.size() > 0) { + for (int index = 0; index < from.size(); index++) { + Contact f = from.get(index); + Contact t = to.get(index); + + List subadded = new LinkedList(); + List subremoved = new LinkedList(); + f.compare(t, subadded, subremoved, subremoved, subadded); + s.sendCommand(Verb.PUT_CONTACT, name); + for (Data d : subremoved) { + s.sendCommand(Verb.DELETE_DATA, d.getContentState()); + } + for (Data d : subadded) { + s.sendCommand(Verb.POST_DATA, d.getContentState()); + s.sendBlock(Vcard21Parser.toStrings(d)); + } + } + } + s.sendCommand(Verb.PUT_CARD); + break; default: // TODO throw new IOException(action