
syncloud.synchronization.nodes.SyncBundle Maven / Gradle / Ivy
The newest version!
package syncloud.synchronization.nodes;
import syncloud.core.CoreException;
import syncloud.core.log.Logger;
import syncloud.storage.IFolder;
import syncloud.storage.INode;
import syncloud.synchronization.IConflictResolver;
import syncloud.synchronization.ISyncRecord;
import syncloud.synchronization.ISynchronizer;
import java.util.ArrayList;
import java.util.List;
public abstract class SyncBundle implements ISyncBundle {
private static Logger logger = Logger.getLogger(SyncBundle.class);
protected ISynchronizer sync;
protected List nodes;
public SyncBundle(ISynchronizer sync, List nodes) {
this.sync = sync;
List statesNodes = new ArrayList();
for(SyncNode node: nodes)
statesNodes.add(new SyncNodeState(node, getState(node)));
this.nodes = statesNodes;
}
protected abstract INode create(IFolder parent, INode from) throws CoreException;
protected void change(INode from, INode to) throws CoreException {
}
protected void delete(INode to) throws CoreException {
to.delete();
}
protected abstract NodeState getState(SyncNode node);
protected abstract void putRecord(ISyncRecord records, INode node);
public void synchronize() {
logger.debug("synchronizing");
try {
IConflictResolver resolver = sync.getResolver();
ISyncRecord records = sync.getRecord();
SyncNodeState from = findFirst(nodes, new NodeState[] { NodeState.CHANGED, NodeState.ADDED, NodeState.DELETED });
if (from != null) {
logger.debug("synchronizing from: " + from.getFullname());
List incompatible = getIncompatible(from, nodes);
if (incompatible.size() == 0) {
synchronize(from, nodes, records);
} else {
incompatible.add(from);
if (resolver != null) {
SyncNodeState resolution = resolver.Resolve(incompatible);
if (resolution != null)
synchronize(resolution, nodes, records);
}
}
} else {
logger.debug("unchanged");
SyncNodeState unchanged = findFirst(nodes, new NodeState[] { NodeState.UNCHANGED });
List notexists = find(nodes, NodeState.NOTEXISTS);
if (unchanged != null && notexists.size() > 0) {
synchronize(unchanged, notexists, records);
}
}
} catch (CoreException e) {
logger.debug("unable to synchronize: ", e);
}
}
private List getIncompatible(SyncNodeState from, List nodes) {
List incompatible = new ArrayList();
for(SyncNodeState node: nodes)
if (node != from && !compatible(from.getState(), node.getState()))
incompatible.add(node);
return incompatible;
}
private boolean compatible(NodeState a, NodeState b) {
if (a == NodeState.CHANGED) {
return b == NodeState.NOTEXISTS || b == NodeState.UNCHANGED;
}
if (a == NodeState.ADDED) {
return b == NodeState.NOTEXISTS;
}
if (a == NodeState.DELETED) {
return false;
}
return false;
}
private SyncNodeState findFirst(List nodes, NodeState[] states) {
for(SyncNodeState node: nodes) {
for(NodeState state: states) {
if (node.getState() == state) return node;
}
}
return null;
}
private void synchronize(SyncNodeState from, List to, ISyncRecord record) throws CoreException {
for(SyncNodeState node: to) {
if (!node.getFullname().equals(from.getFullname())) {
synchronize(from, node, record);
}
}
putRecord(record, from.getNode());
}
protected void synchronize(SyncNodeState from, SyncNodeState to, ISyncRecord record) throws CoreException {
if (from.getState() == NodeState.DELETED) {
String fullName = to.getNode().getKey().getNativePath();
delete(to.getNode());
record.remove(fullName);
} else {
if (to.getState() == NodeState.NOTEXISTS) {
INode createdNode = create(to.getParent(), from.getNode());
putRecord(record, createdNode);
to.setNode(createdNode);
} else if (from.getState() == NodeState.CHANGED) {
change(from.getNode(), to.getNode());
putRecord(record, to.getNode());
}
}
}
protected List find(List files, NodeState[] states) {
List result = new ArrayList();
for(NodeState state: states) {
for(SyncNodeState file: files) {
if (file.getState() == state) result.add(file);
}
}
return result;
}
protected List find(List files, NodeState state) {
return find(files, new NodeState[]{state});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy