package com.trechner.ksync4j;
import com.trechner.ksync4j.type.ChangeType;
import com.trechner.ksync4j.type.SyncType;
import com.trechner.ksync4j.type.Syncable;
import java.util.Vector;
import java.util.Enumeration;
/**
* Abstract sync client.
* <p/>
* Copyright (c) 2008 T-Rechner Ltd.
*
* @author Karl Tiller <karl@t-rechner.com>
* @see com.trechner.ksync4j.type.SyncType
*/
public abstract class AbstractSyncClient {
/**
* Synchronizes changes.
*
* @param syncType Sync type.
* @see com.trechner.ksync4j.type.SyncType
*/
public void sync(int syncType) {
switch (syncType) {
case SyncType.TWO_WAY:
syncTwoWay();
break;
case SyncType.SLOW:
syncSlow();
break;
case SyncType.ONE_WAY_FROM_CLIENT:
syncOneWayFromClient();
break;
case SyncType.REFRESH_FROM_CLIENT:
syncRefreshFromClient();
break;
case SyncType.ONE_WAY_FROM_SERVER:
syncOneWayFromServer();
break;
case SyncType.REFRESH_FROM_SERVER:
syncRefreshFromServer();
break;
}
}
/**
* Must clear storage.
*/
public abstract void clearStorage();
/**
* Must retrieve syncables from storage.
*
* @return Vector
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract Vector getSyncablesFromStorage();
/**
* Must add syncable to storage.
*
* @param syncable Syncable
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract void addSyncableToStorage(Syncable syncable);
/**
* Must replace syncable in storage.
*
* @param syncable Syncable
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract void replaceSyncableToStorage(Syncable syncable);
/**
* Must remove syncable from storage.
*
* @param syncable Syncable
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract void removeSyncableToStorage(Syncable syncable);
/**
* Must receive syncables from server.
*
* @return Vector
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract Vector receiveSyncablesFromServer();
/**
* Must send syncables to server.
*
* @param syncables Vector
* @see com.trechner.ksync4j.type.Syncable
*/
public abstract void sendSyncablesToServer(Vector syncables);
/**
* Must send command to start sync to server.
*
* @param syncType Sync type.
* @see com.trechner.ksync4j.type.SyncType
*/
public abstract void syncToServer(int syncType);
private void syncTwoWay() {
Vector storageSyncables = getSyncablesFromStorage();
sendSyncablesToServer(storageSyncables);
syncToServer(SyncType.TWO_WAY);
Vector serverSyncables = receiveSyncablesFromServer();
applyChangesToStorage(serverSyncables);
}
private void syncSlow() {
Vector storageSyncables = getSyncablesFromStorage();
sendSyncablesToServer(storageSyncables);
syncToServer(SyncType.SLOW);
Vector serverSyncables = receiveSyncablesFromServer();
applyChangesToStorage(serverSyncables);
}
private void syncOneWayFromClient() {
Vector storageSyncables = getSyncablesFromStorage();
sendSyncablesToServer(storageSyncables);
syncToServer(SyncType.ONE_WAY_FROM_CLIENT);
}
private void syncRefreshFromClient() {
Vector storageSyncables = getSyncablesFromStorage();
for (Enumeration en = storageSyncables.elements(); en.hasMoreElements();) {
Syncable syncable = (Syncable) en.nextElement();
syncable.setChangeType(ChangeType.ADDED);
}
sendSyncablesToServer(storageSyncables);
syncToServer(SyncType.REFRESH_FROM_CLIENT);
}
private void syncOneWayFromServer() {
syncToServer(SyncType.ONE_WAY_FROM_SERVER);
Vector serverSyncables = receiveSyncablesFromServer();
applyChangesToStorage(serverSyncables);
}
private void syncRefreshFromServer() {
syncToServer(SyncType.REFRESH_FROM_SERVER);
Vector serverSyncables = receiveSyncablesFromServer();
for (Enumeration en = serverSyncables.elements(); en.hasMoreElements();) {
Syncable syncable = (Syncable) en.nextElement();
syncable.setChangeType(ChangeType.ADDED);
}
clearStorage();
applyChangesToStorage(serverSyncables);
}
private void applyChangesToStorage(Vector syncables) {
Vector copy = new Vector();
for (int i = 0; i < syncables.size(); i++) {
copy.addElement(syncables.elementAt(i));
}
for (Enumeration en = copy.elements(); en.hasMoreElements();) {
Syncable syncable = (Syncable) en.nextElement();
switch (syncable.getChangeType()) {
case ChangeType.ADDED: {
syncable.setChangeType(ChangeType.NONE);
addSyncableToStorage(syncable);
break;
}
case ChangeType.EDITED: {
syncable.setChangeType(ChangeType.NONE);
replaceSyncableToStorage(syncable);
break;
}
case ChangeType.DELETED: {
syncable.setChangeType(ChangeType.NONE);
removeSyncableToStorage(syncable);
break;
}
}
}
}
}