blob: 9bd9b1e600e68ce205f042f19d24e4fda1341493 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008-2011 Chair for Applied Software Engineering,
* Technische Universitaet Muenchen.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Edgar Mueller - initial API and implementation
******************************************************************************/
package org.eclipse.emf.emfstore.client.recording.test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.emfstore.bowling.BowlingFactory;
import org.eclipse.emf.emfstore.bowling.League;
import org.eclipse.emf.emfstore.bowling.Player;
import org.eclipse.emf.emfstore.client.ESLocalProject;
import org.eclipse.emf.emfstore.client.callbacks.ESUpdateCallback;
import org.eclipse.emf.emfstore.client.test.common.cases.ESTestWithSharedProject;
import org.eclipse.emf.emfstore.client.test.common.util.ProjectUtil;
import org.eclipse.emf.emfstore.client.util.ESVoidCallable;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.common.model.ESModelElementIdToEObjectMapping;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESLocalProjectImpl;
import org.eclipse.emf.emfstore.internal.client.model.util.ChecksumErrorHandler;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.common.model.util.SerializationException;
import org.eclipse.emf.emfstore.server.ESConflict;
import org.eclipse.emf.emfstore.server.ESConflictSet;
import org.eclipse.emf.emfstore.server.exceptions.ESException;
import org.eclipse.emf.emfstore.server.model.ESChangePackage;
import org.eclipse.emf.emfstore.server.model.ESOperation;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class MultiReferceOperationReverseApplyTest extends ESTestWithSharedProject {
private static final int NUM_PLAYERS = 6;
private League league;
private final ESUpdateCallback keepMyChanges = new KeepMyChanges();
private final ESUpdateCallback keepTheirChanges = new KeepTheirChanges();
@BeforeClass
public static void beforeClass() {
startEMFStore();
}
@AfterClass
public static void afterClass() {
stopEMFStore();
}
@Override
@Before
public void before() {
org.eclipse.emf.emfstore.internal.client.model.Configuration.getClientBehavior().setChecksumErrorHandler(
ChecksumErrorHandler.CANCEL);
super.before();
league = BowlingFactory.eINSTANCE.createLeague();
RunESCommand.run(new ESVoidCallable() {
@Override
public void run() {
getProject().addModelElement(league);
}
});
for (int i = 0; i < NUM_PLAYERS; i++) {
final Player player = BowlingFactory.eINSTANCE.createPlayer();
league.getPlayers().add(player);
}
try {
ProjectUtil.commit(getLocalProject());
} catch (final ESException ex) {
fail(ex.getMessage());
}
}
@Test
public void reverseTest() throws ESException, SerializationException {
// final ESLocalProject copy = ProjectUtil.checkout(getLocalProject());
final ESLocalProject copy = ProjectUtil.checkout(getLocalProject());
final ProjectSpace copiedProjectSpace = ESLocalProjectImpl.class.cast(copy).toInternalAPI();
final League copiedLeague = (League) copiedProjectSpace.getProject().getModelElements().get(0);
// make parallel changes
mutate(league, 1);
mutate(league, 3);
mutate(copiedLeague, 2);
mutate(copiedLeague, 2);
ProjectUtil.commit(getLocalProject());
ProjectUtil.update(copy, keepMyChanges);
RunESCommand.run(new ESVoidCallable() {
@Override
public void run() {
league.getPlayers().get(0).setName("abc"); //$NON-NLS-1$
}
});
ProjectUtil.commit(getLocalProject());
ProjectUtil.update(copy, keepTheirChanges);
ProjectUtil.commit(copy);
ProjectUtil.update(getLocalProject(), keepTheirChanges);
assertTrue(ModelUtil.areEqual(
getProject(),
copiedProjectSpace.getProject()));
}
private void mutate(final League league, final int deleteIndex) {
RunESCommand.run(new ESVoidCallable() {
@Override
public void run() {
league.getPlayers().remove(deleteIndex);
}
});
}
class KeepMyChanges implements ESUpdateCallback {
public void noChangesOnServer() {
// do nothing if there are no changes on the server (in this example we know
// there are changes anyway)
}
public boolean inspectChanges(ESLocalProject project, List<ESChangePackage> changes,
ESModelElementIdToEObjectMapping idToEObjectMapping) {
// allow update to proceed, here we could also add some UI
return true;
}
public boolean conflictOccurred(ESConflictSet changeConflictSet, IProgressMonitor monitor) {
final Iterator<ESConflict> iterator = changeConflictSet.getConflicts().iterator();
while (iterator.hasNext()) {
final ESConflict conflict = iterator.next();
conflict.resolveConflict(conflict.getLocalOperations(), conflict.getRemoteOperations());
}
return true;
}
}
class KeepTheirChanges implements ESUpdateCallback {
public void noChangesOnServer() {
// do nothing if there are no changes on the server (in this example we know
// there are changes anyway)
}
public boolean inspectChanges(ESLocalProject project, List<ESChangePackage> changes,
ESModelElementIdToEObjectMapping idToEObjectMapping) {
// allow update to proceed, here we could also add some UI
return true;
}
public boolean conflictOccurred(ESConflictSet changeConflictSet, IProgressMonitor monitor) {
// One or more conflicts have occured, they are delivered in a change conflict set
// We know there is only one conflict so we grab it
final Iterator<ESConflict> iterator = changeConflictSet.getConflicts().iterator();
while (iterator.hasNext()) {
final ESConflict conflict = iterator.next();
conflict.resolveConflict(Collections.<ESOperation> emptySet(), Collections.<ESOperation> emptySet());
}
// Finally we claim to have resolved all conflicts so update will try to proceed.
return true;
}
}
}