| /* |
| * Copyright (c) 2010-2012 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: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.emf.cdo.tests.bugzilla; |
| |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.tests.AbstractCDOTest; |
| import org.eclipse.emf.cdo.tests.model1.Category; |
| import org.eclipse.emf.cdo.tests.model1.Company; |
| import org.eclipse.emf.cdo.transaction.CDOTransaction; |
| import org.eclipse.emf.cdo.view.CDOAdapterPolicy; |
| |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| |
| /** |
| * IndexOutOfBoundsException in buildNotification. |
| * <p> |
| * See bug 306710 |
| */ |
| public class Bugzilla_306710_Test extends AbstractCDOTest |
| { |
| public void testBugzilla_306710_remove() throws Exception |
| { |
| final NotifyCounter counter = new NotifyCounter(); |
| |
| // setup connection1. |
| CDOSession session1 = openSession(); |
| CDOTransaction transaction1 = session1.openTransaction(); |
| CDOResource resource1 = transaction1.createResource(getResourcePath("/test1")); |
| |
| // add initial model. |
| Company company1 = getModel1Factory().createCompany(); |
| resource1.getContents().add(company1); |
| Category category1a = getModel1Factory().createCategory(); |
| company1.getCategories().add(category1a); |
| transaction1.commit(); |
| |
| // sleep(100); |
| |
| // setup connection2. |
| CDOSession session2 = openSession(); |
| CDOTransaction transaction2 = session2.openTransaction(); |
| transaction2.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); |
| CDOResource resource2 = transaction2.getOrCreateResource(getResourcePath("/test1")); |
| |
| // add adapter to company2 to have sendDeltaNotification being called. |
| Company company2 = (Company)resource2.getContents().get(0); |
| company2.eAdapters().add(new AdapterImpl() |
| { |
| @Override |
| public void notifyChanged(Notification msg) |
| { |
| if (msg.getEventType() == Notification.ADD) |
| { |
| counter.incAdds(); |
| } |
| else if (msg.getEventType() == Notification.REMOVE) |
| { |
| counter.incRemoves(); |
| } |
| } |
| }); |
| |
| // add and remove an object from category list of company to have the CDONotificationBuilder call remove with an |
| // index not known to the oldRevision. |
| Category category1b = getModel1Factory().createCategory(); |
| company1.getCategories().add(0, category1b); |
| company1.getCategories().remove(1); |
| |
| // commit the changes. |
| transaction1.commit(); |
| |
| // wait for the invalidation to arrive on transaction2. |
| transaction2.waitForUpdate(transaction1.getLastCommitTime(), DEFAULT_TIMEOUT); |
| |
| // cleanup. |
| session1.close(); |
| session2.close(); |
| |
| // check if the notifications arrived (which is not the case because of the exception). |
| assertEquals(1, counter.getAdds()); |
| assertEquals(1, counter.getRemoves()); |
| } |
| |
| /** |
| * @since 4.0 |
| */ |
| public void testBugzilla_306710_addRemove() throws Exception |
| { |
| final NotifyCounter counter = new NotifyCounter(); |
| |
| // setup connection1. |
| CDOSession session1 = openSession(); |
| CDOTransaction transaction1 = session1.openTransaction(); |
| CDOResource resource1 = transaction1.createResource(getResourcePath("/test1")); |
| |
| // add initial model. |
| Company company1 = getModel1Factory().createCompany(); |
| resource1.getContents().add(company1); |
| transaction1.commit(); |
| |
| // sleep(100); |
| |
| // setup connection2. |
| CDOSession session2 = openSession(); |
| CDOTransaction transaction2 = session2.openTransaction(); |
| transaction2.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); |
| CDOResource resource2 = transaction2.getOrCreateResource(getResourcePath("/test1")); |
| |
| // add adapter to company2 to have sendDeltaNotification being called. |
| Company company2 = (Company)resource2.getContents().get(0); |
| company2.eAdapters().add(new AdapterImpl() |
| { |
| @Override |
| public void notifyChanged(Notification msg) |
| { |
| if (msg.getEventType() == Notification.ADD) |
| { |
| counter.incAdds(); |
| } |
| else if (msg.getEventType() == Notification.REMOVE) |
| { |
| counter.incRemoves(); |
| } |
| } |
| }); |
| |
| // add and remove an object from category list of company to have the CDONotificationBuilder call remove with an |
| // index not known to the oldRevision. |
| Category category1a = getModel1Factory().createCategory(); |
| company1.getCategories().add(0, category1a); |
| company1.getCategories().remove(0); |
| |
| // commit the changes. |
| transaction1.commit(); |
| |
| // wait for the invalidation to arrive on transaction2. |
| transaction2.waitForUpdate(transaction1.getLastCommitTime(), DEFAULT_TIMEOUT); |
| |
| // cleanup. |
| session1.close(); |
| session2.close(); |
| |
| // check if the notifications arrived (which is not the case because of the exception). |
| assertEquals(0, counter.getAdds()); |
| assertEquals(0, counter.getRemoves()); |
| } |
| |
| /** |
| * Helper class to count the notifications. |
| */ |
| public static class NotifyCounter |
| { |
| int adds; |
| |
| int removes; |
| |
| public int getAdds() |
| { |
| return adds; |
| } |
| |
| public int getRemoves() |
| { |
| return removes; |
| } |
| |
| public void incAdds() |
| { |
| adds++; |
| } |
| |
| public void incRemoves() |
| { |
| removes++; |
| } |
| } |
| } |