blob: 463fa94f98ff3fe4121975ceaa90ff8b794d176a [file] [log] [blame]
/*
* Copyright (c) 2013 Eike Stepper (Berlin, Germany) and others.
* 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:
* Christian W. Damus (CEA) - initial API and implementation
*/
package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.CDOAdapter;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model2.NotUnsettable;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* Bug 376620: Tests that we get the appropriate notifications for primitive-valued attributes in view invalidations.
*
* @author Christian W. Damus (CEA)
*/
public class Bugzilla_376620b_Test extends AbstractCDOTest
{
public void testBoolean() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableBoolean(), true);
adapter.awaitAssertion();
}
public void testByte() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableByte(), (byte)42);
adapter.awaitAssertion();
}
public void testChar() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableChar(), 'a');
adapter.awaitAssertion();
}
public void testShort() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableShort(), (short)42);
adapter.awaitAssertion();
}
public void testInt() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableInt(), 42);
adapter.awaitAssertion();
}
public void testLong() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableLong(), 42L);
adapter.awaitAssertion();
}
public void testFloat() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableFloat(), 42.0f);
adapter.awaitAssertion();
}
public void testDouble() throws Exception
{
NotUnsettable object = createAndCommitTestObject();
TestAdapter adapter = poke(object, getModel2Package().getNotUnsettable_NotUnsettableDouble(), 42.0);
adapter.awaitAssertion();
}
//
// Test framework
//
protected NotUnsettable createAndCommitTestObject() throws CommitException
{
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.CDO);
Resource res = transaction.createResource(getResourcePath("test"));
NotUnsettable result = getModel2Factory().createNotUnsettable();
res.getContents().add(result);
transaction.commit();
return result;
}
protected TestAdapter poke(EObject object, EAttribute attribute, Object value) throws CommitException
{
CDOSession session = openSession();
CDOTransaction transaction = session.openTransaction();
transaction.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.CDO);
final Object oldValue = object.eGet(attribute);
final TestAdapter result = TestAdapter.assertFuture(object, attribute, oldValue, value);
EObject other = transaction.getObject(object);
other.eSet(attribute, value);
transaction.commit();
return result;
}
/**
* @author Christian W. Damus (CEA)
*/
private static class TestAdapter extends AdapterImpl implements CDOAdapter
{
private final Semaphore semaphore = new Semaphore(0);
private final EAttribute attribute;
private final Object expectedOldValue;
private final Object expectedNewValue;
private volatile boolean received;
public TestAdapter(EAttribute attribute, Object expectedOldValue, Object expectedNewValue)
{
this.attribute = attribute;
this.expectedOldValue = expectedOldValue;
this.expectedNewValue = expectedNewValue;
}
public static TestAdapter assertFuture(EObject notifier, EAttribute attribute, Object oldValue, Object newValue)
{
TestAdapter result = new TestAdapter(attribute, oldValue, newValue);
notifier.eAdapters().add(result);
return result;
}
public void awaitAssertion()
{
try
{
semaphore.tryAcquire(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e)
{
fail("Interrupted while awaiting assertion.");
}
assertEquals(true, received);
}
@Override
public void notifyChanged(Notification msg)
{
if (msg.getFeature() == attribute)
{
try
{
Class<?> type = attribute.getEType().getInstanceClass();
if (type == boolean.class)
{
update(asBoolean(expectedOldValue) == msg.getOldBooleanValue() //
&& asBoolean(expectedNewValue) == msg.getNewBooleanValue());
}
else if (type == byte.class)
{
update(asByte(expectedOldValue) == msg.getOldByteValue() //
&& asByte(expectedNewValue) == msg.getNewByteValue());
}
else if (type == char.class)
{
update(asChar(expectedOldValue) == msg.getOldCharValue() //
&& asChar(expectedNewValue) == msg.getNewCharValue());
}
else if (type == short.class)
{
update(asShort(expectedOldValue) == msg.getOldShortValue() //
&& asShort(expectedNewValue) == msg.getNewShortValue());
}
else if (type == int.class)
{
update(asInt(expectedOldValue) == msg.getOldIntValue() //
&& asInt(expectedNewValue) == msg.getNewIntValue());
}
else if (type == long.class)
{
update(asLong(expectedOldValue) == msg.getOldLongValue() //
&& asLong(expectedNewValue) == msg.getNewLongValue());
}
else if (type == float.class)
{
update(asFloat(expectedOldValue) == msg.getOldFloatValue() //
&& asFloat(expectedNewValue) == msg.getNewFloatValue());
}
else if (type == double.class)
{
update(asDouble(expectedOldValue) == msg.getOldDoubleValue() //
&& asDouble(expectedNewValue) == msg.getNewDoubleValue());
}
}
finally
{
semaphore.release();
}
}
}
private void update(boolean received)
{
if (received)
{
this.received = received;
}
}
private boolean asBoolean(Object value)
{
return ((Boolean)value).booleanValue();
}
private byte asByte(Object value)
{
return ((Number)value).byteValue();
}
private char asChar(Object value)
{
return ((Character)value).charValue();
}
private short asShort(Object value)
{
return ((Number)value).shortValue();
}
private int asInt(Object value)
{
return ((Number)value).intValue();
}
private long asLong(Object value)
{
return ((Number)value).longValue();
}
private float asFloat(Object value)
{
return ((Number)value).floatValue();
}
private double asDouble(Object value)
{
return ((Number)value).doubleValue();
}
}
}