From b68105714d98f4fff318071fb003251eea68f80f Mon Sep 17 00:00:00 2001 From: Eike Stepper Date: Sat, 9 Feb 2008 18:17:30 +0000 Subject: [217117] Develop a HibernateStore https://bugs.eclipse.org/bugs/show_bug.cgi?id=217117 --- .../emf/cdo/server/internal/db/DBStoreWriter.java | 135 +++--- .../emf/cdo/server/internal/db/NoClassMapping.java | 6 +- plugins/org.eclipse.emf.cdo.server/.options | 1 + .../CommitTransactionIndicationOLD.java | 403 +++++++++++++++++ .../emf/cdo/internal/server/MEMStoreAccessor.java | 60 ++- .../emf/cdo/internal/server/NOOPStoreAccessor.java | 19 +- .../emf/cdo/internal/server/PackageManager.java | 45 -- .../emf/cdo/internal/server/Repository.java | 5 + .../emf/cdo/internal/server/RevisionManager.java | 105 ----- .../eclipse/emf/cdo/internal/server/Session.java | 29 +- .../emf/cdo/internal/server/SessionManager.java | 5 +- .../emf/cdo/internal/server/StoreAccessor.java | 6 - .../emf/cdo/internal/server/Transaction.java | 480 +++++++++++++++++++++ .../eclipse/emf/cdo/internal/server/bundle/OM.java | 2 + .../protocol/CommitTransactionIndication.java | 357 +++------------ .../server/protocol/InvalidationNotification.java | 15 +- .../org/eclipse/emf/cdo/server/IRepository.java | 6 + .../org/eclipse/emf/cdo/server/IStoreWriter.java | 93 +++- .../org/eclipse/emf/cdo/server/ITransaction.java | 36 ++ .../emf/cdo/CDOTransactionFinishedEvent.java | 3 +- .../cdo/eresource/impl/EresourceFactoryImpl.java | 2 +- .../eclipse/emf/internal/cdo/CDOSessionImpl.java | 2 +- .../eclipse/emf/internal/cdo/CDOStateMachine.java | 5 +- .../emf/internal/cdo/CDOTransactionImpl.java | 16 +- .../org/eclipse/emf/internal/cdo/CDOViewImpl.java | 2 +- .../cdo/protocol/CommitTransactionRequest.java | 113 +++-- .../cdo/protocol/CommitTransactionResult.java | 7 +- 27 files changed, 1316 insertions(+), 642 deletions(-) create mode 100644 plugins/org.eclipse.emf.cdo.server/CommitTransactionIndicationOLD.java create mode 100644 plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java create mode 100644 plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java index 00eb11ecb3..4357afba52 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/DBStoreWriter.java @@ -19,6 +19,7 @@ import org.eclipse.emf.cdo.protocol.model.CDOClass; import org.eclipse.emf.cdo.protocol.model.CDOFeature; import org.eclipse.emf.cdo.protocol.model.CDOPackage; import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.server.db.IClassMapping; import org.eclipse.emf.cdo.server.db.IDBStoreWriter; @@ -46,12 +47,78 @@ public class DBStoreWriter extends DBStoreReader implements IDBStoreWriter super(store, view); } - public CDOID primeNewObject(CDOClass cdoClass) + public void beginCommit(CommitContext context) + { + writePackages(context.getNewPackages()); + } + + public CDOID createNewResourceID(CommitContext context, int i, CDORevision newResource) + { + return getStore().getNextCDOID(); + } + + public CDOID createNewObjectID(CommitContext context, int i, CDORevision newObject) { return getStore().getNextCDOID(); } - public void writePackages(CDOPackage... cdoPackages) + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevision[] dirtyObjects) + { + for (CDORevision revision : newResources) + { + writeRevision(revision); + } + + for (CDORevision revision : newObjects) + { + writeRevision(revision); + } + + for (CDORevision revision : dirtyObjects) + { + writeRevision(revision); + } + + try + { + if (TRACER.isEnabled()) + { + TRACER.format("Committing transaction: {0}", getView()); + } + + getConnection().commit(); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevisionDelta[] dirtyObjectDeltas) + { + throw new UnsupportedOperationException(); + } + + public void cancelCommit(CommitContext context) + { + try + { + if (TRACER.isEnabled()) + { + TRACER.format("Rolling back transaction: {0}", getView()); + } + + getConnection().rollback(); + } + catch (SQLException ex) + { + throw new DBException(ex); + } + } + + protected void writePackages(CDOPackage... cdoPackages) { for (CDOPackage cdoPackage : cdoPackages) { @@ -62,6 +129,19 @@ public class DBStoreWriter extends DBStoreReader implements IDBStoreWriter getStore().getDBAdapter().createTables(affectedTables, getConnection()); } + protected void writeRevision(CDORevision revision) + { + if (TRACER.isEnabled()) + { + TRACER.format("Inserting revision: {0}", revision); + } + + CDOClass cdoClass = revision.getCDOClass(); + IMappingStrategy mappingStrategy = getStore().getMappingStrategy(); + IClassMapping mapping = mappingStrategy.getClassMapping(cdoClass); + mapping.writeRevision(this, revision); + } + protected void writePackage(CDOPackage cdoPackage) { int id = getStore().getNextPackageID(); @@ -76,8 +156,8 @@ public class DBStoreWriter extends DBStoreReader implements IDBStoreWriter String ecore = cdoPackage.getEcore(); boolean dynamic = cdoPackage.isDynamic(); CDOIDMetaRange metaIDRange = cdoPackage.getMetaIDRange(); - long lowerBound = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getLowerBound()).getValue(); - long upperBound = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getUpperBound()).getValue(); + long lowerBound = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getLowerBound()).getLongValue(); + long upperBound = metaIDRange == null ? 0L : ((CDOIDMeta)metaIDRange.getUpperBound()).getLongValue(); String sql = "INSERT INTO " + CDODBSchema.PACKAGES + " VALUES (?, ?, ?, ?, ?, ?, ?)"; DBUtil.trace(sql); @@ -169,51 +249,4 @@ public class DBStoreWriter extends DBStoreReader implements IDBStoreWriter DBUtil.insertRow(getConnection(), getStore().getDBAdapter(), CDODBSchema.FEATURES, id, classID, featureID, name, type, packageURI, classifierID, many, containment, idx); } - - public void writeRevision(CDORevision revision) - { - if (TRACER.isEnabled()) - { - TRACER.format("Inserting revision: {0}", revision); - } - - CDOClass cdoClass = revision.getCDOClass(); - IMappingStrategy mappingStrategy = getStore().getMappingStrategy(); - IClassMapping mapping = mappingStrategy.getClassMapping(cdoClass); - mapping.writeRevision(this, revision); - } - - public void commit() - { - try - { - if (TRACER.isEnabled()) - { - TRACER.format("Committing transaction: {0}", getView()); - } - - getConnection().commit(); - } - catch (SQLException ex) - { - throw new DBException(ex); - } - } - - public void rollback() - { - try - { - if (TRACER.isEnabled()) - { - TRACER.format("Rolling back transaction: {0}", getView()); - } - - getConnection().rollback(); - } - catch (SQLException ex) - { - throw new DBException(ex); - } - } } diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NoClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NoClassMapping.java index f4b18fd9d5..6b4544117c 100644 --- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NoClassMapping.java +++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/NoClassMapping.java @@ -85,13 +85,11 @@ public class NoClassMapping implements IClassMapping { } - public void readRevisionByTime(IDBStoreReader storeReader, CDORevision revision, long timeStamp, - int referenceChunk) + public void readRevisionByTime(IDBStoreReader storeReader, CDORevision revision, long timeStamp, int referenceChunk) { } - public void readRevisionByVersion(IDBStoreReader storeReader, CDORevision revision, int version, - int referenceChunk) + public void readRevisionByVersion(IDBStoreReader storeReader, CDORevision revision, int version, int referenceChunk) { } } diff --git a/plugins/org.eclipse.emf.cdo.server/.options b/plugins/org.eclipse.emf.cdo.server/.options index 007def7ea8..83038cb0e0 100644 --- a/plugins/org.eclipse.emf.cdo.server/.options +++ b/plugins/org.eclipse.emf.cdo.server/.options @@ -4,6 +4,7 @@ org.eclipse.emf.cdo.server/debug = true org.eclipse.emf.cdo.server/debug.protocol = true org.eclipse.emf.cdo.server/debug.repository = true org.eclipse.emf.cdo.server/debug.session = true +org.eclipse.emf.cdo.server/debug.transaction = true org.eclipse.emf.cdo.server/debug.revision = true org.eclipse.emf.cdo.server/debug.resource = true org.eclipse.emf.cdo.server/debug.store = true diff --git a/plugins/org.eclipse.emf.cdo.server/CommitTransactionIndicationOLD.java b/plugins/org.eclipse.emf.cdo.server/CommitTransactionIndicationOLD.java new file mode 100644 index 0000000000..e95e2bb548 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/CommitTransactionIndicationOLD.java @@ -0,0 +1,403 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * 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 + * Simon McDuff - https://bugs.eclipse.org/bugs/show_bug.cgi?id=201266 + **************************************************************************/ +package org.eclipse.emf.cdo.internal.server.protocol; + +import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl; +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.internal.protocol.revision.delta.CDORevisionDeltaImpl; +import org.eclipse.emf.cdo.internal.server.PackageManager; +import org.eclipse.emf.cdo.internal.server.Repository; +import org.eclipse.emf.cdo.internal.server.RevisionManager; +import org.eclipse.emf.cdo.internal.server.View; +import org.eclipse.emf.cdo.internal.server.bundle.OM; +import org.eclipse.emf.cdo.protocol.CDOProtocolConstants; +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; +import org.eclipse.emf.cdo.protocol.id.CDOIDUtil; +import org.eclipse.emf.cdo.protocol.model.CDOModelUtil; +import org.eclipse.emf.cdo.protocol.model.CDOPackage; +import org.eclipse.emf.cdo.protocol.model.CDOPackageManager; +import org.eclipse.emf.cdo.protocol.model.core.CDOCorePackage; +import org.eclipse.emf.cdo.protocol.model.resource.CDOResourcePackage; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.server.IStore; +import org.eclipse.emf.cdo.server.IStoreWriter; +import org.eclipse.emf.cdo.server.IView; +import org.eclipse.emf.cdo.server.StoreUtil; + +import org.eclipse.net4j.internal.util.om.trace.ContextTracer; +import org.eclipse.net4j.internal.util.transaction.Transaction; +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.io.ExtendedDataInputStream; +import org.eclipse.net4j.util.io.ExtendedDataOutputStream; +import org.eclipse.net4j.util.transaction.ITransaction; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * @author Eike Stepper + */ +@SuppressWarnings("unused") +public class CommitTransactionIndicationOLD extends CDOServerIndication +{ + private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, CommitTransactionIndication.class); + + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CommitTransactionIndication.class); + + private CDOPackage[] newPackages; + + private InternalCDORevision[] newResources; + + private InternalCDORevision[] newObjects; + + private CDORevisionDeltaImpl[] dirtyObjects; + + private CDOID[] dirtyIDs; + + private Map idMappings = new HashMap(); + + private long timeStamp; + + private PackageManager sessionPackageManager; + + private CDOPackageManager transactionPackageManager; + + private View view; + + private String rollbackMessage; + + public CommitTransactionIndicationOLD() + { + } + + @Override + protected short getSignalID() + { + return CDOProtocolConstants.SIGNAL_COMMIT_TRANSACTION; + } + + @Override + protected void indicating(ExtendedDataInputStream in) throws IOException + { + timeStamp = System.currentTimeMillis(); + sessionPackageManager = getPackageManager(); + transactionPackageManager = new TransactionPackageManager(); + + int viewID = in.readInt(); + view = (View)getSession().getView(viewID); + if (view == null || view.getViewType() != IView.Type.TRANSACTION) + { + throw new IllegalStateException("Illegal view: " + view); + } + + IStore store = getStore(); + IStoreWriter storeWriter = store.getWriter(view); + + try + { + StoreUtil.setReader(storeWriter); + newPackages = readNewPackages(in, storeWriter); + newResources = readNewResources(in, storeWriter); + newObjects = readNewObjects(in, storeWriter); + dirtyObjects = readDirtyObjects(in, storeWriter); + ITransaction storeTransaction = new Transaction(storeWriter, false); + + try + { + addPackages(storeTransaction, newPackages); + addRevisions(storeTransaction, newResources); + addRevisions(storeTransaction, newObjects); + writeRevisions(storeTransaction, dirtyObjects); + // addRevisions(storeTransaction, dirtyObjects); + + storeWriter.commit(); + storeTransaction.commit(); + } + catch (RuntimeException ex) + { + OM.LOG.error(ex); + rollbackMessage = ex.getLocalizedMessage(); + storeWriter.rollback(); + storeTransaction.rollback(); + } + } + finally + { + storeWriter.release(); + StoreUtil.setReader(null); + } + } + + @Override + protected void responding(ExtendedDataOutputStream out) throws IOException + { + if (rollbackMessage != null) + { + out.writeBoolean(false); + out.writeString(rollbackMessage); + } + else + { + out.writeBoolean(true); + out.writeLong(timeStamp); + for (CDOPackage newPackage : newPackages) + { + CDOIDUtil.writeMetaRange(out, newPackage.getMetaIDRange()); + } + + writeIDMappings(out); + if (dirtyIDs.length > 0) + { + // getSessionManager().notifyInvalidation(timeStamp, dirtyIDs, getSession()); + } + } + } + + private CDOPackage[] readNewPackages(ExtendedDataInputStream in, IStoreWriter storeWriter) throws IOException + { + int size = in.readInt(); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Reading {0} new packages", size); + } + + CDOPackage[] newPackages = new CDOPackage[size]; + for (int i = 0; i < size; i++) + { + newPackages[i] = CDOModelUtil.readPackage(transactionPackageManager, in); + mapMetaRange(newPackages[i]); + } + + return newPackages; + } + + private void mapMetaRange(CDOPackage newPackage) + { + Repository repository = getRepository(); + CDOIDMetaRange oldRange = newPackage.getMetaIDRange(); + if (oldRange != null && oldRange.isTemporary()) + { + CDOIDMetaRange newRange = repository.getMetaIDRange(oldRange.size()); + ((CDOPackageImpl)newPackage).setMetaIDRange(newRange); + + for (int l = 0; l < oldRange.size(); l++) + { + CDOID oldID = oldRange.get(l); + CDOID newID = newRange.get(l); + + if (TRACER.isEnabled()) + { + TRACER.format("Mapping ID: {0} --> {1}", oldID, newID); + } + + idMappings.put(oldID, newID); + } + } + } + + private InternalCDORevision[] readNewResources(ExtendedDataInputStream in, IStoreWriter storeWriter) + throws IOException + { + int size = in.readInt(); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Reading {0} new resources", size); + } + + return readRevisions(in, storeWriter, size); + } + + private InternalCDORevision[] readNewObjects(ExtendedDataInputStream in, IStoreWriter storeWriter) throws IOException + { + int size = in.readInt(); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Reading {0} new objects", size); + } + + return readRevisions(in, storeWriter, size); + } + + private CDORevisionDeltaImpl[] readDirtyObjects(ExtendedDataInputStream in, IStoreWriter storeWriter) + throws IOException + { + int size = in.readInt(); + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Reading {0} dirty objects", size); + } + + RevisionManager revisionManager = sessionPackageManager.getRepository().getRevisionManager(); + CDORevisionDeltaImpl[] deltas = new CDORevisionDeltaImpl[size]; + dirtyIDs = new CDOID[size]; + for (int i = 0; i < size; i++) + { + deltas[i] = new CDORevisionDeltaImpl(in, transactionPackageManager); + dirtyIDs[i] = deltas[i].getID(); + } + + return deltas; + } + + private InternalCDORevision[] readRevisions(ExtendedDataInputStream in, IStoreWriter storeWriter, int size) + throws IOException + { + RevisionManager revisionManager = sessionPackageManager.getRepository().getRevisionManager(); + InternalCDORevision[] revisions = new InternalCDORevision[size]; + for (int i = 0; i < size; i++) + { + revisions[i] = (InternalCDORevision)CDORevisionUtil.read(in, revisionManager, transactionPackageManager); + mapTemporaryID(revisions[i], storeWriter); + } + + return revisions; + } + + // TODO Remove newPackages parameter + private void addPackages(ITransaction storeTransaction, CDOPackage[] newPackages) + { + sessionPackageManager.addPackages(storeTransaction, newPackages); + } + + private void addRevisions(ITransaction storeTransaction, InternalCDORevision[] revisions) + { + RevisionManager revisionManager = getRevisionManager(); + for (InternalCDORevision revision : revisions) + { + revision.setCreated(timeStamp); + revision.adjustReferences(idMappings); + revisionManager.addRevision(storeTransaction, revision); + } + } + + // TODO Rename to addRevisionDeltas + // TODO Remove deltas parameter + private void writeRevisions(ITransaction storeTransaction, CDORevisionDeltaImpl[] deltas) + { + for (CDORevisionDeltaImpl delta : deltas) + { + delta.adjustReferences(idMappings); + getRevisionManager().addRevisionDelta(storeTransaction, delta); + } + } + + private void mapTemporaryID(InternalCDORevision revision, IStoreWriter storeWriter) + { + CDOID oldID = revision.getID(); + if (oldID.isTemporary()) + { + CDOID newID = storeWriter.primeNewObject(revision.getCDOClass()); + if (newID == null || newID.isNull() || newID.isMeta() || newID.isTemporary()) + { + throw new ImplementationError("Store writer returned bad CDOID " + newID); + } + + if (TRACER.isEnabled()) + { + TRACER.format("Mapping ID: {0} --> {1}", oldID, newID); + } + + idMappings.put(oldID, newID); + revision.setID(newID); + } + } + + private void writeIDMappings(ExtendedDataOutputStream out) throws IOException + { + for (Entry entry : idMappings.entrySet()) + { + CDOID oldID = entry.getKey(); + if (!oldID.isMeta()) + { + CDOID newID = entry.getValue(); + CDOIDUtil.write(out, oldID); + CDOIDUtil.write(out, newID); + } + } + + CDOIDUtil.write(out, CDOID.NULL); + } + + /** + * @author Eike Stepper + */ + private final class TransactionPackageManager implements CDOPackageManager + { + public TransactionPackageManager() + { + } + + public CDOIDObjectFactory getCDOIDObjectFactory() + { + return sessionPackageManager.getCDOIDObjectFactory(); + } + + public CDOPackage lookupPackage(String uri) + { + for (CDOPackage cdoPackage : newPackages) + { + if (ObjectUtil.equals(cdoPackage.getPackageURI(), uri)) + { + return cdoPackage; + } + } + + return sessionPackageManager.lookupPackage(uri); + } + + public CDOCorePackage getCDOCorePackage() + { + throw new UnsupportedOperationException(); + } + + public CDOResourcePackage getCDOResourcePackage() + { + throw new UnsupportedOperationException(); + } + + public int getPackageCount() + { + throw new UnsupportedOperationException(); + } + + public CDOPackage[] getPackages() + { + throw new UnsupportedOperationException(); + } + + public CDOPackage[] getElements() + { + throw new UnsupportedOperationException(); + } + + public boolean isEmpty() + { + throw new UnsupportedOperationException(); + } + + public void addListener(IListener listener) + { + throw new UnsupportedOperationException(); + } + + public void removeListener(IListener listener) + { + throw new UnsupportedOperationException(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java index e3d6665791..0acdc4442f 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/MEMStoreAccessor.java @@ -13,7 +13,6 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.protocol.id.CDOID; -import org.eclipse.emf.cdo.protocol.model.CDOClass; import org.eclipse.emf.cdo.protocol.model.CDOClassRef; import org.eclipse.emf.cdo.protocol.model.CDOFeature; import org.eclipse.emf.cdo.protocol.model.CDOPackage; @@ -129,40 +128,69 @@ public class MEMStoreAccessor extends StoreAccessor implements IStoreReader, ISt throw new UnsupportedOperationException(); } - public CDOID primeNewObject(CDOClass cdoClass) + public void beginCommit(CommitContext context) + { + // Do nothing + } + + public CDOID createNewResourceID(CommitContext context, int i, CDORevision newResource) { return getStore().getNextCDOID(); } - public void writePackages(CDOPackage... cdoPackages) + public CDOID createNewObjectID(CommitContext context, int i, CDORevision newObject) { + return getStore().getNextCDOID(); } - public void writeRevision(CDORevision revision) + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevision[] dirtyObjects) { - newRevisions.add(revision); + writeRevisions(newResources); + writeRevisions(newObjects); + writeRevisions(dirtyObjects); + commit(); } - @Override - public void writeRevisionDelta(CDORevisionDelta delta) + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevisionDelta[] dirtyObjectDeltas) { - InternalCDORevision revision = (InternalCDORevision)getStore().getRevision(delta.getID()); - InternalCDORevision newRevision = (InternalCDORevision)CDORevisionUtil.copy(revision); - delta.apply(newRevision); - newRevisions.add(newRevision); + writeRevisions(newResources); + writeRevisions(newObjects); + writeRevisionDeltas(dirtyObjectDeltas); + commit(); } - public void commit() + public void cancelCommit(CommitContext context) { - MEMStore store = getStore(); - for (CDORevision revision : newRevisions) + } + + protected void writeRevisions(CDORevision[] revisions) + { + for (CDORevision revision : revisions) { - store.addRevision(revision); + newRevisions.add(revision); } } - public void rollback() + protected void writeRevisionDeltas(CDORevisionDelta[] revisionDeltas) { + for (CDORevisionDelta revisionDelta : revisionDeltas) + { + CDORevision revision = getStore().getRevision(revisionDelta.getID()); + CDORevision newRevision = CDORevisionUtil.copy(revision); + revisionDelta.apply(newRevision); + newRevisions.add(newRevision); + } + } + + protected void commit() + { + MEMStore store = getStore(); + for (CDORevision revision : newRevisions) + { + store.addRevision(revision); + } } @Override diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java index 24e1bbb4ed..49951fcc78 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/NOOPStoreAccessor.java @@ -11,12 +11,12 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.protocol.id.CDOID; -import org.eclipse.emf.cdo.protocol.model.CDOClass; import org.eclipse.emf.cdo.protocol.model.CDOClassRef; import org.eclipse.emf.cdo.protocol.model.CDOFeature; import org.eclipse.emf.cdo.protocol.model.CDOPackage; import org.eclipse.emf.cdo.protocol.model.CDOPackageInfo; import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IStoreChunkReader; import org.eclipse.emf.cdo.server.IStoreReader; @@ -99,24 +99,31 @@ public class NOOPStoreAccessor extends StoreAccessor implements IStoreReader, IS throw new UnsupportedOperationException(); } - public CDOID primeNewObject(CDOClass cdoClass) + public void beginCommit(CommitContext context) + { + } + + public CDOID createNewResourceID(CommitContext context, int i, CDORevision newResource) { return getStore().getNextCDOID(); } - public void writePackages(CDOPackage... cdoPackages) + public CDOID createNewObjectID(CommitContext context, int i, CDORevision newObject) { + return getStore().getNextCDOID(); } - public void writeRevision(CDORevision revision) + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevision[] dirtyObjects) { } - public void commit() + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevisionDelta[] dirtyObjectDeltas) { } - public void rollback() + public void cancelCommit(CommitContext context) { } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/PackageManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/PackageManager.java index 68b6ebdfbd..3fac8c83a8 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/PackageManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/PackageManager.java @@ -14,16 +14,11 @@ import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl; import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageManagerImpl; import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; import org.eclipse.emf.cdo.protocol.model.CDOModelUtil; -import org.eclipse.emf.cdo.protocol.model.CDOPackage; import org.eclipse.emf.cdo.protocol.model.CDOPackageInfo; import org.eclipse.emf.cdo.server.IPackageManager; import org.eclipse.emf.cdo.server.IStoreReader; -import org.eclipse.emf.cdo.server.IStoreWriter; import org.eclipse.emf.cdo.server.StoreUtil; -import org.eclipse.net4j.util.transaction.ITransaction; -import org.eclipse.net4j.util.transaction.ITransactionalOperation; - import java.util.Collection; /** @@ -48,16 +43,6 @@ public class PackageManager extends CDOPackageManagerImpl implements IPackageMan return repository.getStore().getCDOIDObjectFactory(); } - public void addPackages(ITransaction storeTransaction, CDOPackage[] cdoPackages) - { - for (CDOPackage cdoPackage : cdoPackages) - { - ((CDOPackageImpl)cdoPackage).setPackageManager(this); - } - - storeTransaction.execute(new AddPackagesOperation(cdoPackages)); - } - @Override protected void resolve(CDOPackageImpl cdoPackage) { @@ -98,34 +83,4 @@ public class PackageManager extends CDOPackageManagerImpl implements IPackageMan } } } - - /** - * @author Eike Stepper - */ - private final class AddPackagesOperation implements ITransactionalOperation - { - private CDOPackage[] cdoPackages; - - private AddPackagesOperation(CDOPackage[] cdoPackages) - { - this.cdoPackages = cdoPackages; - } - - public void phase1(IStoreWriter storeWriter) throws Exception - { - storeWriter.writePackages(cdoPackages); - } - - public void phase2(IStoreWriter storeWriter) - { - for (CDOPackage cdoPackage : cdoPackages) - { - addPackage(cdoPackage); - } - } - - public void undoPhase1(IStoreWriter storeWriter) - { - } - } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java index 97a1405b4c..29d1838976 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java @@ -230,6 +230,11 @@ public class Repository extends Container implements IReposi throw new IllegalArgumentException("store is null"); } + if (isSupportingRevisionDeltas() && !store.hasWriteDeltaSupport()) + { + throw new IllegalStateException("Store without revision delta support"); + } + if (isSupportingAudits() && !store.hasAuditingSupport()) { throw new IllegalStateException("Store without auditing support"); diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RevisionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RevisionManager.java index a3a4574e32..f4d8cdb5c0 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RevisionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/RevisionManager.java @@ -15,25 +15,19 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.internal.protocol.model.CDOClassImpl; import org.eclipse.emf.cdo.internal.protocol.revision.CDORevisionResolverImpl; import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; -import org.eclipse.emf.cdo.internal.protocol.revision.delta.CDORevisionDeltaImpl; import org.eclipse.emf.cdo.protocol.id.CDOID; import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; import org.eclipse.emf.cdo.protocol.model.CDOFeature; import org.eclipse.emf.cdo.protocol.model.resource.CDOPathFeature; import org.eclipse.emf.cdo.protocol.revision.CDOReferenceProxy; -import org.eclipse.emf.cdo.protocol.revision.CDORevision; -import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; import org.eclipse.emf.cdo.server.IRevisionManager; import org.eclipse.emf.cdo.server.IStoreChunkReader; import org.eclipse.emf.cdo.server.IStoreReader; -import org.eclipse.emf.cdo.server.IStoreWriter; import org.eclipse.emf.cdo.server.StoreUtil; import org.eclipse.emf.cdo.server.IRepository.Props; import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk; import org.eclipse.net4j.util.collection.MoveableList; -import org.eclipse.net4j.util.transaction.ITransaction; -import org.eclipse.net4j.util.transaction.ITransactionalOperation; import java.util.ArrayList; import java.util.Collection; @@ -64,16 +58,6 @@ public class RevisionManager extends CDORevisionResolverImpl implements IRevisio return repository.getStore().getCDOIDObjectFactory(); } - public void addRevision(ITransaction storeTransaction, InternalCDORevision revision) - { - storeTransaction.execute(new AddRevisionOperation(revision)); - } - - public void addRevisionDelta(ITransaction storeTransaction, CDORevisionDeltaImpl delta) - { - storeTransaction.execute(new AddRevisionDeltaOperation(delta)); - } - public CDOID resolveReferenceProxy(CDOReferenceProxy referenceProxy) { throw new UnsupportedOperationException("Reference proxies not supported on server side"); @@ -269,93 +253,4 @@ public class RevisionManager extends CDORevisionResolverImpl implements IRevisio String capacity = repository.getProperties().get(prop); return capacity == null ? 0 : Integer.valueOf(capacity); } - - /** - * @author Eike Stepper - */ - private final class AddRevisionOperation implements ITransactionalOperation - { - private InternalCDORevision revision; - - private AddRevisionOperation(InternalCDORevision revision) - { - this.revision = revision; - } - - public void phase1(IStoreWriter storeWriter) throws Exception - { - // Can throw an exception if duplicate - storeWriter.writeRevision(revision); - } - - public void phase2(IStoreWriter storeWriter) - { - addRevision(revision); - if (revision.isResource()) - { - String path = (String)revision.getData().get(cdoPathFeature, -1); - repository.getResourceManager().registerResource(revision.getID(), path); - } - } - - public void undoPhase1(IStoreWriter storeWriter) - { - } - } - - /** - * @author Simon McDuff - */ - private final class AddRevisionDeltaOperation implements ITransactionalOperation - { - private CDORevisionDeltaImpl revisionDelta; - - private InternalCDORevision dirtyRevision; - - private AddRevisionDeltaOperation(CDORevisionDeltaImpl revisionDelta) - { - this.revisionDelta = revisionDelta; - } - - public void phase1(IStoreWriter storeWriter) throws Exception - { - boolean supportDelta = getRepository().isSupportingRevisionDeltas(); - InternalCDORevision originRevision = getRevisionByVersion(revisionDelta.getID(), CDORevision.UNCHUNKED, - revisionDelta.getOriginVersion(), !supportDelta); - - if (originRevision != null) - { - dirtyRevision = (InternalCDORevision)CDORevisionUtil.copy(originRevision); - revisionDelta.apply(dirtyRevision); - } - else if (!supportDelta) - { - // Origin revision need to be accessible for stores that do not support deltas - throw new IllegalStateException("Can not retrieve origin revision"); - } - - if (supportDelta) - { - // Can throw an exception if duplicate - storeWriter.writeRevisionDelta(revisionDelta); - } - else - { - // Can throw an exception if duplicate - storeWriter.writeRevision(dirtyRevision); - } - } - - public void phase2(IStoreWriter storeWriter) - { - if (dirtyRevision != null) - { - addRevision(dirtyRevision); - } - } - - public void undoPhase1(IStoreWriter storeWriter) - { - } - } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java index bcf3462ee2..f0410c73cf 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Session.java @@ -11,7 +11,6 @@ **************************************************************************/ package org.eclipse.emf.cdo.internal.server; -import org.eclipse.emf.cdo.internal.protocol.model.CDOClassImpl; import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.internal.server.bundle.OM; import org.eclipse.emf.cdo.internal.server.protocol.CDOServerProtocol; @@ -54,7 +53,7 @@ public class Session extends Container implements ISession, CDOIDProvider private boolean disableLegacyObjects; - private ConcurrentMap views = new ConcurrentHashMap(); + private ConcurrentMap views = new ConcurrentHashMap(); private IListener protocolListener = new LifecycleEventAdapter() { @@ -120,7 +119,7 @@ public class Session extends Container implements ISession, CDOIDProvider return views.values().toArray(new View[views.size()]); } - public View getView(int viewID) + public IView getView(int viewID) { return views.get(viewID); } @@ -129,7 +128,7 @@ public class Session extends Container implements ISession, CDOIDProvider { if (kind == CDOProtocolConstants.VIEW_CLOSED) { - View view = views.remove(viewID); + IView view = views.remove(viewID); if (view != null) { fireElementRemovedEvent(view); @@ -137,29 +136,31 @@ public class Session extends Container implements ISession, CDOIDProvider } else { - Type viewType = getViewType(kind); - View view = new View(this, viewID, viewType); + IView view = createView(kind, viewID); views.put(viewID, view); fireElementAddedEvent(view); } } - private Type getViewType(byte kind) + private IView createView(byte kind, int viewID) { switch (kind) { case CDOProtocolConstants.VIEW_TRANSACTION: - return Type.TRANSACTION; + return new Transaction(this, viewID); + case CDOProtocolConstants.VIEW_READONLY: - return Type.READONLY; + return new View(this, viewID, Type.READONLY); + case CDOProtocolConstants.VIEW_AUDIT: - return Type.AUDIT; - } + return new View(this, viewID, Type.AUDIT); - throw new ImplementationError("Invalid kind: " + kind); + default: + throw new ImplementationError("Invalid kind: " + kind); + } } - public void notifyInvalidation(long timeStamp, CDOID[] dirtyIDs) + public void notifyInvalidation(long timeStamp, List dirtyIDs) { try { @@ -203,7 +204,7 @@ public class Session extends Container implements ISession, CDOIDProvider List additionalRevisions) { RevisionManager revisionManager = getSessionManager().getRepository().getRevisionManager(); - CDOClassImpl cdoClass = (CDOClassImpl)revision.getCDOClass(); + CDOClass cdoClass = revision.getCDOClass(); CDOFeature[] features = cdoClass.getAllFeatures(); for (int i = 0; i < features.length; i++) { diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java index 8775779744..7adafdbdd4 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/SessionManager.java @@ -23,6 +23,7 @@ import org.eclipse.net4j.internal.util.container.Container; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -103,13 +104,13 @@ public class SessionManager extends Container implements ISessionManag } } - public void notifyInvalidation(long timeStamp, CDOID[] dirtyObjects, Session excludedSession) + public void notifyInvalidation(long timeStamp, List dirtyIDs, Session excludedSession) { for (Session session : getSessions()) { if (session != excludedSession) { - session.notifyInvalidation(timeStamp, dirtyObjects); + session.notifyInvalidation(timeStamp, dirtyIDs); } } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java index 0c0b1a89b5..a2b4252da3 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/StoreAccessor.java @@ -13,7 +13,6 @@ package org.eclipse.emf.cdo.internal.server; import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.protocol.revision.CDORevision; -import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.IStoreAccessor; import org.eclipse.emf.cdo.server.IView; @@ -89,9 +88,4 @@ public class StoreAccessor implements IStoreAccessor { return (InternalCDORevision)revision; } - - public void writeRevisionDelta(CDORevisionDelta delta) - { - throw new UnsupportedOperationException(); - } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java new file mode 100644 index 0000000000..dfd30ea352 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Transaction.java @@ -0,0 +1,480 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * 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.internal.server; + +import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl; +import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; +import org.eclipse.emf.cdo.internal.protocol.revision.delta.InternalCDORevisionDelta; +import org.eclipse.emf.cdo.internal.server.bundle.OM; +import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; +import org.eclipse.emf.cdo.protocol.model.CDOPackage; +import org.eclipse.emf.cdo.protocol.model.CDOPackageManager; +import org.eclipse.emf.cdo.protocol.model.core.CDOCorePackage; +import org.eclipse.emf.cdo.protocol.model.resource.CDOResourcePackage; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionResolver; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.server.IPackageManager; +import org.eclipse.emf.cdo.server.IRepository; +import org.eclipse.emf.cdo.server.IStoreWriter; +import org.eclipse.emf.cdo.server.ITransaction; +import org.eclipse.emf.cdo.server.StoreUtil; + +import org.eclipse.net4j.internal.util.om.trace.ContextTracer; +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.event.IListener; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * @author Eike Stepper + */ +public class Transaction extends View implements ITransaction, IStoreWriter.CommitContext +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION, Transaction.class); + + private IRepository repository; + + private IPackageManager repositoryPackageManager; + + private TransactionPackageManager packageManager; + + private IStoreWriter storeWriter; + + private long timeStamp; + + private CDOPackage[] newPackages; + + private CDORevision[] newResources; + + private CDORevision[] newObjects; + + private CDORevisionDelta[] dirtyObjectDeltas; + + private CDORevision[] dirtyObjects; + + private List metaIDRanges = new ArrayList(); + + private ConcurrentMap idMappings = new ConcurrentHashMap(); + + private String rollbackMessage; + + public Transaction(Session session, int viewID) + { + super(session, viewID, Type.TRANSACTION); + repository = session.getSessionManager().getRepository(); + repositoryPackageManager = repository.getPackageManager(); + packageManager = new TransactionPackageManager(); + + } + + public int getTransactionID() + { + return getViewID(); + } + + public long getTimeStamp() + { + return timeStamp; + } + + public TransactionPackageManager getPackageManager() + { + return packageManager; + } + + public CDOPackage[] getNewPackages() + { + return newPackages; + } + + public int getNumberOfNewResources() + { + return newResources == null ? 0 : newResources.length; + } + + public int getNumberOfNewObjects() + { + return newObjects == null ? 0 : newObjects.length; + } + + public int getNumberOfDirtyObjects() + { + return dirtyObjects == null ? 0 : dirtyObjects.length; + } + + public List getMetaIDRanges() + { + return Collections.unmodifiableList(metaIDRanges); + } + + public Map getIdMappings() + { + return Collections.unmodifiableMap(idMappings); + } + + public String getRollbackMessage() + { + return rollbackMessage; + } + + public void commit(CDOPackage[] newPackages, CDORevision[] newResources, CDORevision[] newObjects, + CDORevisionDelta[] dirtyObjectDeltas) + { + timeStamp = System.currentTimeMillis(); + this.newPackages = newPackages; + this.newResources = newResources; + this.newObjects = newObjects; + this.dirtyObjectDeltas = dirtyObjectDeltas; + dirtyObjects = new CDORevision[dirtyObjectDeltas.length]; + + storeWriter = repository.getStore().getWriter(this); + StoreUtil.setReader(storeWriter); + + try + { + adjustMetaRanges(); + beginCommit(); + populateIDMappings(); + adjust(); + finishCommit(); + updateInfraStructure(); + } + catch (RuntimeException ex) + { + OM.LOG.error(ex); + rollbackMessage = ex.getMessage(); + cancelCommit(); + } + finally + { + if (storeWriter != null) + { + StoreUtil.setReader(null); + storeWriter.release(); + storeWriter = null; + } + } + } + + public void postCommit(boolean success) + { + try + { + int modifications = dirtyObjectDeltas.length; + if (success && modifications > 0) + { + List dirtyIDs = new ArrayList(modifications); + for (int i = 0; i < modifications; i++) + { + dirtyIDs.add(dirtyObjectDeltas[i].getID()); + } + + SessionManager sessionManager = (SessionManager)repository.getSessionManager(); + sessionManager.notifyInvalidation(timeStamp, dirtyIDs, getSession()); + } + } + finally + { + timeStamp = 0L; + packageManager.clear(); + metaIDRanges.clear(); + idMappings.clear(); + rollbackMessage = null; + newPackages = null; + newResources = null; + newObjects = null; + dirtyObjectDeltas = null; + dirtyObjects = null; + } + } + + private void adjustMetaRanges() + { + for (CDOPackage newPackage : newPackages) + { + adjustMetaRange(newPackage); + } + } + + private void adjustMetaRange(CDOPackage newPackage) + { + CDOIDMetaRange oldRange = newPackage.getMetaIDRange(); + if (!oldRange.isTemporary()) + { + throw new IllegalStateException("!oldRange.isTemporary()"); + } + + CDOIDMetaRange newRange = repository.getMetaIDRange(oldRange.size()); + ((CDOPackageImpl)newPackage).setMetaIDRange(newRange); + for (int l = 0; l < oldRange.size(); l++) + { + CDOIDTemp oldID = (CDOIDTemp)oldRange.get(l); + CDOID newID = newRange.get(l); + if (TRACER.isEnabled()) + { + TRACER.format("Mapping meta ID: {0} --> {1}", oldID, newID); + } + + idMappings.put(oldID, newID); + } + + metaIDRanges.add(newRange); + } + + private void beginCommit() + { + storeWriter.beginCommit(this); + } + + private void populateIDMappings() + { + for (int i = 0; i < newResources.length; i++) + { + CDORevision newResource = newResources[i]; + CDOID newID = storeWriter.createNewResourceID(this, i, newResource); + addIDMapping((CDOIDTemp)newResource.getID(), newID); + } + + for (int i = 0; i < newObjects.length; i++) + { + CDORevision newObject = newObjects[i]; + CDOID newID = storeWriter.createNewObjectID(this, i, newObject); + addIDMapping((CDOIDTemp)newObject.getID(), newID); + } + } + + private void addIDMapping(CDOIDTemp oldID, CDOID newID) + { + if (newID == null) + { + throw new IllegalArgumentException("newID == null"); + } + + CDOID previousMapping = idMappings.putIfAbsent(oldID, newID); + if (previousMapping != null) + { + throw new IllegalStateException("previousMapping != null"); + } + } + + private void adjust() + { + for (CDORevision newResource : newResources) + { + adjustRevision((InternalCDORevision)newResource); + } + + for (CDORevision newObject : newObjects) + { + adjustRevision((InternalCDORevision)newObject); + } + + for (CDORevisionDelta dirtyObjectDelta : dirtyObjectDeltas) + { + ((InternalCDORevisionDelta)dirtyObjectDelta).adjustReferences(idMappings); + } + } + + private void adjustRevision(InternalCDORevision revision) + { + revision.setID(idMappings.get(revision.getID())); + revision.setCreated(timeStamp); + revision.adjustReferences(idMappings); + } + + private void computeDirtyObjects(boolean failOnNull) + { + for (int i = 0; i < dirtyObjectDeltas.length; i++) + { + dirtyObjects[i] = computeDirtyObject(dirtyObjectDeltas[i]); + if (dirtyObjects[i] == null && failOnNull) + { + throw new IllegalStateException("Can not retrieve origin revision for " + dirtyObjectDeltas[i]); + } + } + } + + private CDORevision computeDirtyObject(CDORevisionDelta dirtyObjectDelta) + { + CDOID id = dirtyObjectDelta.getID(); + int version = dirtyObjectDelta.getOriginVersion(); + + CDORevisionResolver revisionResolver = repository.getRevisionManager(); + CDORevision originObject = revisionResolver.getRevisionByVersion(id, CDORevision.UNCHUNKED, version, false); + if (originObject != null) + { + CDORevision dirtyObject = CDORevisionUtil.copy(originObject); + dirtyObjectDelta.apply(dirtyObject); + ((InternalCDORevision)dirtyObject).setCreated(timeStamp); + return dirtyObject; + } + + return null; + } + + private void finishCommit() + { + if (repository.isSupportingRevisionDeltas()) + { + computeDirtyObjects(false); + storeWriter.finishCommit(this, newResources, newObjects, dirtyObjectDeltas); + } + else + { + computeDirtyObjects(true); + storeWriter.finishCommit(this, newResources, newObjects, dirtyObjects); + } + } + + private void cancelCommit() + { + if (storeWriter != null) + { + try + { + storeWriter.cancelCommit(this); + } + catch (RuntimeException ex) + { + OM.LOG.warn("Problem while rolling back the transaction", ex); + } + } + } + + private void updateInfraStructure() + { + try + { + addNewPackages(); + addRevisions(newResources); + addRevisions(newObjects); + addRevisions(dirtyObjects); + } + catch (RuntimeException ex) + { + // TODO Rethink this case + OM.LOG.error("FATAL: Memory infrastructure corrupted after successful commit operation of the store"); + } + } + + private void addNewPackages() + { + PackageManager packageManager = (PackageManager)repository.getPackageManager(); + for (int i = 0; i < newPackages.length; i++) + { + CDOPackage cdoPackage = newPackages[i]; + packageManager.addPackage(cdoPackage); + } + } + + private void addRevisions(CDORevision[] revisions) + { + RevisionManager revisionManager = (RevisionManager)repository.getRevisionManager(); + for (CDORevision revision : revisions) + { + if (revision != null) + { + revisionManager.addRevision((InternalCDORevision)revision); + } + } + } + + /** + * @author Eike Stepper + */ + public final class TransactionPackageManager implements CDOPackageManager + { + + private List newPackages = new ArrayList(); + + public TransactionPackageManager() + { + } + + public void addPackage(CDOPackage cdoPackage) + { + newPackages.add(cdoPackage); + } + + public void clear() + { + newPackages.clear(); + } + + public CDOIDObjectFactory getCDOIDObjectFactory() + { + return repositoryPackageManager.getCDOIDObjectFactory(); + } + + public CDOPackage lookupPackage(String uri) + { + for (CDOPackage cdoPackage : newPackages) + { + if (ObjectUtil.equals(cdoPackage.getPackageURI(), uri)) + { + return cdoPackage; + } + } + + return repositoryPackageManager.lookupPackage(uri); + } + + public CDOCorePackage getCDOCorePackage() + { + return repositoryPackageManager.getCDOCorePackage(); + } + + public CDOResourcePackage getCDOResourcePackage() + { + return repositoryPackageManager.getCDOResourcePackage(); + } + + public int getPackageCount() + { + throw new UnsupportedOperationException(); + } + + public CDOPackage[] getPackages() + { + throw new UnsupportedOperationException(); + } + + public CDOPackage[] getElements() + { + throw new UnsupportedOperationException(); + } + + public boolean isEmpty() + { + throw new UnsupportedOperationException(); + } + + public void addListener(IListener listener) + { + throw new UnsupportedOperationException(); + } + + public void removeListener(IListener listener) + { + throw new UnsupportedOperationException(); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/bundle/OM.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/bundle/OM.java index cf3caaf39b..fc00e26507 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/bundle/OM.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/bundle/OM.java @@ -35,6 +35,8 @@ public abstract class OM public static final OMTracer DEBUG_SESSION = DEBUG.tracer("session"); //$NON-NLS-1$ + public static final OMTracer DEBUG_TRANSACTION = DEBUG.tracer("transaction"); //$NON-NLS-1$ + public static final OMTracer DEBUG_REVISION = DEBUG.tracer("revision"); //$NON-NLS-1$ public static final OMTracer DEBUG_RESOURCE = DEBUG.tracer("resource"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java index 363ecb3dd4..6a36e48636 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/CommitTransactionIndication.java @@ -11,75 +11,41 @@ **************************************************************************/ package org.eclipse.emf.cdo.internal.server.protocol; -import org.eclipse.emf.cdo.internal.protocol.model.CDOPackageImpl; -import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.internal.protocol.revision.delta.CDORevisionDeltaImpl; -import org.eclipse.emf.cdo.internal.server.PackageManager; -import org.eclipse.emf.cdo.internal.server.Repository; -import org.eclipse.emf.cdo.internal.server.RevisionManager; -import org.eclipse.emf.cdo.internal.server.View; +import org.eclipse.emf.cdo.internal.server.Transaction; +import org.eclipse.emf.cdo.internal.server.Transaction.TransactionPackageManager; import org.eclipse.emf.cdo.internal.server.bundle.OM; import org.eclipse.emf.cdo.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.protocol.id.CDOID; import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; -import org.eclipse.emf.cdo.protocol.id.CDOIDObjectFactory; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import org.eclipse.emf.cdo.protocol.id.CDOIDUtil; import org.eclipse.emf.cdo.protocol.model.CDOModelUtil; import org.eclipse.emf.cdo.protocol.model.CDOPackage; -import org.eclipse.emf.cdo.protocol.model.CDOPackageManager; -import org.eclipse.emf.cdo.protocol.model.core.CDOCorePackage; -import org.eclipse.emf.cdo.protocol.model.resource.CDOResourcePackage; +import org.eclipse.emf.cdo.protocol.revision.CDORevision; +import org.eclipse.emf.cdo.protocol.revision.CDORevisionResolver; import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; -import org.eclipse.emf.cdo.server.IStore; -import org.eclipse.emf.cdo.server.IStoreWriter; +import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.server.IRepository; import org.eclipse.emf.cdo.server.IView; -import org.eclipse.emf.cdo.server.StoreUtil; import org.eclipse.net4j.internal.util.om.trace.ContextTracer; -import org.eclipse.net4j.internal.util.transaction.Transaction; -import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.ObjectUtil; -import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.io.ExtendedDataInputStream; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; -import org.eclipse.net4j.util.transaction.ITransaction; import java.io.IOException; -import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * @author Eike Stepper */ -@SuppressWarnings("unused") public class CommitTransactionIndication extends CDOServerIndication { private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, CommitTransactionIndication.class); - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CommitTransactionIndication.class); - - private CDOPackage[] newPackages; - - private InternalCDORevision[] newResources; - - private InternalCDORevision[] newObjects; - - private CDORevisionDeltaImpl[] dirtyObjects; - - private CDOID[] dirtyIDs; - - private Map idMappings = new HashMap(); - - private long timeStamp; - - private PackageManager sessionPackageManager; - - private CDOPackageManager transactionPackageManager; - - private View view; - - private String rollbackMessage; + private Transaction transaction; public CommitTransactionIndication() { @@ -94,305 +60,114 @@ public class CommitTransactionIndication extends CDOServerIndication @Override protected void indicating(ExtendedDataInputStream in) throws IOException { - timeStamp = System.currentTimeMillis(); - sessionPackageManager = getPackageManager(); - transactionPackageManager = new TransactionPackageManager(); + IRepository repository = getRepository(); + CDORevisionResolver revisionResolver = repository.getRevisionManager(); int viewID = in.readInt(); - view = getSession().getView(viewID); - if (view == null || view.getViewType() != IView.Type.TRANSACTION) - { - throw new IllegalStateException("Illegal view: " + view); - } - - IStore store = getStore(); - IStoreWriter storeWriter = store.getWriter(view); - - try - { - StoreUtil.setReader(storeWriter); - newPackages = readNewPackages(in, storeWriter); - newResources = readNewResources(in, storeWriter); - newObjects = readNewObjects(in, storeWriter); - dirtyObjects = readDirtyObjects(in, storeWriter); - ITransaction storeTransaction = new Transaction(storeWriter, false); + transaction = getTransaction(viewID); + TransactionPackageManager packageManager = transaction.getPackageManager(); - try - { - addPackages(storeTransaction, newPackages); - addRevisions(storeTransaction, newResources); - addRevisions(storeTransaction, newObjects); - writeRevisions(storeTransaction, dirtyObjects); - // addRevisions(storeTransaction, dirtyObjects); + CDOPackage[] newPackages = new CDOPackage[in.readInt()]; + CDORevision[] newResources = new CDORevision[in.readInt()]; + CDORevision[] newObjects = new CDORevision[in.readInt()]; + CDORevisionDelta[] dirtyObjectDeltas = new CDORevisionDelta[in.readInt()]; - storeWriter.commit(); - storeTransaction.commit(); - } - catch (RuntimeException ex) - { - OM.LOG.error(ex); - rollbackMessage = ex.getLocalizedMessage(); - storeWriter.rollback(); - storeTransaction.rollback(); - } - } - finally - { - storeWriter.release(); - StoreUtil.setReader(null); - } - } - - @Override - protected void responding(ExtendedDataOutputStream out) throws IOException - { - if (rollbackMessage != null) - { - out.writeBoolean(false); - out.writeString(rollbackMessage); - } - else - { - out.writeBoolean(true); - out.writeLong(timeStamp); - for (CDOPackage newPackage : newPackages) - { - CDOIDUtil.writeMetaRange(out, newPackage.getMetaIDRange()); - } - - writeIDMappings(out); - if (dirtyIDs.length > 0) - { - getSessionManager().notifyInvalidation(timeStamp, dirtyIDs, getSession()); - } - } - } - - private CDOPackage[] readNewPackages(ExtendedDataInputStream in, IStoreWriter storeWriter) throws IOException - { - int size = in.readInt(); + // New packages if (PROTOCOL.isEnabled()) { - PROTOCOL.format("Reading {0} new packages", size); + PROTOCOL.format("Reading {0} new packages", newPackages.length); } - Repository repository = getRepository(); - CDOPackage[] newPackages = new CDOPackage[size]; - for (int i = 0; i < size; i++) + for (int i = 0; i < newPackages.length; i++) { - newPackages[i] = CDOModelUtil.readPackage(transactionPackageManager, in); - CDOIDMetaRange oldRange = newPackages[i].getMetaIDRange(); - if (oldRange != null && oldRange.isTemporary()) - { - CDOIDMetaRange newRange = repository.getMetaIDRange(oldRange.size()); - ((CDOPackageImpl)newPackages[i]).setMetaIDRange(newRange); - - for (int l = 0; l < oldRange.size(); l++) - { - CDOID oldID = oldRange.get(l); - CDOID newID = newRange.get(l); - - if (TRACER.isEnabled()) - { - TRACER.format("Mapping ID: {0} --> {1}", oldID, newID); - } - - idMappings.put(oldID, newID); - } - } + newPackages[i] = CDOModelUtil.readPackage(packageManager, in); + packageManager.addPackage(newPackages[i]); } - return newPackages; - } - - private InternalCDORevision[] readNewResources(ExtendedDataInputStream in, IStoreWriter storeWriter) - throws IOException - { - int size = in.readInt(); + // New resources if (PROTOCOL.isEnabled()) { - PROTOCOL.format("Reading {0} new resources", size); + PROTOCOL.format("Reading {0} new resources", newResources.length); } - return readRevisions(in, storeWriter, size); - } - - private InternalCDORevision[] readNewObjects(ExtendedDataInputStream in, IStoreWriter storeWriter) throws IOException - { - int size = in.readInt(); - if (PROTOCOL.isEnabled()) + for (int i = 0; i < newResources.length; i++) { - PROTOCOL.format("Reading {0} new objects", size); + newResources[i] = CDORevisionUtil.read(in, revisionResolver, packageManager); } - return readRevisions(in, storeWriter, size); - } - - private CDORevisionDeltaImpl[] readDirtyObjects(ExtendedDataInputStream in, IStoreWriter storeWriter) - throws IOException - { - int size = in.readInt(); + // New objects if (PROTOCOL.isEnabled()) { - PROTOCOL.format("Reading {0} dirty objects", size); + PROTOCOL.format("Reading {0} new objects", newObjects.length); } - RevisionManager revisionManager = sessionPackageManager.getRepository().getRevisionManager(); - CDORevisionDeltaImpl[] deltas = new CDORevisionDeltaImpl[size]; - dirtyIDs = new CDOID[size]; - for (int i = 0; i < size; i++) + for (int i = 0; i < newObjects.length; i++) { - deltas[i] = new CDORevisionDeltaImpl(in, transactionPackageManager); - dirtyIDs[i] = deltas[i].getID(); + newObjects[i] = CDORevisionUtil.read(in, revisionResolver, packageManager); } - return deltas; - } - - private InternalCDORevision[] readRevisions(ExtendedDataInputStream in, IStoreWriter storeWriter, int size) - throws IOException - { - RevisionManager revisionManager = sessionPackageManager.getRepository().getRevisionManager(); - InternalCDORevision[] revisions = new InternalCDORevision[size]; - for (int i = 0; i < size; i++) + // Dirty objects + if (PROTOCOL.isEnabled()) { - revisions[i] = (InternalCDORevision)CDORevisionUtil.read(in, revisionManager, transactionPackageManager); - mapTemporaryID(revisions[i], storeWriter); + PROTOCOL.format("Reading {0} dirty object deltas", dirtyObjectDeltas.length); } - return revisions; - } - - // TODO Remove newPackages parameter - private void addPackages(ITransaction storeTransaction, CDOPackage[] newPackages) - { - sessionPackageManager.addPackages(storeTransaction, newPackages); - } - - private void addRevisions(ITransaction storeTransaction, InternalCDORevision[] revisions) - { - RevisionManager revisionManager = getRevisionManager(); - for (InternalCDORevision revision : revisions) + for (int i = 0; i < dirtyObjectDeltas.length; i++) { - revision.setCreated(timeStamp); - revision.adjustReferences(idMappings); - revisionManager.addRevision(storeTransaction, revision); + dirtyObjectDeltas[i] = new CDORevisionDeltaImpl(in, packageManager); } - } - // TODO Rename to addRevisionDeltas - // TODO Remove deltas parameter - private void writeRevisions(ITransaction storeTransaction, CDORevisionDeltaImpl[] deltas) - { - for (CDORevisionDeltaImpl delta : deltas) - { - delta.adjustReferences(idMappings); - getRevisionManager().addRevisionDelta(storeTransaction, delta); - } + transaction.commit(newPackages, newResources, newObjects, dirtyObjectDeltas); } - private void mapTemporaryID(InternalCDORevision revision, IStoreWriter storeWriter) + @Override + protected void responding(ExtendedDataOutputStream out) throws IOException { - CDOID oldID = revision.getID(); - if (oldID.isTemporary()) + String rollbackMessage = transaction.getRollbackMessage(); + boolean success = rollbackMessage == null; + out.writeBoolean(success); + if (success) { - CDOID newID = storeWriter.primeNewObject(revision.getCDOClass()); - if (newID == null || newID.isNull() || newID.isMeta() || newID.isTemporary()) - { - throw new ImplementationError("Store writer returned bad CDOID " + newID); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Mapping ID: {0} --> {1}", oldID, newID); - } - - idMappings.put(oldID, newID); - revision.setID(newID); - } - } + out.writeLong(transaction.getTimeStamp()); - private void writeIDMappings(ExtendedDataOutputStream out) throws IOException - { - for (Entry entry : idMappings.entrySet()) - { - CDOID oldID = entry.getKey(); - if (!oldID.isMeta()) + // Meta ID ranges + List metaRanges = transaction.getMetaIDRanges(); + for (CDOIDMetaRange metaRange : metaRanges) { - CDOID newID = entry.getValue(); - CDOIDUtil.write(out, oldID); - CDOIDUtil.write(out, newID); + CDOIDUtil.writeMetaRange(out, metaRange); } - } - - CDOIDUtil.write(out, CDOID.NULL); - } - /** - * @author Eike Stepper - */ - private final class TransactionPackageManager implements CDOPackageManager - { - public TransactionPackageManager() - { - } - - public CDOIDObjectFactory getCDOIDObjectFactory() - { - return sessionPackageManager.getCDOIDObjectFactory(); - } - - public CDOPackage lookupPackage(String uri) - { - for (CDOPackage cdoPackage : newPackages) + // ID mappings + Map idMappings = transaction.getIdMappings(); + for (Entry entry : idMappings.entrySet()) { - if (ObjectUtil.equals(cdoPackage.getPackageURI(), uri)) + CDOIDTemp oldID = entry.getKey(); + if (!oldID.isMeta()) { - return cdoPackage; + CDOID newID = entry.getValue(); + CDOIDUtil.write(out, oldID); + CDOIDUtil.write(out, newID); } } - return sessionPackageManager.lookupPackage(uri); + CDOIDUtil.write(out, CDOID.NULL); } - - public CDOCorePackage getCDOCorePackage() - { - throw new UnsupportedOperationException(); - } - - public CDOResourcePackage getCDOResourcePackage() - { - throw new UnsupportedOperationException(); - } - - public int getPackageCount() - { - throw new UnsupportedOperationException(); - } - - public CDOPackage[] getPackages() - { - throw new UnsupportedOperationException(); - } - - public CDOPackage[] getElements() + else { - throw new UnsupportedOperationException(); + out.writeString(rollbackMessage); } - public boolean isEmpty() - { - throw new UnsupportedOperationException(); - } + transaction.postCommit(success); + } - public void addListener(IListener listener) + private Transaction getTransaction(int viewID) + { + IView view = getSession().getView(viewID); + if (view instanceof Transaction) { - throw new UnsupportedOperationException(); + return (Transaction)view; } - public void removeListener(IListener listener) - { - throw new UnsupportedOperationException(); - } + throw new IllegalStateException("Illegal transaction: " + view); } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/InvalidationNotification.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/InvalidationNotification.java index f4d586d967..e07c1799e9 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/InvalidationNotification.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/protocol/InvalidationNotification.java @@ -22,6 +22,7 @@ import org.eclipse.net4j.signal.Request; import org.eclipse.net4j.util.io.ExtendedDataOutputStream; import java.io.IOException; +import java.util.List; /** * @author Eike Stepper @@ -32,9 +33,9 @@ public class InvalidationNotification extends Request private long timeStamp; - private CDOID[] dirtyIDs; + private List dirtyIDs; - public InvalidationNotification(IChannel channel, long timeStamp, CDOID[] dirtyIDs) + public InvalidationNotification(IChannel channel, long timeStamp, List dirtyIDs) { super(channel); this.timeStamp = timeStamp; @@ -56,17 +57,15 @@ public class InvalidationNotification extends Request } out.writeLong(timeStamp); - - int size = dirtyIDs.length; if (PROTOCOL.isEnabled()) { - PROTOCOL.format("Writing {0} IDs", size); + PROTOCOL.format("Writing {0} dirty IDs", dirtyIDs.size()); } - out.writeInt(size); - for (int i = 0; i < dirtyIDs.length; i++) + out.writeInt(dirtyIDs.size()); + for (CDOID dirtyID : dirtyIDs) { - CDOIDUtil.write(out, dirtyIDs[i]); + CDOIDUtil.write(out, dirtyID); } } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IRepository.java index 6c40628327..10fbfd8fa6 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IRepository.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IRepository.java @@ -10,6 +10,8 @@ **************************************************************************/ package org.eclipse.emf.cdo.server; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; + import org.eclipse.net4j.util.container.IContainer; import java.util.Map; @@ -33,6 +35,8 @@ public interface IRepository extends IContainer public String getUUID(); + public boolean isSupportingRevisionDeltas(); + public boolean isSupportingAudits(); public boolean isVerifyingRevisions(); @@ -45,6 +49,8 @@ public interface IRepository extends IContainer public IRevisionManager getRevisionManager(); + public CDOIDMetaRange getMetaIDRange(int count); + /** * @author Eike Stepper */ diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java index f29a6da84b..c1ddffa472 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/IStoreWriter.java @@ -11,13 +11,17 @@ **************************************************************************/ package org.eclipse.emf.cdo.server; -import org.eclipse.emf.cdo.internal.protocol.model.CDOClassProxy; import org.eclipse.emf.cdo.protocol.id.CDOID; -import org.eclipse.emf.cdo.protocol.model.CDOClass; +import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import org.eclipse.emf.cdo.protocol.model.CDOPackage; +import org.eclipse.emf.cdo.protocol.model.CDOPackageManager; import org.eclipse.emf.cdo.protocol.revision.CDORevision; import org.eclipse.emf.cdo.protocol.revision.delta.CDORevisionDelta; +import java.util.List; +import java.util.Map; + /** * @author Eike Stepper */ @@ -25,27 +29,82 @@ public interface IStoreWriter extends IStoreReader { public IView getView(); + public void beginCommit(CommitContext context); + + public CDOID createNewResourceID(CommitContext context, int i, CDORevision newResource); + + public CDOID createNewObjectID(CommitContext context, int i, CDORevision newObject); + + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevision[] dirtyObjects); + + public void finishCommit(CommitContext context, CDORevision[] newResources, CDORevision[] newObjects, + CDORevisionDelta[] dirtyObjectDeltas); + + public void cancelCommit(CommitContext context); + /** - * Stores an array of complete package descriptions so that they can be restored to an identical state at a later - * point in time. - *

- * Note: The implementor of this method must not assume that references to classes in this package or in any - * other package are already resolved or are resolveable at the point in time when this method is called by the - * framework. - *

+ * Represents the state of a single, logical commit operation which is driven through multiple calls to several + * methods on the {@link IStoreWriter} API. All these method calls get the same CommitContext instance + * passed so that the implementor of the {@link IStoreWriter} can track the state and progress of the commit + * operation. * - * @see CDOClassProxy#getPackageURI() - * @see CDOClassProxy#getClassifierID() + * @author Eike Stepper */ - public void writePackages(CDOPackage... cdoPackages); + public interface CommitContext + { + /** + * Returns the ID of the transactional view (ITransaction) which is the scope of the commit + * operation represented by this CommitContext. + */ + public int getTransactionID(); + + /** + * Returns the time stamp of this commit operation. + */ + public long getTimeStamp(); + + /** + * Returns the temporary, transactional package manager associated with the commit operation represented by this + * CommitContext. In addition to the packages registered with the session this package manager also + * contains the new packages that are part of this commit operation. + */ + public CDOPackageManager getPackageManager(); + + /** + * Returns an array of the new packages that are part of the commit operation represented by this + * CommitContext. + */ + public CDOPackage[] getNewPackages(); - public CDOID primeNewObject(CDOClass cdoClass); + /** + * Returns the number of new resources that are part of the commit operation represented by this + * CommitContext. + */ + public int getNumberOfNewResources(); - public void writeRevision(CDORevision revision); + /** + * Returns the number of new objects that are part of the commit operation represented by this + * CommitContext. + */ + public int getNumberOfNewObjects(); - public void writeRevisionDelta(CDORevisionDelta delta); + /** + * Returns the number of dirty objects that are part of the commit operation represented by this + * CommitContext. + */ + public int getNumberOfDirtyObjects(); - public void commit(); + /** + * Returns an unmodifiable list of the temporary meta ID ranges of the new packages as they are received by the + * framework. + */ + public List getMetaIDRanges(); - public void rollback(); + /** + * Returns an unmodifiable map from all temporary IDs (meta or not) to their persistent counter parts. It is + * initially populated with the mappings of all new meta objects. + */ + public Map getIdMappings(); + } } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java new file mode 100644 index 0000000000..4c70f547f9 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/server/ITransaction.java @@ -0,0 +1,36 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * 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.server; + +import org.eclipse.emf.cdo.protocol.CDOProtocolView; +import org.eclipse.emf.cdo.protocol.model.CDOPackageManager; + +/** + * @author Eike Stepper + */ +public interface ITransaction extends IView +{ + /** + * Returns the ID of this transactional view. Same as {@link CDOProtocolView#getViewID() getViewID()}. + */ + public int getTransactionID(); + + /** + * Returns the temporary, transactional package manager associated with this ITransaction during the process of a + * commit operation. In addition to the packages registered with the session + * {@link IRepository#getPackageManager() package manager} this package manager also contains the new packages that + * are part of the commit operation. + * + * @return a temporary, transactional package manager if this ITransaction is in the process of a commit operation, + * null otherwise. + */ + public CDOPackageManager getPackageManager(); +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionFinishedEvent.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionFinishedEvent.java index 34524ecc90..535f158304 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionFinishedEvent.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOTransactionFinishedEvent.java @@ -11,6 +11,7 @@ package org.eclipse.emf.cdo; import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import java.util.Map; @@ -21,7 +22,7 @@ public interface CDOTransactionFinishedEvent extends CDOViewEvent { public Type getType(); - public Map getIDMappings(); + public Map getIDMappings(); public enum Type { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/EresourceFactoryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/EresourceFactoryImpl.java index c8fc2eb1d8..e36d510f4c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/EresourceFactoryImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/EresourceFactoryImpl.java @@ -39,7 +39,7 @@ public class EresourceFactoryImpl extends EFactoryImpl implements EresourceFacto try { EresourceFactory theEresourceFactory = (EresourceFactory)EPackage.Registry.INSTANCE - .getEFactory("http://www.eclipse.org/emf/CDO/resource/1.0.0"); + .getEFactory("http://www.eclipse.org/emf/CDO/resource/1.0.0"); if (theEresourceFactory != null) { return theEresourceFactory; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java index f81815cf0f..90fa71fa81 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java @@ -427,7 +427,7 @@ public class CDOSessionImpl extends Container implements CDOSession, CD CDOIDTemp lowerBound = new CDOIDTempMetaImpl(lastTempMetaID + 1); CDOIDMetaRange range = CDOIDUtil.createMetaRange(lowerBound, 0); range = registerMetaInstance((InternalEObject)ePackage, range); - lastTempMetaID = ((CDOIDTemp)range.getUpperBound()).getValue(); + lastTempMetaID = ((CDOIDTemp)range.getUpperBound()).getIntValue(); return range; } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java index bafcf042c1..d8d3351f45 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java @@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.CDOView; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import org.eclipse.emf.cdo.protocol.revision.CDORevision; import org.eclipse.emf.cdo.protocol.revision.CDORevisionUtil; import org.eclipse.emf.cdo.protocol.revision.delta.CDOFeatureDelta; @@ -421,7 +422,7 @@ public final class CDOStateMachine extends FiniteStateMachine idMappings = data.getIDMappings(); + Map idMappings = data.getIDMappings(); // Adjust object CDOID id = object.cdoID(); @@ -593,7 +594,7 @@ public final class CDOStateMachine extends FiniteStateMachine getDirtyObjects() { return Collections.unmodifiableMap(dirtyObjects); } + /** + * TODO Consolidate with {@link #getDirtyObjects()} + */ public Map getRevisionDeltas() { return Collections.unmodifiableMap(revisionDeltas); @@ -236,7 +242,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction } cleanUp(); - Map idMappings = result.getIDMappings(); + Map idMappings = result.getIDMappings(); fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.COMMITTED, idMappings)); } catch (RuntimeException ex) @@ -280,7 +286,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction } cleanUp(); - Map idMappings = Collections.emptyMap(); + Map idMappings = Collections.emptyMap(); fireEvent(new FinishedEvent(CDOTransactionFinishedEvent.Type.ROLLED_BACK, idMappings)); } catch (RuntimeException ex) @@ -475,9 +481,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction private Type type; - private Map idMappings; + private Map idMappings; - private FinishedEvent(Type type, Map idMappings) + private FinishedEvent(Type type, Map idMappings) { this.type = type; this.idMappings = idMappings; @@ -488,7 +494,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements CDOTransaction return type; } - public Map getIDMappings() + public Map getIDMappings() { return idMappings; } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java index 6f37962ded..8fb81de287 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java @@ -190,7 +190,7 @@ public class CDOViewImpl extends org.eclipse.net4j.internal.util.event.Notifier public CDOResourceImpl getResource(CDOID resourceID) { - if (resourceID == null || resourceID == CDOID.NULL) + if (resourceID == null || resourceID.isNull()) { throw new IllegalArgumentException("resourceID == null || resourceID == CDOID.NULL"); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java index d159cc5434..fef017c2a3 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionRequest.java @@ -18,6 +18,7 @@ import org.eclipse.emf.cdo.internal.protocol.revision.InternalCDORevision; import org.eclipse.emf.cdo.protocol.CDOProtocolConstants; import org.eclipse.emf.cdo.protocol.id.CDOID; import org.eclipse.emf.cdo.protocol.id.CDOIDMetaRange; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import org.eclipse.emf.cdo.protocol.id.CDOIDUtil; import org.eclipse.emf.cdo.protocol.model.CDOModelUtil; import org.eclipse.emf.cdo.protocol.model.CDOPackage; @@ -63,11 +64,54 @@ public class CommitTransactionRequest extends CDOClientRequest newPackages = transaction.getNewPackages(); + Collection newResources = transaction.getNewResources().values(); + Collection newObjects = transaction.getNewObjects().values(); + Collection dirtyObjects = transaction.getRevisionDeltas().values(); + out.writeInt(transaction.getViewID()); - writeNewPackages(out); - writeNewResources(out); - writeNewObjects(out); - writeRevisionDeltas(out); + out.writeInt(newPackages.size()); + out.writeInt(newResources.size()); + out.writeInt(newObjects.size()); + out.writeInt(dirtyObjects.size()); + + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Writing {0} new packages", newPackages.size()); + } + + for (CDOPackage newPackage : newPackages) + { + CDOModelUtil.writePackage(out, newPackage); + } + + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Writing {0} new resources", newResources.size()); + } + + writeRevisions(out, newResources); + + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Writing {0} new objects", newObjects.size()); + } + + writeRevisions(out, newObjects); + + if (PROTOCOL.isEnabled()) + { + PROTOCOL.format("Writing {0} dirty objects", dirtyObjects.size()); + } + + RevisionAdjuster revisionAdjuster = new RevisionAdjuster(transaction); + for (CDORevisionDelta revisionDelta : dirtyObjects) + { + revisionDelta.write(out, transaction); + CDOObject object = transaction.getDirtyObjects().get(revisionDelta.getID()); + InternalCDORevision revision = (InternalCDORevision)object.cdoRevision(); + revisionAdjuster.adjustRevision(revision, revisionDelta); + } } @Override @@ -93,7 +137,7 @@ public class CommitTransactionRequest extends CDOClientRequest newPackages = transaction.getNewPackages(); - if (PROTOCOL.isEnabled()) - { - PROTOCOL.format("Writing {0} new packages", newPackages.size()); - } - - out.writeInt(newPackages.size()); - for (CDOPackage newPackage : newPackages) - { - CDOModelUtil.writePackage(out, newPackage); - } - } - - private void writeNewResources(ExtendedDataOutputStream out) throws IOException - { - Collection newResources = transaction.getNewResources().values(); - if (PROTOCOL.isEnabled()) - { - PROTOCOL.format("Writing {0} new resources", newResources.size()); - } - - writeRevisions(out, newResources); - } - - private void writeNewObjects(ExtendedDataOutputStream out) throws IOException - { - Collection newObjects = transaction.getNewObjects().values(); - if (PROTOCOL.isEnabled()) - { - PROTOCOL.format("Writing {0} new objects", newObjects.size()); - } - - writeRevisions(out, newObjects); - } - @SuppressWarnings("unused") private void writeDirtyObjects(ExtendedDataOutputStream out) throws IOException { @@ -164,28 +171,8 @@ public class CommitTransactionRequest extends CDOClientRequest revisionDeltas = transaction.getRevisionDeltas().values(); - if (PROTOCOL.isEnabled()) - { - PROTOCOL.format("Writing {0} revision deltas", revisionDeltas.size()); - } - - RevisionAdjuster revisionAdjuster = new RevisionAdjuster(transaction); - out.writeInt(revisionDeltas.size()); - for (CDORevisionDelta revisionDelta : revisionDeltas) - { - revisionDelta.write(out, transaction); - CDOObject object = transaction.getDirtyObjects().get(revisionDelta.getID()); - InternalCDORevision revision = (InternalCDORevision)object.cdoRevision(); - revisionAdjuster.adjustRevision(revision, revisionDelta); - } - } - private void writeRevisions(ExtendedDataOutputStream out, Collection objects) throws IOException { - out.writeInt(objects.size()); for (Iterator it = objects.iterator(); it.hasNext();) { CDOObject object = (CDOObject)it.next(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java index 2c332c7976..fe75980cd2 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/CommitTransactionResult.java @@ -11,6 +11,7 @@ package org.eclipse.emf.internal.cdo.protocol; import org.eclipse.emf.cdo.protocol.id.CDOID; +import org.eclipse.emf.cdo.protocol.id.CDOIDTemp; import java.util.HashMap; import java.util.Map; @@ -24,7 +25,7 @@ public final class CommitTransactionResult private long timeStamp; - private Map idMappings = new HashMap(); + private Map idMappings = new HashMap(); public CommitTransactionResult(String rollbackMessage) { @@ -46,12 +47,12 @@ public final class CommitTransactionResult return timeStamp; } - public Map getIDMappings() + public Map getIDMappings() { return idMappings; } - void addIDMapping(CDOID oldID, CDOID newID) + void addIDMapping(CDOIDTemp oldID, CDOID newID) { idMappings.put(oldID, newID); } -- cgit v1.2.3