}
private void resolveConflicts(Map<String, Syncable> database, Map<String, Syncable> clientChanges, Map<String, Syncable> resultingDatabase, Map<String, Syncable> resultingClientChanges, boolean merge) throws Exception {
// Determine what to write to database.
for (Syncable syncable : database.values()) {
Syncable copy = syncable.getClass().newInstance();
copy.copy(syncable);
copy.setChangeType(ChangeType.NONE);
resultingDatabase.put(copy.getGuid(), copy);
}
for (String guid : clientChanges.keySet()) {
Syncable clientSyncable = clientChanges.get(guid);
Syncable databaseSyncable = database.get(guid);
switch (clientSyncable.getChangeType()) {
case ChangeType.NONE: {
if (merge) {
if (databaseSyncable == null) {
Syncable copy = clientSyncable.getClass().newInstance();
copy.copy(clientSyncable);
copy.setChangeType(ChangeType.NONE);
resultingDatabase.put(guid, copy);
}
}
break;
}
case ChangeType.ADDED: {
Syncable copy = clientSyncable.getClass().newInstance();
copy.copy(clientSyncable);
copy.setChangeType(ChangeType.NONE);
resultingDatabase.put(guid, copy);
break;
}
case ChangeType.EDITED: {
Syncable copy = clientSyncable.getClass().newInstance();
copy.copy(clientSyncable);
copy.setChangeType(ChangeType.NONE);
resultingDatabase.put(guid, copy);
break;
}
case ChangeType.DELETED: {
// Remove from database. Conflict. Client and server: DELETED/NONE, DELETED/DELETED (remove)
if (databaseSyncable == null || databaseSyncable.getChangeType() == ChangeType.NONE || databaseSyncable.getChangeType() == ChangeType.DELETED) {
resultingDatabase.remove(guid);
}
break;
}
default: {
break;
}
}
}
// Determine what to write to client.
for (String guid : database.keySet()) {
Syncable databaseSyncable = database.get(guid);
Syncable clientSyncable = clientChanges.get(guid);
switch (databaseSyncable.getChangeType()) {
case ChangeType.NONE: {
if (merge) {
if (clientSyncable == null) {
Syncable copy = databaseSyncable.getClass().newInstance();
copy.copy(databaseSyncable);
copy.setChangeType(ChangeType.ADDED);
resultingClientChanges.put(guid, copy);
}
}
break;
}
case ChangeType.ADDED: {
// Send editions to client. Conflict. Client and server: NONE/ADDED, DELETED/ADDED (send)
if (clientSyncable == null || clientSyncable.getChangeType() == ChangeType.NONE || clientSyncable.getChangeType() == ChangeType.DELETED) {
Syncable copy = databaseSyncable.getClass().newInstance();
copy.copy(databaseSyncable);
resultingClientChanges.put(guid, copy);
}
break;
}
case ChangeType.EDITED: {
// Send editions to client. Conflict. Client and server: NONE/EDITED, DELETED/EDITED (send)
if (clientSyncable == null || clientSyncable.getChangeType() == ChangeType.NONE || clientSyncable.getChangeType() == ChangeType.DELETED) {
Syncable copy = databaseSyncable.getClass().newInstance();
copy.copy(databaseSyncable);
resultingClientChanges.put(guid, copy);
}
break;
}
case ChangeType.DELETED: {
// Send editions to client. Conflict. Client and server: NONE/DELETED, DELETED/DELETED (send)
if (clientSyncable == null || clientSyncable.getChangeType() == ChangeType.NONE || clientSyncable.getChangeType() == ChangeType.DELETED) {
Syncable copy = databaseSyncable.getClass().newInstance();
copy.copy(databaseSyncable);
resultingClientChanges.put(guid, copy);
resultingDatabase.remove(guid);
}
break;
}