All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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