package org.eclipse.emf.emfstore.client.model.controller; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.emfstore.client.model.WorkspaceManager; import org.eclipse.emf.emfstore.client.model.connectionmanager.ServerCall; import org.eclipse.emf.emfstore.client.model.controller.callbacks.UpdateCallback; import org.eclipse.emf.emfstore.client.model.exceptions.ChangeConflictException; import org.eclipse.emf.emfstore.client.model.impl.ProjectSpaceBase; import org.eclipse.emf.emfstore.client.model.observers.UpdateObserver; import org.eclipse.emf.emfstore.server.conflictDetection.ConflictDetector; import org.eclipse.emf.emfstore.server.exceptions.EmfStoreException; import org.eclipse.emf.emfstore.server.model.versioning.ChangePackage; import org.eclipse.emf.emfstore.server.model.versioning.PrimaryVersionSpec; import org.eclipse.emf.emfstore.server.model.versioning.VersionSpec; public class UpdateController extends ServerCall<PrimaryVersionSpec> { private VersionSpec version; private UpdateCallback callback; public UpdateController(ProjectSpaceBase projectSpace, VersionSpec version, UpdateCallback callback, IProgressMonitor progress) { super(projectSpace); /** * SANITY CHECKS */ if (version == null) { version = VersionSpec.HEAD_VERSION; } if (callback == null) { callback = UpdateCallback.NOCALLBACK; } this.version = version; this.callback = callback; setProgressMonitor(progress); } @Override protected PrimaryVersionSpec run() throws EmfStoreException { return doUpdate(version); } private PrimaryVersionSpec doUpdate(VersionSpec version) throws EmfStoreException { getProgressMonitor().beginTask("Updating Project", 100); getProgressMonitor().worked(1); getProgressMonitor().subTask("Resolving new version"); final PrimaryVersionSpec resolvedVersion = getProjectSpace() .resolveVersionSpec(version); if (resolvedVersion.compareTo(getProjectSpace().getBaseVersion()) == 0) { return resolvedVersion; } getProgressMonitor().worked(5); if (getProgressMonitor().isCanceled()) { return getProjectSpace().getBaseVersion(); } getProgressMonitor().subTask("Fetching changes from server"); List<ChangePackage> changes = new ArrayList<ChangePackage>(); changes = getConnectionManager().getChanges(getSessionId(), getProjectSpace().getProjectId(), getProjectSpace().getBaseVersion(), resolvedVersion); ChangePackage localchanges = getProjectSpace().getLocalChangePackage( false); getProgressMonitor().worked(65); if (getProgressMonitor().isCanceled()) { return getProjectSpace().getBaseVersion(); } getProgressMonitor().subTask("Checking for conflicts"); ConflictDetector conflictDetector = new ConflictDetector(); for (ChangePackage change : changes) { if (conflictDetector.doConflict(change, localchanges)) { if (callback.conflictOccurred(new ChangeConflictException( changes, getProjectSpace(), conflictDetector))) { return getProjectSpace().getBaseVersion(); } else { throw new ChangeConflictException(changes, getProjectSpace(), conflictDetector); } } } getProgressMonitor().worked(15); // TODO ASYNC review this cancel if (getProgressMonitor().isCanceled() || !callback.inspectChanges(getProjectSpace(), changes)) { return resolvedVersion; // updateDone(getProjectSpace().getBaseVersion(), null); } WorkspaceManager.getObserverBus().notify(UpdateObserver.class) .inspectChanges(getProjectSpace(), changes); getProgressMonitor().subTask("Applying changes"); final List<ChangePackage> cps = changes; // revert getProjectSpace().revert(); // apply changes from repo for (ChangePackage change : cps) { getProjectSpace().applyOperations(change.getCopyOfOperations(), false); } // reapply local changes getProjectSpace().applyOperations(localchanges.getCopyOfOperations(), true); getProjectSpace().setBaseVersion(resolvedVersion); getProjectSpace().saveProjectSpaceOnly(); WorkspaceManager.getObserverBus().notify(UpdateObserver.class) .updateCompleted(getProjectSpace()); return getProjectSpace().getBaseVersion(); } }