diff options
2 files changed, 210 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ObjectWriteAccessHandler.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ObjectWriteAccessHandler.java new file mode 100644 index 0000000000..b724e1ecc9 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/ObjectWriteAccessHandler.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2004 - 2010 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.spi.server; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.server.CDOServerUtil; +import org.eclipse.emf.cdo.server.IRepository.WriteAccessHandler; +import org.eclipse.emf.cdo.server.IStoreAccessor; +import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; +import org.eclipse.emf.cdo.server.ITransaction; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.view.CDOView; + +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.om.monitor.OMMonitor; + +import org.eclipse.emf.ecore.EObject; + +/** + * @author Eike Stepper + * @since 4.0 + */ +public class ObjectWriteAccessHandler implements WriteAccessHandler +{ + private boolean legacyModeEnabled; + + private IStoreAccessor.CommitContext commitContext; + + private CDOView view; + + private EObject[] newObjects; + + private EObject[] dirtyObjects; + + public ObjectWriteAccessHandler() + { + } + + public ObjectWriteAccessHandler(boolean legacyModeEnabled) + { + this.legacyModeEnabled = legacyModeEnabled; + } + + public final boolean isLegacyModeEnabled() + { + return legacyModeEnabled; + } + + protected final IStoreAccessor.CommitContext getCommitContext() + { + return commitContext; + } + + protected final ITransaction getTransaction() + { + return commitContext.getTransaction(); + } + + protected final CDOView getView() + { + if (view == null) + { + view = CDOServerUtil.openView(commitContext, legacyModeEnabled); + } + + return view; + } + + protected final EObject[] getNewObjects() + { + if (newObjects == null) + { + InternalCDORevision[] newRevisions = commitContext.getNewObjects(); + newObjects = new EObject[newRevisions.length]; + CDOView view = getView(); + + for (int i = 0; i < newRevisions.length; i++) + { + InternalCDORevision newRevision = newRevisions[i]; + CDOObject newObject = view.getObject(newRevision.getID()); + newObjects[i] = CDOUtil.getEObject(newObject); + } + } + + return newObjects; + } + + protected final EObject[] getDirtyObjects() + { + if (dirtyObjects == null) + { + InternalCDORevision[] dirtyRevisions = commitContext.getDirtyObjects(); + dirtyObjects = new EObject[dirtyRevisions.length]; + CDOView view = getView(); + + for (int i = 0; i < dirtyRevisions.length; i++) + { + InternalCDORevision dirtyRevision = dirtyRevisions[i]; + CDOObject dirtyObject = view.getObject(dirtyRevision.getID()); + dirtyObjects[i] = CDOUtil.getEObject(dirtyObject); + } + } + + return dirtyObjects; + } + + public final void handleTransactionBeforeCommitting(ITransaction transaction, + IStoreAccessor.CommitContext commitContext, OMMonitor monitor) throws RuntimeException + { + try + { + this.commitContext = commitContext; + handleTransactionBeforeCommitting(monitor); + } + finally + { + LifecycleUtil.deactivate(view); + view = null; + dirtyObjects = null; + newObjects = null; + this.commitContext = null; + } + } + + public final void handleTransactionAfterCommitted(ITransaction transaction, CommitContext commitContext, + OMMonitor monitor) + { + try + { + this.commitContext = commitContext; + handleTransactionAfterCommitted(monitor); + } + finally + { + LifecycleUtil.deactivate(view); + view = null; + dirtyObjects = null; + newObjects = null; + this.commitContext = null; + } + } + + protected void handleTransactionBeforeCommitting(OMMonitor monitor) throws RuntimeException + { + } + + protected void handleTransactionAfterCommitted(OMMonitor monitor) + { + } +} diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RepositoryTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RepositoryTest.java index 34b2e4a4ef..1e2268f161 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RepositoryTest.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/RepositoryTest.java @@ -20,6 +20,7 @@ import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext; import org.eclipse.emf.cdo.server.ITransaction; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.spi.server.InternalStore; +import org.eclipse.emf.cdo.spi.server.ObjectWriteAccessHandler; import org.eclipse.emf.cdo.tests.model1.Customer; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CDOUtil; @@ -216,6 +217,56 @@ public class RepositoryTest extends AbstractCDOTest session.close(); } + public void testObjectWriteAccessHandler() throws Exception + { + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + CDOResource resource = transaction.createResource("/res1"); + resource.getContents().add(createCustomer("Eike")); + transaction.commit(); // Ensure that model1 is committed to the repository + + getRepository().addHandler(new ObjectWriteAccessHandler(isConfig(LEGACY)) + { + @Override + protected void handleTransactionBeforeCommitting(OMMonitor monitor) throws RuntimeException + { + for (EObject object : getNewObjects()) + { + if (object instanceof Customer) + { + Customer customer = (Customer)object; + String name = customer.getName(); + if ("Admin".equals(name)) + { + throw new IllegalStateException("Adding a customer with name 'Admin' is not allowed"); + } + } + } + } + }); + + resource.getContents().add(createCustomer("Simon")); + transaction.commit(); + resource.getContents().add(createCustomer("Admin")); + + try + { + transaction.commit(); + fail("CommitException expected"); + } + catch (CommitException expected) + { + // Success + transaction.rollback(); + } + + resource.getContents().add(createCustomer("Martin")); + transaction.commit(); + resource.getContents().add(createCustomer("Nick")); + transaction.commit(); + session.close(); + } + public void testReadAccessHandlers() throws Exception { { |