Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java')
-rw-r--r--org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java1923
1 files changed, 1923 insertions, 0 deletions
diff --git a/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
new file mode 100644
index 0000000000..70dacf074b
--- /dev/null
+++ b/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -0,0 +1,1923 @@
+/**
+ * Copyright (c) 2004 - 2011 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
+ * Simon McDuff - bug 201266
+ * Simon McDuff - bug 233273
+ * Simon McDuff - bug 233490
+ * Stefan Winkler - changed order of determining audit and revision delta support.
+ * Andre Dietisheim - bug 256649
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
+import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.etypes.EtypesPackage;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IStore;
+import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreChunkReader;
+import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.server.IView;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
+import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
+import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
+import org.eclipse.emf.cdo.spi.server.InternalStore;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
+
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.MoveableList;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
+import org.eclipse.net4j.util.container.Container;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.monitor.Monitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class Repository extends Container<Object> implements InternalRepository
+{
+ private String name;
+
+ private String uuid;
+
+ private InternalStore store;
+
+ private Type type = Type.MASTER;
+
+ private State state = State.ONLINE;
+
+ private Map<String, String> properties;
+
+ private boolean supportingAudits;
+
+ private boolean supportingBranches;
+
+ private boolean supportingEcore;
+
+ private boolean ensuringReferentialIntegrity;
+
+ private IDGenerationLocation idGenerationLocation;
+
+ /**
+ * Must not be thread-bound to support XA commits.
+ */
+ private Semaphore packageRegistryCommitLock = new Semaphore(1);
+
+ private InternalCDOPackageRegistry packageRegistry;
+
+ private InternalCDOBranchManager branchManager;
+
+ private InternalCDORevisionManager revisionManager;
+
+ private InternalCDOCommitInfoManager commitInfoManager;
+
+ private InternalSessionManager sessionManager;
+
+ private InternalQueryManager queryManager;
+
+ private InternalCommitManager commitManager;
+
+ private InternalLockManager lockManager;
+
+ private IQueryHandlerProvider queryHandlerProvider;
+
+ private List<ReadAccessHandler> readAccessHandlers = new ArrayList<ReadAccessHandler>();
+
+ private List<WriteAccessHandler> writeAccessHandlers = new ArrayList<WriteAccessHandler>();
+
+ private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>();
+
+ private EPackage[] initialPackages;
+
+ // Bugzilla 297940
+ private TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);
+
+ @ExcludeFromDump
+ private transient Object createBranchLock = new Object();
+
+ private boolean skipInitialization;
+
+ private CDOID rootResourceID;
+
+ public Repository()
+ {
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getUUID()
+ {
+ if (uuid == null)
+ {
+ uuid = getProperties().get(Props.OVERRIDE_UUID);
+ if (uuid == null)
+ {
+ uuid = UUID.randomUUID().toString();
+ }
+ else if (uuid.length() == 0)
+ {
+ uuid = getName();
+ }
+ }
+
+ return uuid;
+ }
+
+ public InternalStore getStore()
+ {
+ return store;
+ }
+
+ public void setStore(InternalStore store)
+ {
+ this.store = store;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public void setType(Type type)
+ {
+ checkArg(type, "type"); //$NON-NLS-1$
+ if (this.type != type)
+ {
+ changingType(this.type, type);
+ }
+ }
+
+ protected void changingType(Type oldType, Type newType)
+ {
+ type = newType;
+ fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
+
+ if (sessionManager != null)
+ {
+ sessionManager.sendRepositoryTypeNotification(oldType, newType);
+ }
+ }
+
+ public State getState()
+ {
+ return state;
+ }
+
+ public void setState(State state)
+ {
+ checkArg(state, "state"); //$NON-NLS-1$
+ if (this.state != state)
+ {
+ changingState(this.state, state);
+ }
+ }
+
+ protected void changingState(State oldState, State newState)
+ {
+ state = newState;
+ fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
+
+ if (sessionManager != null)
+ {
+ sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
+ }
+ }
+
+ public synchronized Map<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new HashMap<String, String>();
+ }
+
+ return properties;
+ }
+
+ public synchronized void setProperties(Map<String, String> properties)
+ {
+ this.properties = properties;
+ }
+
+ public boolean isSupportingAudits()
+ {
+ return supportingAudits;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return supportingBranches;
+ }
+
+ public boolean isSupportingEcore()
+ {
+ return supportingEcore;
+ }
+
+ public boolean isEnsuringReferentialIntegrity()
+ {
+ return ensuringReferentialIntegrity;
+ }
+
+ public IDGenerationLocation getIDGenerationLocation()
+ {
+ return idGenerationLocation;
+ }
+
+ public String getStoreType()
+ {
+ return store.getType();
+ }
+
+ public Set<CDOID.ObjectType> getObjectIDTypes()
+ {
+ return store.getObjectIDTypes();
+ }
+
+ public CDOID getRootResourceID()
+ {
+ return rootResourceID;
+ }
+
+ public void setRootResourceID(CDOID rootResourceID)
+ {
+ this.rootResourceID = rootResourceID;
+ }
+
+ public Object processPackage(Object value)
+ {
+ CDOFactoryImpl.prepareDynamicEPackage(value);
+ return value;
+ }
+
+ public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
+ }
+
+ public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
+ {
+ if (!isSupportingBranches())
+ {
+ throw new IllegalStateException("Branching is not supported by " + this);
+ }
+
+ long baseTimeStamp = branchInfo.getBaseTimeStamp();
+ if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ baseTimeStamp = getTimeStamp();
+ branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
+ }
+
+ synchronized (createBranchLock)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.createBranch(branchID, branchInfo);
+ }
+ }
+
+ public BranchInfo loadBranch(int branchID)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadBranch(branchID);
+ }
+
+ public SubBranchInfo[] loadSubBranches(int branchID)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadSubBranches(branchID);
+ }
+
+ public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadBranches(startID, endID, branchHandler);
+ }
+
+ public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.loadCommitInfos(branch, startTime, endTime, handler);
+ }
+
+ public CDOCommitData loadCommitData(long timeStamp)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadCommitData(timeStamp);
+ }
+
+ public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+ int referenceChunk, int prefetchDepth)
+ {
+ for (RevisionInfo info : infos)
+ {
+ CDOID id = info.getID();
+ RevisionInfo.Type type = info.getType();
+ switch (type)
+ {
+ case AVAILABLE_NORMAL: // direct == false
+ {
+ RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
+ checkArg(availableInfo.isDirect() == false, "Load is not needed");
+ break;
+ }
+
+ case AVAILABLE_POINTER: // direct == false || target == null
+ {
+ RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
+ boolean needsTarget = !pointerInfo.hasTarget();
+ checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");
+
+ if (needsTarget)
+ {
+ CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
+ InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
+ PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo
+ .getAvailableBranchVersion().getBranch(), CDORevision.UNSPECIFIED_DATE, target);
+
+ info.setResult(target);
+ info.setSynthetic(pointer);
+ continue;
+ }
+
+ break;
+ }
+
+ case AVAILABLE_DETACHED: // direct == false
+ {
+ RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
+ checkArg(detachedInfo.isDirect() == false, "Load is not needed");
+ break;
+ }
+
+ case MISSING:
+ {
+ break;
+ }
+
+ default:
+ throw new IllegalStateException("Invalid revision info type: " + type);
+ }
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+ if (revision == null)
+ {
+ if (isSupportingAudits())
+ {
+ // Case "Pointer"?
+ InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
+ if (target != null)
+ {
+ CDOBranch branch = branchPoint.getBranch();
+ long revised = loadRevisionRevised(id, branch);
+ PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
+ info.setSynthetic(pointer);
+ }
+
+ info.setResult(target);
+ }
+ else
+ {
+ DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id,
+ branchPoint.getBranch(), 0, CDORevision.UNSPECIFIED_DATE);
+ info.setSynthetic(detachedRevision);
+ }
+ }
+ else if (revision instanceof DetachedCDORevision)
+ {
+ DetachedCDORevision detached = (DetachedCDORevision)revision;
+ info.setSynthetic(detached);
+ }
+ else
+ {
+ revision.freeze();
+ info.setResult(revision);
+ }
+ }
+
+ return null;
+ }
+
+ private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk,
+ IStoreAccessor accessor)
+ {
+ CDOBranch branch = branchPoint.getBranch();
+ while (!branch.isMainBranch())
+ {
+ branchPoint = branch.getBase();
+ branch = branchPoint.getBranch();
+
+ InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+ if (revision != null)
+ {
+ revision.freeze();
+ return revision;
+ }
+ }
+
+ return null;
+ }
+
+ private long loadRevisionRevised(CDOID id, CDOBranch branch)
+ {
+ InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION),
+ CDORevision.UNCHUNKED);
+ if (revision != null)
+ {
+ return revision.getTimeStamp() - 1;
+ }
+
+ return CDORevision.UNSPECIFIED_DATE;
+ }
+
+ public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
+ }
+
+ protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
+ {
+ EClass eClass = revision.getEClass();
+ EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
+ for (int i = 0; i < features.length; i++)
+ {
+ EStructuralFeature feature = features[i];
+ if (feature.isMany())
+ {
+ MoveableList<Object> list = revision.getList(feature);
+ int chunkEnd = Math.min(referenceChunk, list.size());
+ accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);
+ }
+ }
+ }
+
+ public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+ int chunkEnd)
+ {
+ MoveableList<Object> list = revision.getList(feature);
+ chunkEnd = Math.min(chunkEnd, list.size());
+ return ensureChunk(revision, feature, StoreThreadLocal.getAccessor(), list, chunkStart, chunkEnd);
+ }
+
+ protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature,
+ IStoreAccessor accessor, MoveableList<Object> list, int chunkStart, int chunkEnd)
+ {
+ IStoreChunkReader chunkReader = null;
+ int fromIndex = -1;
+ for (int j = chunkStart; j < chunkEnd; j++)
+ {
+ if (list.get(j) == InternalCDOList.UNINITIALIZED)
+ {
+ if (fromIndex == -1)
+ {
+ fromIndex = j;
+ }
+ }
+ else
+ {
+ if (fromIndex != -1)
+ {
+ if (chunkReader == null)
+ {
+ if (accessor == null)
+ {
+ accessor = StoreThreadLocal.getAccessor();
+ }
+
+ chunkReader = accessor.createChunkReader(revision, feature);
+ }
+
+ int toIndex = j;
+ if (fromIndex == toIndex - 1)
+ {
+ chunkReader.addSimpleChunk(fromIndex);
+ }
+ else
+ {
+ chunkReader.addRangedChunk(fromIndex, toIndex);
+ }
+
+ fromIndex = -1;
+ }
+ }
+ }
+
+ // Add last chunk
+ if (fromIndex != -1)
+ {
+ if (chunkReader == null)
+ {
+ if (accessor == null)
+ {
+ accessor = StoreThreadLocal.getAccessor();
+ }
+
+ chunkReader = accessor.createChunkReader(revision, feature);
+ }
+
+ int toIndex = chunkEnd;
+ if (fromIndex == toIndex - 1)
+ {
+ chunkReader.addSimpleChunk(fromIndex);
+ }
+ else
+ {
+ chunkReader.addRangedChunk(fromIndex, toIndex);
+ }
+ }
+
+ if (chunkReader != null)
+ {
+ InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;
+
+ List<Chunk> chunks = chunkReader.executeRead();
+ for (Chunk chunk : chunks)
+ {
+ int startIndex = chunk.getStartIndex();
+ for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
+ {
+ Object id = chunk.get(indexInChunk);
+ if (cdoList != null)
+ {
+ cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
+ }
+ else
+ {
+ list.set(startIndex + indexInChunk, id);
+ }
+ }
+ }
+ }
+
+ return accessor;
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
+ {
+ if (considerCommitContext)
+ {
+ IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
+ if (commitContext != null)
+ {
+ InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
+ if (contextualPackageRegistry != null)
+ {
+ return contextualPackageRegistry;
+ }
+ }
+ }
+
+ return packageRegistry;
+ }
+
+ public Semaphore getPackageRegistryCommitLock()
+ {
+ return packageRegistryCommitLock;
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry()
+ {
+ return getPackageRegistry(true);
+ }
+
+ public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
+ {
+ checkInactive();
+ this.packageRegistry = packageRegistry;
+ }
+
+ public InternalSessionManager getSessionManager()
+ {
+ return sessionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setSessionManager(InternalSessionManager sessionManager)
+ {
+ checkInactive();
+ this.sessionManager = sessionManager;
+ }
+
+ public InternalCDOBranchManager getBranchManager()
+ {
+ return branchManager;
+ }
+
+ public void setBranchManager(InternalCDOBranchManager branchManager)
+ {
+ checkInactive();
+ this.branchManager = branchManager;
+ }
+
+ public InternalCDOCommitInfoManager getCommitInfoManager()
+ {
+ return commitInfoManager;
+ }
+
+ public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
+ {
+ checkInactive();
+ this.commitInfoManager = commitInfoManager;
+ }
+
+ public InternalCDORevisionManager getRevisionManager()
+ {
+ return revisionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setRevisionManager(InternalCDORevisionManager revisionManager)
+ {
+ checkInactive();
+ this.revisionManager = revisionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalQueryManager getQueryManager()
+ {
+ return queryManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setQueryManager(InternalQueryManager queryManager)
+ {
+ checkInactive();
+ this.queryManager = queryManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalCommitManager getCommitManager()
+ {
+ return commitManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setCommitManager(InternalCommitManager commitManager)
+ {
+ checkInactive();
+ this.commitManager = commitManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalLockManager getLockManager()
+ {
+ return lockManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setLockManager(InternalLockManager lockManager)
+ {
+ checkInactive();
+ this.lockManager = lockManager;
+ }
+
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return new TransactionCommitContext(transaction);
+ }
+
+ public long getLastCommitTimeStamp()
+ {
+ return timeStampAuthority.getLastFinishedTimeStamp();
+ }
+
+ public void setLastCommitTimeStamp(long lastCommitTimeStamp)
+ {
+ timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+ }
+
+ public long waitForCommit(long timeout)
+ {
+ return timeStampAuthority.waitForCommit(timeout);
+ }
+
+ public long[] createCommitTimeStamp(OMMonitor monitor)
+ {
+ return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
+ }
+
+ public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
+ {
+ return timeStampAuthority.startCommit(override, monitor);
+ }
+
+ public void endCommit(long timestamp)
+ {
+ timeStampAuthority.endCommit(timestamp);
+ }
+
+ public void failCommit(long timestamp)
+ {
+ timeStampAuthority.failCommit(timestamp);
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void addCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ synchronized (commitInfoHandlers)
+ {
+ if (!commitInfoHandlers.contains(handler))
+ {
+ commitInfoHandlers.add(handler);
+ }
+ }
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ synchronized (commitInfoHandlers)
+ {
+ commitInfoHandlers.remove(handler);
+ }
+ }
+
+ public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
+ {
+ sessionManager.sendCommitNotification(sender, commitInfo);
+
+ CDOCommitInfoHandler[] handlers;
+ synchronized (commitInfoHandlers)
+ {
+ handlers = commitInfoHandlers.toArray(new CDOCommitInfoHandler[commitInfoHandlers.size()]);
+ }
+
+ for (CDOCommitInfoHandler handler : handlers)
+ {
+ try
+ {
+ handler.handleCommitInfo(commitInfo);
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public IQueryHandlerProvider getQueryHandlerProvider()
+ {
+ return queryHandlerProvider;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
+ {
+ this.queryHandlerProvider = queryHandlerProvider;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
+ {
+ String language = info.getQueryLanguage();
+ if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
+ {
+ return new ResourcesQueryHandler();
+ }
+
+ if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
+ {
+ return new XRefsQueryHandler();
+ }
+
+ IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
+ if (storeAccessor != null)
+ {
+ IQueryHandler handler = storeAccessor.getQueryHandler(info);
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+
+ if (queryHandlerProvider == null)
+ {
+ queryHandlerProvider = new ContainerQueryHandlerProvider(IPluginContainer.INSTANCE);
+ }
+
+ IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
+ if (handler != null)
+ {
+ return handler;
+ }
+
+ return null;
+ }
+
+ public Object[] getElements()
+ {
+ final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager,
+ commitManager, commitInfoManager, lockManager, store };
+ return elements;
+ }
+
+ @Override
+ public boolean isEmpty()
+ {
+ return false;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public long getCreationTime()
+ {
+ return store.getCreationTime();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+ {
+ long creationTimeStamp = getCreationTime();
+ if (timeStamp < creationTimeStamp)
+ {
+ throw new IllegalArgumentException(
+ MessageFormat
+ .format(
+ "timeStamp ({0}) < repository creation time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp))); //$NON-NLS-1$
+ }
+
+ long currentTimeStamp = getTimeStamp();
+ if (timeStamp > currentTimeStamp)
+ {
+ throw new IllegalArgumentException(
+ MessageFormat
+ .format(
+ "timeStamp ({0}) > current time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp))); //$NON-NLS-1$
+ }
+ }
+
+ public long getTimeStamp()
+ {
+ return System.currentTimeMillis();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void addHandler(Handler handler)
+ {
+ if (handler instanceof ReadAccessHandler)
+ {
+ synchronized (readAccessHandlers)
+ {
+ if (!readAccessHandlers.contains(handler))
+ {
+ readAccessHandlers.add((ReadAccessHandler)handler);
+ }
+ }
+ }
+
+ if (handler instanceof WriteAccessHandler)
+ {
+ synchronized (writeAccessHandlers)
+ {
+ if (!writeAccessHandlers.contains(handler))
+ {
+ writeAccessHandlers.add((WriteAccessHandler)handler);
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void removeHandler(Handler handler)
+ {
+ if (handler instanceof ReadAccessHandler)
+ {
+ synchronized (readAccessHandlers)
+ {
+ readAccessHandlers.remove(handler);
+ }
+ }
+
+ if (handler instanceof WriteAccessHandler)
+ {
+ synchronized (writeAccessHandlers)
+ {
+ writeAccessHandlers.remove(handler);
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+ List<CDORevision> additionalRevisions)
+ {
+ ReadAccessHandler[] handlers;
+ synchronized (readAccessHandlers)
+ {
+ int size = readAccessHandlers.size();
+ if (size == 0)
+ {
+ return;
+ }
+
+ handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
+ }
+
+ for (ReadAccessHandler handler : handlers)
+ {
+ // Do *not* protect against unchecked exceptions from handlers!
+ handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
+ }
+ }
+
+ public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
+ boolean beforeCommit, OMMonitor monitor)
+ {
+ WriteAccessHandler[] handlers;
+ synchronized (writeAccessHandlers)
+ {
+ int size = writeAccessHandlers.size();
+ if (size == 0)
+ {
+ return;
+ }
+
+ handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
+ }
+
+ try
+ {
+ monitor.begin(handlers.length);
+ for (WriteAccessHandler handler : handlers)
+ {
+ try
+ {
+ if (beforeCommit)
+ {
+ handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
+ }
+ else
+ {
+ handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ if (!beforeCommit)
+ {
+ OM.LOG.error(ex);
+ }
+ else
+ {
+ // Do *not* protect against unchecked exceptions from handlers on before case!
+ throw ex;
+ }
+ }
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ public void setInitialPackages(EPackage... initialPackages)
+ {
+ checkInactive();
+ this.initialPackages = initialPackages;
+ }
+
+ public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+ throws IOException
+ {
+ final int fromBranchID = lastReplicatedBranchID + 1;
+ final int toBranchID = getStore().getLastBranchID();
+
+ final long fromCommitTime = lastReplicatedCommitTime + 1L;
+ final long toCommitTime = getStore().getLastCommitTime();
+
+ out.writeInt(toBranchID);
+ out.writeLong(toCommitTime);
+
+ IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
+ accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
+
+ return new CDOReplicationInfo()
+ {
+ public int getLastReplicatedBranchID()
+ {
+ return toBranchID;
+ }
+
+ public long getLastReplicatedCommitTime()
+ {
+ return toCommitTime;
+ }
+
+ public String[] getLockAreaIDs()
+ {
+ return null; // TODO (CD) Raw replication of lockAreas
+ }
+ };
+ }
+
+ public void replicate(CDOReplicationContext context)
+ {
+ int startID = context.getLastReplicatedBranchID() + 1;
+ branchManager.getBranches(startID, 0, context);
+
+ long startTime = context.getLastReplicatedCommitTime();
+ commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
+
+ lockManager.getLockAreas(null, context);
+ }
+
+ public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
+ {
+ CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);
+
+ return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
+ }
+
+ public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+ CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
+ {
+ CDOBranchPoint target = targetInfo.getBranchPoint();
+ CDOBranchPoint source = sourceInfo.getBranchPoint();
+
+ monitor.begin(5);
+
+ try
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ Set<CDOID> ids = new HashSet<CDOID>();
+
+ if (targetBaseInfo == null && sourceBaseInfo == null)
+ {
+ if (CDOBranchUtil.isContainedBy(source, target))
+ {
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
+ }
+ else if (CDOBranchUtil.isContainedBy(target, source))
+ {
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
+ }
+ else
+ {
+ CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
+ }
+ }
+ else
+ {
+ CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
+
+ ids.addAll(accessor.readChangeSet(monitor.fork(),
+ CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target)));
+
+ ids.addAll(accessor.readChangeSet(monitor.fork(),
+ CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source)));
+ }
+
+ loadMergeData(ids, targetInfo, monitor.fork());
+ loadMergeData(ids, sourceInfo, monitor.fork());
+
+ if (targetBaseInfo != null)
+ {
+ loadMergeData(ids, targetBaseInfo, monitor.fork());
+ }
+
+ if (sourceBaseInfo != null)
+ {
+ loadMergeData(ids, sourceBaseInfo, monitor.fork());
+ }
+
+ return ids;
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
+ {
+ int size = ids.size();
+ monitor.begin(size);
+
+ try
+ {
+ CDOBranchPoint branchPoint = info.getBranchPoint();
+ for (CDOID id : ids)
+ {
+ if (info.containsRevision(id))
+ {
+ info.removeRevision(id);
+ }
+ else
+ {
+ InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
+ if (revision != null)
+ {
+ info.addRevision(revision);
+ }
+ else
+ {
+ info.removeRevision(id);
+ }
+ }
+
+ monitor.worked();
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
+ {
+ InternalCDORevision revision = revisionManager.getRevision(id, branchPoint, CDORevision.UNCHUNKED,
+ CDORevision.DEPTH_NONE, true);
+ // if (revision == null || !ObjectUtil.equals(revision.getBranch(), branchPoint.getBranch()))
+ // {
+ // return null;
+ // }
+
+ return revision;
+ }
+
+ public void queryLobs(List<byte[]> ids)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.queryLobs(ids);
+ }
+
+ public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.handleLobs(fromTime, toTime, handler);
+ }
+
+ public void loadLob(byte[] id, OutputStream out) throws IOException
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.loadLob(id, out);
+ }
+
+ public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+ final CDORevisionHandler handler)
+ {
+ CDORevisionHandler wrapper = handler;
+ if (!exactBranch && !branch.isMainBranch())
+ {
+ if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
+ }
+
+ wrapper = new CDORevisionHandler()
+ {
+ private Set<CDOID> handled = new HashSet<CDOID>();
+
+ public boolean handleRevision(CDORevision revision)
+ {
+ CDOID id = revision.getID();
+ if (handled.add(id))
+ {
+ return handler.handleRevision(revision);
+ }
+
+ return true;
+ }
+ };
+ }
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ while (branch != null)
+ {
+ accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
+ if (exactBranch)
+ {
+ break;
+ }
+
+ CDOBranchPoint base = branch.getBase();
+ branch = base.getBranch();
+ timeStamp = base.getTimeStamp();
+ }
+ }
+
+ public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
+ boolean isSupportingBranches)
+ {
+ List<Object> lockables = new ArrayList<Object>();
+ for (CDORevisionKey revKey : revisionKeys)
+ {
+ CDOID id = revKey.getID();
+ if (isSupportingBranches)
+ {
+ lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
+ }
+ else
+ {
+ lockables.add(id);
+ }
+ }
+ return lockables;
+ }
+
+ public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, long timeout)
+ {
+ List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
+ return lock(view, lockType, lockables, revKeys, timeout);
+ }
+
+ protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
+ List<CDORevisionKey> loadedRevs, long timeout)
+ {
+ List<LockState<Object, IView>> newLockStates = null;
+ try
+ {
+ newLockStates = lockManager.lock2(true, type, view, lockables, timeout);
+ }
+ catch (TimeoutRuntimeException ex)
+ {
+ return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+
+ long[] requiredTimestamp = { 0L };
+ CDORevisionKey[] staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
+
+ // If some of the clients' revisions are stale and it has passiveUpdates disabled,
+ // then the locks are useless so we release them and report the stale revisions
+ //
+ InternalSession session = view.getSession();
+ boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
+ if (staleNoUpdate)
+ {
+ lockManager.unlock2(true, type, view, lockables);
+ return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
+ getTimeStamp());
+ }
+
+ CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+ sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
+
+ boolean waitForUpdate = staleRevisionsArray.length > 0;
+ return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
+ getTimeStamp());
+ }
+
+ private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
+ List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
+ {
+ List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
+ if (revisionKeys != null)
+ {
+ InternalCDORevisionManager revManager = getRevisionManager();
+ CDOBranch viewedBranch = view.getBranch();
+ for (CDORevisionKey revKey : revisionKeys)
+ {
+ CDOID id = revKey.getID();
+ InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), CDORevision.UNCHUNKED,
+ CDORevision.DEPTH_NONE, true);
+
+ if (rev == null)
+ {
+ lockManager.unlock2(true, lockType, view, objectsToLock);
+ throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
+ viewedBranch));
+ }
+
+ if (!revKey.equals(rev))
+ {
+ staleRevisions.add(revKey);
+ requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
+ }
+ }
+ }
+
+ // Convert the list to an array, to satisfy the API later
+ //
+ CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
+ staleRevisions.toArray(staleRevisionsArray);
+
+ return staleRevisionsArray;
+ }
+
+ private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
+ {
+ long timestamp = getTimeStamp();
+ CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
+ lockType, cdoLockStates);
+ getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
+ }
+
+ // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
+ public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
+ {
+ CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
+ int i = 0;
+
+ for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
+ {
+ CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
+ cdoLockStates[i++] = cdoLockState;
+ }
+
+ return cdoLockStates;
+ }
+
+ public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs)
+ {
+ List<Object> unlockables = null;
+ if (objectIDs != null)
+ {
+ unlockables = new ArrayList<Object>(objectIDs.size());
+ CDOBranch branch = view.getBranch();
+ for (CDOID id : objectIDs)
+ {
+ Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
+ unlockables.add(key);
+ }
+ }
+
+ return doUnlock(view, lockType, unlockables);
+ }
+
+ protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables)
+ {
+ List<LockState<Object, IView>> newLockStates = null;
+ if (lockType == null) // Signals an unlock-all operation
+ {
+ newLockStates = lockManager.unlock2(true, view);
+ }
+ else
+ {
+ newLockStates = lockManager.unlock2(true, lockType, view, unlockables);
+ }
+
+ long timestamp = getTimeStamp();
+ CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+ sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
+
+ return new UnlockObjectsResult(cdoLockStates, timestamp);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("Repository[{0}]", name); //$NON-NLS-1$
+ }
+
+ public boolean isSkipInitialization()
+ {
+ return skipInitialization;
+ }
+
+ public void setSkipInitialization(boolean skipInitialization)
+ {
+ this.skipInitialization = skipInitialization;
+ }
+
+ protected void initProperties()
+ {
+ String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
+ if (valueAudits != null)
+ {
+ supportingAudits = Boolean.valueOf(valueAudits);
+ }
+ else
+ {
+ supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
+ }
+
+ String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
+ if (valueBranches != null)
+ {
+ supportingBranches = Boolean.valueOf(valueBranches);
+ }
+ else
+ {
+ supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
+ }
+
+ String valueEcore = properties.get(Props.SUPPORTING_ECORE);
+ if (valueEcore != null)
+ {
+ supportingEcore = Boolean.valueOf(valueEcore);
+ }
+
+ String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
+ if (valueIntegrity != null)
+ {
+ ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
+ }
+
+ String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
+ if (valueIDLocation != null)
+ {
+ idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
+ }
+
+ if (idGenerationLocation == null)
+ {
+ idGenerationLocation = IDGenerationLocation.STORE;
+ }
+ }
+
+ public void initSystemPackages()
+ {
+ IStoreAccessor writer = store.getWriter(null);
+ StoreThreadLocal.setAccessor(writer);
+
+ try
+ {
+ List<InternalCDOPackageUnit> units = new ArrayList<InternalCDOPackageUnit>();
+ units.add(initSystemPackage(EcorePackage.eINSTANCE));
+ units.add(initSystemPackage(EresourcePackage.eINSTANCE));
+ units.add(initSystemPackage(EtypesPackage.eINSTANCE));
+
+ if (initialPackages != null)
+ {
+ for (EPackage initialPackage : initialPackages)
+ {
+ if (!packageRegistry.containsKey(initialPackage.getNsURI()))
+ {
+ units.add(initSystemPackage(initialPackage));
+ }
+ }
+ }
+
+ InternalCDOPackageUnit[] systemUnits = units.toArray(new InternalCDOPackageUnit[units.size()]);
+ writer.writePackageUnits(systemUnits, new Monitor());
+ writer.commit(new Monitor());
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ protected InternalCDOPackageUnit initSystemPackage(EPackage ePackage)
+ {
+ EMFUtil.registerPackage(ePackage, packageRegistry);
+ InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);
+
+ InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
+ packageUnit.setTimeStamp(store.getCreationTime());
+ packageUnit.setState(CDOPackageUnit.State.LOADED);
+ return packageUnit;
+ }
+
+ public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
+ {
+ branchManager.initMainBranch(false, timeStamp);
+ }
+
+ protected void initRootResource()
+ {
+ CDOBranchPoint head = branchManager.getMainBranch().getHead();
+
+ CDORevisionFactory factory = getRevisionManager().getFactory();
+ InternalCDORevision rootResource = (InternalCDORevision)factory
+ .createRevision(EresourcePackage.Literals.CDO_RESOURCE);
+
+ rootResource.setBranchPoint(head);
+ rootResource.setContainerID(CDOID.NULL);
+ rootResource.setContainingFeatureID(0);
+
+ CDOID id = createRootResourceID();
+ rootResource.setID(id);
+ rootResource.setResourceID(id);
+
+ InternalSession session = getSessionManager().openSession(null);
+ InternalTransaction transaction = session.openTransaction(1, head);
+ InternalCommitContext commitContext = new TransactionCommitContext(transaction)
+ {
+ @Override
+ protected long[] createTimeStamp(OMMonitor monitor)
+ {
+ InternalRepository repository = getTransaction().getSession().getManager().getRepository();
+ return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
+ }
+
+ @Override
+ public String getUserID()
+ {
+ return SYSTEM_USER_ID;
+ }
+
+ @Override
+ public String getCommitComment()
+ {
+ return "<initialize>"; //$NON-NLS-1$
+ }
+ };
+
+ commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
+ commitContext.preWrite();
+
+ commitContext.write(new Monitor());
+ commitContext.commit(new Monitor());
+
+ String rollbackMessage = commitContext.getRollbackMessage();
+ if (rollbackMessage != null)
+ {
+ throw new TransactionException(rollbackMessage);
+ }
+
+ rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;
+
+ commitContext.postCommit(true);
+ session.close();
+ }
+
+ protected CDOID createRootResourceID()
+ {
+ if (getIDGenerationLocation() == IDGenerationLocation.STORE)
+ {
+ return CDOIDUtil.createTempObject(1);
+ }
+
+ return CDOIDGenerator.UUID.generateCDOID(null);
+ }
+
+ protected void readRootResource()
+ {
+ IStoreAccessor reader = store.getReader(null);
+ StoreThreadLocal.setAccessor(reader);
+
+ try
+ {
+ CDOBranchPoint head = branchManager.getMainBranch().getHead();
+ rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ protected void readPackageUnits()
+ {
+ IStoreAccessor reader = store.getReader(null);
+ StoreThreadLocal.setAccessor(reader);
+
+ try
+ {
+ Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
+ for (InternalCDOPackageUnit packageUnit : packageUnits)
+ {
+ packageRegistry.putPackageUnit(packageUnit);
+ }
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkState(store, "store"); //$NON-NLS-1$
+ checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
+ checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
+ checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
+ checkState(branchManager, "branchManager"); //$NON-NLS-1$
+ checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
+ checkState(queryManager, "queryManager"); //$NON-NLS-1$
+ checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
+ checkState(commitManager, "commitManager"); //$NON-NLS-1$
+ checkState(lockManager, "lockingManager"); //$NON-NLS-1$
+
+ packageRegistry.setReplacingDescriptors(true);
+ packageRegistry.setPackageProcessor(this);
+ packageRegistry.setPackageLoader(this);
+
+ branchManager.setBranchLoader(this);
+ branchManager.setTimeProvider(this);
+
+ revisionManager.setRevisionLoader(this);
+ sessionManager.setRepository(this);
+ queryManager.setRepository(this);
+ commitInfoManager.setCommitInfoLoader(this);
+ commitManager.setRepository(this);
+ lockManager.setRepository(this);
+ store.setRepository(this);
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ initProperties();
+ if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
+ {
+ throw new IllegalStateException("Store can not handle client assigned IDs: " + store);
+ }
+
+ store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING
+ : IStore.RevisionTemporality.NONE);
+ store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING
+ : IStore.RevisionParallelism.NONE);
+ revisionManager.setSupportingAudits(supportingAudits);
+ revisionManager.setSupportingBranches(supportingBranches);
+
+ LifecycleUtil.activate(store);
+ LifecycleUtil.activate(packageRegistry);
+ LifecycleUtil.activate(sessionManager);
+ LifecycleUtil.activate(revisionManager);
+ LifecycleUtil.activate(branchManager);
+ LifecycleUtil.activate(queryManager);
+ LifecycleUtil.activate(commitInfoManager);
+ LifecycleUtil.activate(commitManager);
+ LifecycleUtil.activate(queryHandlerProvider);
+
+ if (!skipInitialization)
+ {
+ long lastCommitTimeStamp = Math.max(store.getCreationTime(), store.getLastCommitTime());
+ timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+ initMainBranch(branchManager, lastCommitTimeStamp);
+
+ if (store.isFirstStart())
+ {
+ initSystemPackages();
+ initRootResource();
+ }
+ else
+ {
+ readPackageUnits();
+ readRootResource();
+ }
+
+ // This check does not work for CDOWorkspace:
+ // if (CDOIDUtil.isNull(rootResourceID))
+ // {
+ // throw new IllegalStateException("Root resource ID is null");
+ // }
+ }
+
+ LifecycleUtil.activate(lockManager); // Needs an initialized main branch / branch manager
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ LifecycleUtil.deactivate(lockManager);
+ LifecycleUtil.deactivate(queryHandlerProvider);
+ LifecycleUtil.deactivate(commitManager);
+ LifecycleUtil.deactivate(commitInfoManager);
+ LifecycleUtil.deactivate(queryManager);
+ LifecycleUtil.deactivate(revisionManager);
+ LifecycleUtil.deactivate(sessionManager);
+ LifecycleUtil.deactivate(store);
+ LifecycleUtil.deactivate(branchManager);
+ LifecycleUtil.deactivate(packageRegistry);
+ super.doDeactivate();
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+ public static class Default extends Repository
+ {
+ public Default()
+ {
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ if (getPackageRegistry(false) == null)
+ {
+ setPackageRegistry(createPackageRegistry());
+ }
+
+ if (getSessionManager() == null)
+ {
+ setSessionManager(createSessionManager());
+ }
+
+ if (getBranchManager() == null)
+ {
+ setBranchManager(createBranchManager());
+ }
+
+ if (getRevisionManager() == null)
+ {
+ setRevisionManager(createRevisionManager());
+ }
+
+ if (getQueryManager() == null)
+ {
+ setQueryManager(createQueryManager());
+ }
+
+ if (getCommitInfoManager() == null)
+ {
+ setCommitInfoManager(createCommitInfoManager());
+ }
+
+ if (getCommitManager() == null)
+ {
+ setCommitManager(createCommitManager());
+ }
+
+ if (getLockManager() == null)
+ {
+ setLockManager(createLockManager());
+ }
+
+ super.doBeforeActivate();
+ }
+
+ protected InternalCDOPackageRegistry createPackageRegistry()
+ {
+ return new CDOPackageRegistryImpl();
+ }
+
+ protected InternalSessionManager createSessionManager()
+ {
+ return new SessionManager();
+ }
+
+ protected InternalCDOBranchManager createBranchManager()
+ {
+ return CDOBranchUtil.createBranchManager();
+ }
+
+ protected InternalCDORevisionManager createRevisionManager()
+ {
+ return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
+ }
+
+ protected InternalQueryManager createQueryManager()
+ {
+ return new QueryManager();
+ }
+
+ protected InternalCDOCommitInfoManager createCommitInfoManager()
+ {
+ return CDOCommitInfoUtil.createCommitInfoManager();
+ }
+
+ protected InternalCommitManager createCommitManager()
+ {
+ return new CommitManager();
+ }
+
+ protected InternalLockManager createLockManager()
+ {
+ return new LockManager();
+ }
+ }
+}

Back to the top