| /* |
| * Copyright (c) 2012, 2015 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.hibernate; |
| |
| import org.eclipse.emf.cdo.CDOObject; |
| import org.eclipse.emf.cdo.CDOObjectHistory; |
| import org.eclipse.emf.cdo.common.commit.CDOCommitHistory; |
| import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; |
| import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion; |
| import org.eclipse.emf.cdo.common.revision.CDORevision; |
| import org.eclipse.emf.cdo.common.revision.CDORevisionKey; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; |
| import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta; |
| import org.eclipse.emf.cdo.eresource.CDOResource; |
| import org.eclipse.emf.cdo.eresource.EresourcePackage; |
| import org.eclipse.emf.cdo.session.CDOSession; |
| import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; |
| import org.eclipse.emf.cdo.tests.AbstractCDOTest; |
| import org.eclipse.emf.cdo.tests.config.IRepositoryConfig; |
| import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires; |
| import org.eclipse.emf.cdo.tests.model1.Company; |
| import org.eclipse.emf.cdo.tests.model1.Model1Package; |
| import org.eclipse.emf.cdo.tests.model1.Product1; |
| import org.eclipse.emf.cdo.tests.model1.VAT; |
| import org.eclipse.emf.cdo.transaction.CDOTransaction; |
| import org.eclipse.emf.cdo.util.CDOUtil; |
| import org.eclipse.emf.cdo.view.CDOView; |
| |
| import org.eclipse.net4j.util.concurrent.ConcurrencyUtil; |
| import org.eclipse.net4j.util.lifecycle.LifecycleUtil; |
| |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| import org.eclipse.emf.teneo.Constants; |
| |
| import java.util.List; |
| |
| /** |
| * @author Martin Taal |
| * @author Eike Stepper |
| */ |
| @Requires(IRepositoryConfig.CAPABILITY_AUDITING) |
| public class CDOObjectHistoryTest extends AbstractCDOTest |
| { |
| protected CDOSession session1; |
| |
| @Override |
| public void setUp() throws Exception |
| { |
| if (Model1Package.eINSTANCE.getProduct1_Vat().getEAnnotation(Constants.ANNOTATION_SOURCE_TENEO_JPA) == null) |
| { |
| final EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); |
| eAnnotation.setSource(Constants.ANNOTATION_SOURCE_TENEO_JPA); |
| eAnnotation.getDetails().put(Constants.ANNOTATION_KEY_VALUE, "@Enumerated(value=EnumType.ORDINAL)"); |
| Model1Package.eINSTANCE.getProduct1_Vat().getEAnnotations().add(eAnnotation); |
| } |
| |
| super.setUp(); |
| } |
| |
| @Override |
| protected void doTearDown() throws Exception |
| { |
| LifecycleUtil.deactivate(session1); |
| session1 = null; |
| super.doTearDown(); |
| } |
| |
| protected CDOSession openSession1() |
| { |
| session1 = openSession(); |
| return session1; |
| } |
| |
| protected void closeSession1() |
| { |
| session1.close(); |
| } |
| |
| protected CDOSession openSession2() |
| { |
| return openSession(); |
| } |
| |
| public void testChangedAudit() throws Exception |
| { |
| CDOSession session = openSession1(); |
| CDOTransaction transaction = session.openTransaction(); |
| CDOResource resource = transaction.createResource(getResourcePath("/res1")); |
| |
| Company company = getModel1Factory().createCompany(); |
| company.setName("ESC"); |
| resource.getContents().add(company); |
| |
| // add a product |
| Product1 product = getModel1Factory().createProduct1(); |
| product.setVat(VAT.VAT15); |
| product.setDescription("description"); |
| resource.getContents().add(product); |
| |
| long commitTime1 = transaction.commit().getTimeStamp(); |
| assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime1); |
| assertEquals("ESC", company.getName()); |
| final CDOObject cdoObjectCompany = CDOUtil.getCDOObject(company); |
| assertEquals(1, cdoObjectCompany.cdoRevision().getVersion()); |
| |
| company.setName("Sympedia"); |
| long commitTime2 = transaction.commit().getTimeStamp(); |
| assertEquals(true, commitTime1 < commitTime2); |
| assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime2); |
| assertEquals("Sympedia", company.getName()); |
| assertEquals(2, cdoObjectCompany.cdoRevision().getVersion()); |
| |
| company.setName("Eclipse"); |
| long commitTime3 = transaction.commit().getTimeStamp(); |
| assertEquals(true, commitTime2 < commitTime3); |
| assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime2); |
| assertEquals("Eclipse", company.getName()); |
| assertEquals(3, cdoObjectCompany.cdoRevision().getVersion()); |
| |
| resource.getContents().remove(company); |
| long commitTime4 = transaction.commit().getTimeStamp(); |
| |
| closeSession1(); |
| session = openSession2(); |
| |
| CDOView audit = session.openView(commitTime1); |
| { |
| CDOResource auditResource = audit.getResource(getResourcePath("/res1")); |
| Company auditCompany = (Company)auditResource.getContents().get(0); |
| assertEquals("ESC", auditCompany.getName()); |
| |
| final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany); |
| assertEquals(1, cdoObjectHistory.getElements().length); |
| for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements()) |
| { |
| if (cdoCommitInfo.getTimeStamp() == commitTime1) |
| { |
| checkCommitInfo1(cdoCommitInfo); |
| } |
| else |
| { |
| fail(); |
| } |
| } |
| audit.close(); |
| } |
| |
| audit = session.openView(commitTime2); |
| { |
| CDOResource auditResource = audit.getResource(getResourcePath("/res1")); |
| Company auditCompany = (Company)auditResource.getContents().get(0); |
| assertEquals("Sympedia", auditCompany.getName()); |
| |
| final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany); |
| assertEquals(2, cdoObjectHistory.getElements().length); |
| for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements()) |
| { |
| if (cdoCommitInfo.getTimeStamp() == commitTime1) |
| { |
| checkCommitInfo1(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime2) |
| { |
| checkCommitInfo2(cdoCommitInfo); |
| } |
| else |
| { |
| fail(); |
| } |
| } |
| audit.close(); |
| } |
| |
| audit = session.openView(commitTime3); |
| { |
| CDOResource auditResource = audit.getResource(getResourcePath("/res1")); |
| |
| Company auditCompany = (Company)auditResource.getContents().get(0); |
| assertEquals("Eclipse", auditCompany.getName()); |
| |
| final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany); |
| assertEquals(3, cdoObjectHistory.getElements().length); |
| for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements()) |
| { |
| if (cdoCommitInfo.getTimeStamp() == commitTime1) |
| { |
| checkCommitInfo1(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime2) |
| { |
| checkCommitInfo2(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime3) |
| { |
| checkCommitInfo3(cdoCommitInfo); |
| } |
| else |
| { |
| fail(); |
| } |
| } |
| |
| final CDOObject cdoObject = CDOUtil.getCDOObject(auditCompany); |
| int initialVersion = cdoObject.cdoRevision().getVersion(); |
| assertEquals(3, initialVersion); |
| |
| final InternalCDORevision revision3 = (InternalCDORevision)CDOUtil.getRevisionByVersion(cdoObject, 3); |
| final InternalCDORevision revision2 = (InternalCDORevision)CDOUtil.getRevisionByVersion(cdoObject, 2); |
| final InternalCDORevision revision1 = (InternalCDORevision)CDOUtil.getRevisionByVersion(cdoObject, 1); |
| |
| CDORevisionDelta revisionDelta = revision3.compare(revision2); |
| for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas()) |
| { |
| System.err |
| .println(featureDelta.getFeature().getName() + " changed through changeType " + featureDelta.getType()); |
| } |
| |
| assertEquals("ESC", revision1.getValue(revision1.getEClass().getEStructuralFeature("name"))); |
| assertEquals("Sympedia", revision2.getValue(revision1.getEClass().getEStructuralFeature("name"))); |
| assertEquals("Eclipse", revision3.getValue(revision1.getEClass().getEStructuralFeature("name"))); |
| |
| audit.close(); |
| } |
| |
| audit = session.openView(commitTime4); |
| { |
| final CDOCommitHistory cdoCommitHistory = getCDOCommitHistory(audit); |
| assertEquals(5, cdoCommitHistory.getElements().length); |
| for (CDOCommitInfo cdoCommitInfo : cdoCommitHistory.getElements()) |
| { |
| if (cdoCommitInfo.getTimeStamp() == commitTime1) |
| { |
| checkCommitInfo1(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime2) |
| { |
| checkCommitInfo2(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime3) |
| { |
| checkCommitInfo3(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getTimeStamp() == commitTime4) |
| { |
| checkCommitInfo4(cdoCommitInfo); |
| } |
| else if (cdoCommitInfo.getComment() != null && cdoCommitInfo.getComment().equals("<initialize>")) |
| { |
| // as expected |
| } |
| else |
| { |
| fail(); |
| } |
| } |
| audit.close(); |
| } |
| |
| session.close(); |
| } |
| |
| private void checkCommitInfo1(CDOCommitInfo cdoCommitInfo) |
| { |
| final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects(); |
| final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects(); |
| final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects(); |
| assertEquals(0, detachedObjects.size()); |
| assertEquals(4, newObjects.size()); |
| assertEquals(1, changedObjects.size()); |
| for (Object o : changedObjects) |
| { |
| final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o; |
| final CDOFeatureDelta cdoFeatureDelta = cdoRevisionDelta |
| .getFeatureDelta(EresourcePackage.eINSTANCE.getCDOResource_Contents()); |
| assertNotNull(cdoFeatureDelta); |
| assertEquals(CDOFeatureDelta.Type.LIST, cdoFeatureDelta.getType()); |
| } |
| int resourceCnt = 0; |
| int resourceFolderCnt = 0; |
| int companyCnt = 0; |
| int productCnt = 0; |
| for (Object o : newObjects) |
| { |
| final CDORevision cdoRevision = (CDORevision)o; |
| if (cdoRevision.getEClass().getName().equals(Model1Package.eINSTANCE.getProduct1().getName())) |
| { |
| productCnt++; |
| } |
| if (cdoRevision.getEClass().getName().equals(Model1Package.eINSTANCE.getCompany().getName())) |
| { |
| companyCnt++; |
| } |
| if (cdoRevision.getEClass() == EresourcePackage.eINSTANCE.getCDOResource()) |
| { |
| resourceCnt++; |
| } |
| if (cdoRevision.getEClass() == EresourcePackage.eINSTANCE.getCDOResourceFolder()) |
| { |
| resourceFolderCnt++; |
| } |
| } |
| assertEquals(1, productCnt); |
| assertEquals(1, companyCnt); |
| assertEquals(1, resourceCnt); |
| assertEquals(1, resourceFolderCnt); |
| } |
| |
| private void checkCommitInfo2(CDOCommitInfo cdoCommitInfo) |
| { |
| final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects(); |
| final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects(); |
| final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects(); |
| assertEquals(0, detachedObjects.size()); |
| assertEquals(0, newObjects.size()); |
| assertEquals(1, changedObjects.size()); |
| for (Object o : changedObjects) |
| { |
| final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o; |
| final CDOSetFeatureDelta cdoFeatureDelta = (CDOSetFeatureDelta)cdoRevisionDelta |
| .getFeatureDelta(cdoRevisionDelta.getEClass().getEStructuralFeature("name")); |
| assertNotNull(cdoFeatureDelta); |
| assertEquals("Sympedia", cdoFeatureDelta.getValue()); |
| } |
| } |
| |
| private void checkCommitInfo3(CDOCommitInfo cdoCommitInfo) |
| { |
| final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects(); |
| final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects(); |
| final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects(); |
| assertEquals(0, detachedObjects.size()); |
| assertEquals(0, newObjects.size()); |
| assertEquals(1, changedObjects.size()); |
| for (Object o : changedObjects) |
| { |
| final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o; |
| final CDOSetFeatureDelta cdoFeatureDelta = (CDOSetFeatureDelta)cdoRevisionDelta |
| .getFeatureDelta(cdoRevisionDelta.getEClass().getEStructuralFeature("name")); |
| assertNotNull(cdoFeatureDelta); |
| assertEquals("Eclipse", cdoFeatureDelta.getValue()); |
| } |
| } |
| |
| private void checkCommitInfo4(CDOCommitInfo cdoCommitInfo) |
| { |
| final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects(); |
| final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects(); |
| final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects(); |
| assertEquals(1, detachedObjects.size()); |
| assertEquals(0, newObjects.size()); |
| // due to a bug/issue in cdo hibernate store, there are 2 changedobjects |
| // need to revisit after default/enum value setting has been changed |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=387752 |
| assertEquals(1, changedObjects.size()); |
| for (Object o : changedObjects) |
| { |
| final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o; |
| if (cdoRevisionDelta.getEClass().getName().equals("Product1")) |
| { |
| continue; |
| } |
| final CDOFeatureDelta cdoFeatureDelta = cdoRevisionDelta |
| .getFeatureDelta(EresourcePackage.eINSTANCE.getCDOResource_Contents()); |
| assertNotNull(cdoFeatureDelta); |
| assertEquals(CDOFeatureDelta.Type.LIST, cdoFeatureDelta.getType()); |
| } |
| } |
| |
| private synchronized CDOObjectHistory getCDOObjectHistory(CDOView audit, Object object) |
| { |
| CDOObjectHistory cdoObjectHistory = audit.getHistory((CDOObject)object); |
| |
| cdoObjectHistory.triggerLoad(); |
| long startTime = System.currentTimeMillis(); |
| while (cdoObjectHistory.isLoading()) |
| { |
| ConcurrencyUtil.sleep(10); |
| |
| // waited too long |
| if (System.currentTimeMillis() - startTime > 5000) |
| { |
| throw new IllegalStateException("commit info could not be loaded"); |
| } |
| } |
| return cdoObjectHistory; |
| } |
| |
| private synchronized CDOCommitHistory getCDOCommitHistory(CDOView audit) |
| { |
| CDOCommitHistory cdoCommitHistory = audit.getHistory(); |
| |
| cdoCommitHistory.triggerLoad(); |
| long startTime = System.currentTimeMillis(); |
| while (cdoCommitHistory.isLoading()) |
| { |
| ConcurrencyUtil.sleep(10); |
| |
| // waited too long |
| if (System.currentTimeMillis() - startTime > 5000) |
| { |
| throw new IllegalStateException("commit info could not be loaded"); |
| } |
| } |
| return cdoCommitHistory; |
| } |
| } |