Index: src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (working copy) @@ -1099,8 +1099,7 @@ throw new ItemExistsException(safeGetJCRPath(errorId)); } if (id == null) { - // create new id - id = new NodeId(); + id = context.getNodeIdFactory().newNodeId(); } if (nodeTypeName == null) { // no primary node type specified, @@ -1617,8 +1616,8 @@ sharedState.addShare(destParentId); return sharedState; } - // always create new uuid - id = new NodeId(); + // always create new node id + id = context.getNodeIdFactory().newNodeId(); if (referenceable) { // remember uuid mapping refTracker.mappedId(srcState.getNodeId(), id); @@ -1626,8 +1625,8 @@ break; case CLONE: if (!referenceable) { - // non-referenceable node: always create new uuid - id = new NodeId(); + // non-referenceable node: always create new node id + id = context.getNodeIdFactory().newNodeId(); break; } // use same uuid as source node @@ -1645,8 +1644,8 @@ break; case CLONE_REMOVE_EXISTING: if (!referenceable) { - // non-referenceable node: always create new uuid - id = new NodeId(); + // non-referenceable node: always create new node id + id = context.getNodeIdFactory().newNodeId(); break; } // use same uuid as source node @@ -1756,7 +1755,7 @@ } // copy properties for (Name propName : srcState.getPropertyNames()) { - Path propPath = PathFactoryImpl.getInstance().create(srcPath, propName, true); + Path propPath = PathFactoryImpl.getInstance().create(srcPath, propName, true); PropertyId propId = new PropertyId(srcState.getNodeId(), propName); if (!srcAccessMgr.canRead(propPath, propId)) { continue; Index: src/main/java/org/apache/jackrabbit/core/NodeImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/NodeImpl.java (working copy) @@ -503,7 +503,7 @@ NodeState nodeState; try { if (id == null) { - id = new NodeId(); + id = sessionContext.getNodeIdFactory().newNodeId(); } nodeState = stateMgr.createTransientNodeState(id, nodeType.getQName(), Index: src/main/java/org/apache/jackrabbit/core/RepositoryContext.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/RepositoryContext.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/RepositoryContext.java (working copy) @@ -20,6 +20,7 @@ import org.apache.jackrabbit.core.data.DataStore; import org.apache.jackrabbit.core.fs.FileSystem; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.security.JackrabbitSecurityManager; import org.apache.jackrabbit.core.state.ItemStateCacheFactory; @@ -90,6 +91,8 @@ */ private ItemStateCacheFactory itemStateCacheFactory; + private NodeIdFactory nodeIdFactory; + /** * Repository-wide timer instance. */ @@ -323,4 +326,12 @@ this.itemStateCacheFactory = itemStateCacheFactory; } + public void setNodeIdFactory(NodeIdFactory nodeIdFactory) { + this.nodeIdFactory = nodeIdFactory; + } + + public NodeIdFactory getNodeIdFactory() { + return nodeIdFactory; + } + } Index: src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (working copy) @@ -80,6 +80,7 @@ import org.apache.jackrabbit.core.fs.FileSystemException; import org.apache.jackrabbit.core.fs.FileSystemResource; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.lock.LockManager; import org.apache.jackrabbit.core.lock.LockManagerImpl; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; @@ -184,6 +185,8 @@ // configuration of the repository protected final RepositoryConfig repConfig; + protected NodeIdFactory nodeIdFactory; + /** * the delegating observation dispatcher for all workspaces */ @@ -303,6 +306,10 @@ context.setDataStore(dataStore); } + nodeIdFactory = new NodeIdFactory(repConfig.getHomeDir()); + nodeIdFactory.open(); + context.setNodeIdFactory(nodeIdFactory); + context.setWorkspaceManager(new WorkspaceManager(this)); // init workspace configs @@ -510,7 +517,8 @@ VERSION_STORAGE_NODE_ID, ACTIVITIES_NODE_ID, context.getItemStateCacheFactory(), - ismLocking); + ismLocking, + context.getNodeIdFactory()); } /** @@ -1138,6 +1146,12 @@ log.error("error while closing repository file system", e); } + try { + nodeIdFactory.close(); + } catch (RepositoryException e) { + log.error("error while closing repository file system", e); + } + // make sure this instance is not used anymore disposed = true; @@ -1377,7 +1391,8 @@ context.getNodeTypeRegistry(), true, context.getItemStateCacheFactory(), - locking); + locking, + context.getNodeIdFactory()); } /** Index: src/main/java/org/apache/jackrabbit/core/id/NodeId.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/id/NodeId.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/id/NodeId.java (working copy) @@ -160,25 +160,19 @@ } /** - * Creates a node identifier using the given random number generator. - * - * @param random random number generator + * Creates a random node identifier using a secure random number generator. */ - public NodeId(Random random) { - this( // Most significant 64 bits, with version field set to 4 + public static NodeId randomId() { + Random random = SeededSecureRandom.getInstance(); + return new NodeId( + // Most significant 64 bits, with version field set to 4 random.nextLong() & 0xFfffFfffFfff0fffL | 0x0000000000004000L, // Least significant 64 bits, with variant field set to IETF - random.nextLong() & 0x3fffFfffFfffFfffL | 0x8000000000000000L); + random.nextLong() & 0x3fffFfffFfffFfffL | 0x8000000000000000L + ); } /** - * Creates a random node identifier using a secure random number generator. - */ - public NodeId() { - this(SeededSecureRandom.getInstance()); - } - - /** * Returns the 64 most significant bits of this identifier. * * @return 64 most significant bits Index: src/main/java/org/apache/jackrabbit/core/id/NodeIdFactory.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/id/NodeIdFactory.java (revision 0) +++ src/main/java/org/apache/jackrabbit/core/id/NodeIdFactory.java (revision 0) @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.id; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Properties; +import javax.jcr.RepositoryException; + +/** + * A factory for creating new node ids. + */ +public class NodeIdFactory { + + public final static String SEQUENTIAL_NODE_ID = "jackrabbit.sequentialNodeId"; + + private final static String NODE_ID_FILE = "nodeId.properties"; + private final static String NODE_ID_FILE_TEMP = "nodeId.properties.temp"; + private final static String MSB = "msb"; + private final static String NEXT_LSB = "nextLsb"; + private final static int DEFAULT_CACHE_SIZE = 128; + + private final String repositoryHome; + + private boolean createRandom; + private long msb; + private long nextLsb; + private long storedLsb; + private int cacheSize = DEFAULT_CACHE_SIZE; + + public NodeIdFactory(String repositoryHome) { + this.repositoryHome = repositoryHome; + } + + public void setCacheSize(int cacheSize) { + this.cacheSize = cacheSize; + } + + public void open() throws RepositoryException { + String seq = System.getProperty(SEQUENTIAL_NODE_ID); + if (seq == null) { + createRandom = true; + return; + } + try { + File n = new File(repositoryHome, NODE_ID_FILE); + if (!n.exists()) { + File temp = new File(repositoryHome, NODE_ID_FILE_TEMP); + if (temp.exists()) { + temp.renameTo(n); + } else { + n.getParentFile().mkdirs(); + n.createNewFile(); + } + } + Properties p = new Properties(); + p.load(new FileReader(n)); + String defaultMsb = "0", defaultLsb = "0"; + int index = seq.indexOf("/"); + if (index >= 0) { + defaultMsb = seq.substring(0, index); + defaultLsb = seq.substring(index + 1); + } + msb = Long.parseLong(p.getProperty(MSB, defaultMsb), 16); + storedLsb = nextLsb = Long.parseLong(p.getProperty(NEXT_LSB, defaultLsb), 16); + } catch (Exception e) { + throw new RepositoryException("Could not open node id factory", e); + } + } + + public void close() throws RepositoryException { + if (!createRandom) { + store(nextLsb); + } + } + + private void store(long lsb) throws RepositoryException { + this.storedLsb = lsb; + Properties p = new Properties(); + p.setProperty(MSB, Long.toHexString(msb)); + p.setProperty(NEXT_LSB, Long.toHexString(lsb)); + try { + File temp = new File(repositoryHome, NODE_ID_FILE_TEMP); + p.store(new FileWriter(temp), null); + File n = new File(repositoryHome, NODE_ID_FILE); + n.delete(); + temp.renameTo(n); + } catch (IOException e) { + throw new RepositoryException("Could not store next node id", e); + } + } + + public NodeId newNodeId() throws RepositoryException { + if (createRandom) { + return NodeId.randomId(); + } + long lsb = nextLsb++; + if (lsb >= storedLsb) { + store(lsb + cacheSize); + } + return new NodeId(msb, lsb); + } + +} Index: src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (working copy) @@ -101,7 +101,7 @@ /** Sentinel instance used to mark a non-existent bundle in the cache */ private static final NodePropBundle MISSING = - new NodePropBundle(new NodeId()); + new NodePropBundle(NodeId.randomId()); /** the index for namespaces */ private StringIndex nsIndex; Index: src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (working copy) @@ -1645,7 +1645,7 @@ */ private static final int ENTRY_LENGTH = Long.toString(Long.MAX_VALUE).length() + Action.ADD_NODE.length() - + new NodeId().toString().length() + 2; + + new NodeId(0, 0).toString().length() + 2; /** * The id of the node to add. @@ -1928,7 +1928,7 @@ */ private static final int ENTRY_LENGTH = Long.toString(Long.MAX_VALUE).length() + Action.DELETE_NODE.length() - + new NodeId().toString().length() + 2; + + new NodeId(0, 0).toString().length() + 2; /** * The id of the node to remove. Index: src/main/java/org/apache/jackrabbit/core/session/SessionContext.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/session/SessionContext.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/session/SessionContext.java (working copy) @@ -30,6 +30,7 @@ import org.apache.jackrabbit.core.config.WorkspaceConfig; import org.apache.jackrabbit.core.data.DataStore; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.observation.ObservationManagerImpl; @@ -286,6 +287,10 @@ this.observationManager = observationManager; } + public NodeIdFactory getNodeIdFactory() { + return repositoryContext.getNodeIdFactory(); + } + //--------------------------------------------------------< NameResolver > public Name getQName(String name) Index: src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (working copy) @@ -20,6 +20,7 @@ import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.id.PropertyId; import org.apache.jackrabbit.core.observation.EventStateCollectionFactory; import org.apache.jackrabbit.spi.Name; @@ -76,8 +77,8 @@ /** * Creates a new {@code LocalItemStateManager} instance and registers it as an {@link ItemStateListener} - * with the given {@link SharedItemStateManager}. - * + * with the given {@link SharedItemStateManager}. + * * @param sharedStateMgr the {@link SharedItemStateManager} * @param factory the {@link EventStateCollectionFactory} * @param cacheFactory the {@link ItemStateCacheFactory} @@ -548,4 +549,9 @@ public void nodeRemoved(NodeState state, Name name, int index, NodeId id) { dispatcher.notifyNodeRemoved(state, name, index, id); } + + public NodeIdFactory getNodeIdFactory() { + return sharedStateMgr.getNodeIdFactory(); + } + } Index: src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (working copy) @@ -37,6 +37,7 @@ import org.apache.jackrabbit.core.ZombieHierarchyManager; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.id.PropertyId; import org.apache.jackrabbit.spi.Name; import org.slf4j.Logger; @@ -479,7 +480,7 @@ // remove any descendant candidates boolean skip = false; for (Iterator it = candidateIds.iterator(); it.hasNext();) { - NodeId id = it.next(); + NodeId id = it.next(); if (nodeId.equals(id) || hierMgr.isAncestor(id, nodeId)) { // already a candidate or a descendant thereof // => skip @@ -968,4 +969,9 @@ return false; } } + + public NodeIdFactory getNodeIdFactory() { + return stateMgr.getNodeIdFactory(); + } + } Index: src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy) @@ -30,6 +30,7 @@ import org.apache.jackrabbit.core.cluster.UpdateEventChannel; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.id.PropertyId; import org.apache.jackrabbit.core.nodetype.EffectiveNodeType; import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException; @@ -181,6 +182,8 @@ */ private UpdateEventChannel eventChannel; + private final NodeIdFactory nodeIdFactory; + /** * Creates a new SharedItemStateManager instance. * @@ -193,7 +196,8 @@ NodeTypeRegistry ntReg, boolean usesReferences, ItemStateCacheFactory cacheFactory, - ISMLocking locking) + ISMLocking locking, + NodeIdFactory nodeIdFactory) throws ItemStateException { cache = new ItemStateReferenceCache(cacheFactory); this.persistMgr = persistMgr; @@ -201,6 +205,7 @@ this.usesReferences = usesReferences; this.rootNodeId = rootNodeId; this.ismLocking = locking; + this.nodeIdFactory = nodeIdFactory; // create root node state if it doesn't yet exist if (!hasNonVirtualItemState(rootNodeId)) { createRootNodeState(rootNodeId, ntReg); @@ -1114,17 +1119,17 @@ } } - + /** * Validates the hierarchy consistency of the changes in the changelog. - * + * * @param changeLog * The local changelog the should be validated * @throws ItemStateException * If the hierarchy changes are inconsistent. * @throws RepositoryException * If the consistency could not be validated - * + * */ private void validateHierarchy(ChangeLog changeLog) throws ItemStateException, RepositoryException { @@ -1140,7 +1145,7 @@ /** * Checks the parents and children of all deleted node states in the changelog. - * + * * @param changeLog * The local changelog the should be validated * @throws ItemStateException @@ -1210,7 +1215,7 @@ /** * Checks the parents and children of all added node states in the changelog. - * + * * @param changeLog * The local changelog the should be validated * @throws ItemStateException @@ -1262,7 +1267,7 @@ /** * Checks the parents and children of all modified node states in the changelog. - * + * * @param changeLog * The local changelog the should be validated * @throws ItemStateException @@ -1371,7 +1376,7 @@ /** * Check the consistency of a parent/child relationship. - * + * * @param changeLog * The changelog to check * @param childState @@ -1417,7 +1422,7 @@ /** * Determines whether the specified node is shareable, i.e. whether the mixin type mix:shareable * is either directly assigned or indirectly inherited. - * + * * @param state * node state to check * @return true if the specified node is shareable, false otherwise. @@ -1441,7 +1446,7 @@ throw new RepositoryException(msg, ntce); } } - + /** * Begin update operation. This will return an object that can itself be * ended/canceled. @@ -1848,4 +1853,9 @@ throw new ItemStateException("Interrupted while acquiring write lock"); } } + + public NodeIdFactory getNodeIdFactory() { + return this.nodeIdFactory; + } + } Index: src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/state/UpdatableItemStateManager.java (working copy) @@ -18,6 +18,7 @@ import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import javax.jcr.ReferentialIntegrityException; @@ -120,4 +121,7 @@ * Disposes this UpdatableItemStateManager and frees resources. */ void dispose(); + + NodeIdFactory getNodeIdFactory(); + } Index: src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java (working copy) @@ -354,7 +354,7 @@ public synchronized Name[] getVersionNames() { return nameCache.keySet().toArray(new Name[nameCache.size()]); } - + /** * {@inheritDoc} */ @@ -563,7 +563,7 @@ predecessors = new InternalValue[]{InternalValue.create(last)}; } - NodeId versionId = new NodeId(); + NodeId versionId = vMgr.getNodeIdFactory().newNodeId(); NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true); // check for jcr:activity @@ -619,7 +619,7 @@ NodeState nodeState, NodeId copiedFrom) throws RepositoryException { // create history node - NodeId historyId = new NodeId(); + NodeId historyId = vMgr.getNodeIdFactory().newNodeId(); NodeStateEx pNode = parent.addNode(name, NameConstants.NT_VERSIONHISTORY, historyId, true); // set the versionable uuid @@ -635,7 +635,7 @@ } // create root version - NodeId versionId = new NodeId(); + NodeId versionId = vMgr.getNodeIdFactory().newNodeId(); NodeStateEx vNode = pNode.addNode(NameConstants.JCR_ROOTVERSION, NameConstants.NT_VERSION, versionId, true); // initialize 'created' and 'predecessors' Index: src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerBase.java (working copy) @@ -29,6 +29,7 @@ import javax.jcr.version.VersionException; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.state.DefaultISMLocking; import org.apache.jackrabbit.core.state.ISMLocking.ReadLock; @@ -76,12 +77,16 @@ */ private final DefaultISMLocking rwLock = new DefaultISMLocking(); + private final NodeIdFactory nodeIdFactory; + protected InternalVersionManagerBase(NodeTypeRegistry ntReg, NodeId historiesId, - NodeId activitiesId) { + NodeId activitiesId, + NodeIdFactory nodeIdFactory) { this.ntReg = ntReg; this.historiesId = historiesId; this.activitiesId = activitiesId; + this.nodeIdFactory = nodeIdFactory; } //-------------------------------------------------------< InternalVersionManager > @@ -449,7 +454,7 @@ WriteOperation operation = startWriteOperation(); try { // create deep path - NodeId activityId = new NodeId(); + NodeId activityId = nodeIdFactory.newNodeId(); NodeStateEx parent = getParentNode(getActivitiesRoot(), activityId.toString(), NameConstants.REP_ACTIVITIES); Name name = getName(activityId.toString()); @@ -728,7 +733,7 @@ /** * Set version label on the specified version. - * + * * @param history version history * @param version version name * @param label version label @@ -816,4 +821,9 @@ throw new RepositoryException(e); } } + + public NodeIdFactory getNodeIdFactory() { + return nodeIdFactory; + } + } Index: src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java (working copy) @@ -35,6 +35,7 @@ import org.apache.jackrabbit.core.fs.FileSystem; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.id.PropertyId; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.observation.DelegatingObservationDispatcher; @@ -120,7 +121,7 @@ * Persistent root node of the activities. */ private final NodeStateEx activitiesRoot; - + /** * Map of returned items. this is kept for invalidating */ @@ -149,8 +150,9 @@ NodeId historiesId, NodeId activitiesId, ItemStateCacheFactory cacheFactory, - ISMLocking ismLocking) throws RepositoryException { - super(ntReg, historiesId, activitiesId); + ISMLocking ismLocking, + NodeIdFactory nodeIdFactory) throws RepositoryException { + super(ntReg, historiesId, activitiesId, nodeIdFactory); try { this.pMgr = pMgr; this.fs = fs; @@ -188,7 +190,7 @@ pMgr.store(cl); } - sharedStateMgr = createItemStateManager(pMgr, systemId, ntReg, cacheFactory, ismLocking); + sharedStateMgr = createItemStateManager(pMgr, systemId, ntReg, cacheFactory, ismLocking, nodeIdFactory); stateMgr = LocalItemStateManager.createInstance(sharedStateMgr, escFactory, cacheFactory); stateMgr.addListener(this); @@ -572,9 +574,10 @@ NodeId rootId, NodeTypeRegistry ntReg, ItemStateCacheFactory cacheFactory, - ISMLocking ismLocking) + ISMLocking ismLocking, + NodeIdFactory nodeIdFactory) throws ItemStateException { - return new VersionItemStateManager(pMgr, rootId, ntReg, cacheFactory, ismLocking); + return new VersionItemStateManager(pMgr, rootId, ntReg, cacheFactory, ismLocking, nodeIdFactory); } /** Index: src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java (working copy) @@ -115,7 +115,7 @@ public InternalXAVersionManager(InternalVersionManagerImpl vMgr, NodeTypeRegistry ntReg, SessionImpl session, ItemStateCacheFactory cacheFactory) throws RepositoryException { - super(ntReg, vMgr.historiesId, vMgr.activitiesId); + super(ntReg, vMgr.historiesId, vMgr.activitiesId, vMgr.getNodeIdFactory()); this.vMgr = vMgr; this.session = session; this.stateMgr = XAItemStateManager.createInstance(vMgr.getSharedStateMgr(), Index: src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (working copy) @@ -557,7 +557,7 @@ NodeId parentId = nodeState.getNodeId(); // create a new node state if (id == null) { - id = new NodeId(); + id = stateMgr.getNodeIdFactory().newNodeId(); } NodeState state = stateMgr.createNew(id, nodeTypeName, parentId); Index: src/main/java/org/apache/jackrabbit/core/version/VersionItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/VersionItemStateManager.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/VersionItemStateManager.java (working copy) @@ -22,6 +22,7 @@ import javax.jcr.ReferentialIntegrityException; import org.apache.jackrabbit.core.id.NodeId; +import org.apache.jackrabbit.core.id.NodeIdFactory; import org.apache.jackrabbit.core.id.PropertyId; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.persistence.PersistenceManager; @@ -55,9 +56,10 @@ NodeId rootNodeId, NodeTypeRegistry ntReg, ItemStateCacheFactory cacheFactory, - ISMLocking locking) + ISMLocking locking, + NodeIdFactory nodeIdFactory) throws ItemStateException { - super(persistMgr, rootNodeId, ntReg, false, cacheFactory, locking); + super(persistMgr, rootNodeId, ntReg, false, cacheFactory, locking, nodeIdFactory); this.pMgr = persistMgr; } Index: src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplConfig.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplConfig.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplConfig.java (working copy) @@ -181,7 +181,7 @@ Name name = InternalVersionManagerBase.getName(rootId.toString()); if (configId == null) { - configId = new NodeId(); + configId = context.getNodeIdFactory().newNodeId(); } NodeStateEx config = configParent.addNode(name, NameConstants.NT_CONFIGURATION, configId, true); Set mix = new HashSet(); Index: src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java (working copy) @@ -319,12 +319,10 @@ NodeId id, Name nodeTypeName) throws RepositoryException { + assert id != null; + // create a new node state - VirtualNodeState state; - if (id == null) { - id = new NodeId(); - } - state = new VirtualNodeState(this, parent.getNodeId(), id, nodeTypeName, Name.EMPTY_ARRAY); + VirtualNodeState state = new VirtualNodeState(this, parent.getNodeId(), id, nodeTypeName, Name.EMPTY_ARRAY); cache(state); return state; Index: src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java (revision 1055081) +++ src/main/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java (working copy) @@ -74,7 +74,7 @@ * * @param parent * @param name - * @param id + * @param id (must not be null) * @param nodeTypeName * @return * @throws RepositoryException Index: src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/PersistenceManagerTest.java (working copy) @@ -46,9 +46,9 @@ public class PersistenceManagerTest extends TestCase { - private static final NodeId NODE_ID = new NodeId(); + private static final NodeId NODE_ID = NodeId.randomId(); - private static final NodeId CHILD_ID = new NodeId(); + private static final NodeId CHILD_ID = NodeId.randomId(); private static final Name TEST = NameFactoryImpl.getInstance().create("", "test"); Index: src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/cache/ConcurrentCacheTest.java (working copy) @@ -33,7 +33,7 @@ public void testConcurrentCache() { NodeId[] ids = new NodeId[1000]; for (int i = 0; i < ids.length; i++) { - ids[i] = new NodeId(); + ids[i] = NodeId.randomId(); } ConcurrentCache cache = Index: src/test/java/org/apache/jackrabbit/core/cluster/ClusterRecordTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/cluster/ClusterRecordTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/cluster/ClusterRecordTest.java (working copy) @@ -144,7 +144,7 @@ * @throws Exception */ public void testLockOperation() throws Exception { - LockEvent event = new LockEvent(new NodeId(), true, "admin"); + LockEvent event = new LockEvent(NodeId.randomId(), true, "admin"); master.createLockChannel(DEFAULT_WORKSPACE).create(event.getNodeId(), event.isDeep(), event.getUserId()).ended(true); @@ -162,7 +162,7 @@ * @throws Exception */ public void testUnlockOperation() throws Exception { - UnlockEvent event = new UnlockEvent(new NodeId()); + UnlockEvent event = new UnlockEvent(NodeId.randomId()); master.createLockChannel(DEFAULT_WORKSPACE).create(event.getNodeId()).ended(true); Index: src/test/java/org/apache/jackrabbit/core/cluster/UpdateEventFactory.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/cluster/UpdateEventFactory.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/cluster/UpdateEventFactory.java (working copy) @@ -156,7 +156,7 @@ protected NodeState createNodeState() { Name ntName = nameFactory.create("{}testnt"); NodeState n = new NodeState( - new NodeId(), ntName, + NodeId.randomId(), ntName, ROOT_NODE_ID, NodeState.STATUS_EXISTING, false); n.setMixinTypeNames(Collections.EMPTY_SET); return n; Index: src/test/java/org/apache/jackrabbit/core/data/PersistenceManagerIteratorTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/data/PersistenceManagerIteratorTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/data/PersistenceManagerIteratorTest.java (working copy) @@ -117,7 +117,7 @@ log("Random access"); for (int j = 0; j < 50; j++) { - after = new NodeId(); + after = NodeId.randomId(); log(" bigger than: " + after); for (NodeId id : apm.getAllNodeIds(after, 2)) { log(" " + id); Index: src/test/java/org/apache/jackrabbit/core/id/NodeIdFactoryTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/id/NodeIdFactoryTest.java (revision 0) +++ src/test/java/org/apache/jackrabbit/core/id/NodeIdFactoryTest.java (revision 0) @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.core.id; + +import java.io.File; +import java.io.IOException; +import javax.jcr.RepositoryException; +import org.apache.commons.io.FileUtils; +import junit.framework.TestCase; + +public class NodeIdFactoryTest extends TestCase { + + private static final String factoryDir = "target/temp/nodeIdFactory"; + + public void setUp() throws IOException { + FileUtils.deleteDirectory(new File(factoryDir)); + } + + public void tearDown() throws IOException { + setUp(); + } + + public void testRandomVersusSequential() throws RepositoryException { + System.clearProperty(NodeIdFactory.SEQUENTIAL_NODE_ID); + NodeIdFactory f = new NodeIdFactory(factoryDir); + f.open(); + NodeId id = f.newNodeId(); + assertTrue(id.getLeastSignificantBits() != 0); + f.close(); + + System.setProperty(NodeIdFactory.SEQUENTIAL_NODE_ID, "true"); + f = new NodeIdFactory(factoryDir); + f.open(); + id = f.newNodeId(); + assertTrue(id.getLeastSignificantBits() == 0); + f.close(); + } + + public void testNormalUsage() throws RepositoryException { + System.setProperty(NodeIdFactory.SEQUENTIAL_NODE_ID, "true"); + NodeIdFactory f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-0000-0000-000000000000", f.newNodeId().toString()); + f.close(); + f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-0000-0000-000000000001", f.newNodeId().toString()); + f.close(); + } + + public void testOffset() throws RepositoryException { + System.setProperty(NodeIdFactory.SEQUENTIAL_NODE_ID, "ab/0"); + NodeIdFactory f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-00ab-0000-000000000000", f.newNodeId().toString()); + f.close(); + f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-00ab-0000-000000000001", f.newNodeId().toString()); + f.close(); + } + + public void testKillRepository() throws RepositoryException { + System.setProperty(NodeIdFactory.SEQUENTIAL_NODE_ID, "true"); + int cacheSize = 8; + for (int i = 1; i < 40; i++) { + File id = new File(factoryDir, "nodeId.properties"); + id.delete(); + NodeIdFactory f = new NodeIdFactory(factoryDir); + f.setCacheSize(cacheSize); + f.open(); + NodeId last = null; + for (int j = 0; j < i; j++) { + last = f.newNodeId(); + } + // don't close the factory - this is the same as killing the process + // f.close(); + f = new NodeIdFactory(factoryDir); + f.setCacheSize(cacheSize); + f.open(); + NodeId n = f.newNodeId(); + assertTrue("now: " + n + " last: " + last, n.compareTo(last) > 0); + long diff = n.getLeastSignificantBits() - last.getLeastSignificantBits(); + assertTrue("diff: " + diff, diff > 0 && diff <= cacheSize); + f.close(); + } + } + + public void testKillWhileSaving() throws RepositoryException { + System.setProperty(NodeIdFactory.SEQUENTIAL_NODE_ID, "true"); + NodeIdFactory f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-0000-0000-000000000000", f.newNodeId().toString()); + f.close(); + File id = new File(factoryDir, "nodeId.properties"); + assertTrue(id.exists()); + File idTemp = new File(factoryDir, "nodeId.properties.temp"); + id.renameTo(idTemp); + f = new NodeIdFactory(factoryDir); + f.open(); + assertEquals("00000000-0000-0000-0000-000000000001", f.newNodeId().toString()); + assertFalse(idTemp.exists()); + f.close(); + } + +} Index: src/test/java/org/apache/jackrabbit/core/id/NodeIdTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/id/NodeIdTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/id/NodeIdTest.java (working copy) @@ -21,7 +21,7 @@ public class NodeIdTest extends TestCase { private static final NodeId[] ids = { - new NodeId(), // random id + NodeId.randomId(), // random id new NodeId(0, 0), new NodeId(-1, -1), new NodeId("cafebabe-cafe-babe-cafe-babecafebabe") @@ -81,7 +81,7 @@ public void testUuidFormat() { long maxHigh = 0, maxLow = 0, minHigh = -1L, minLow = -1L; for (int i = 0; i < 100; i++) { - NodeId id = new NodeId(); + NodeId id = NodeId.randomId(); assertUuidFormat(id); maxHigh |= id.getMostSignificantBits(); maxLow |= id.getLeastSignificantBits(); Index: src/test/java/org/apache/jackrabbit/core/id/TestAll.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/id/TestAll.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/id/TestAll.java (working copy) @@ -32,7 +32,10 @@ */ public static Test suite() { TestSuite suite = new TestSuite("Identifier tests"); + + suite.addTestSuite(NodeIdFactoryTest.class); suite.addTestSuite(NodeIdTest.class); + return suite; } } Index: src/test/java/org/apache/jackrabbit/core/persistence/util/BundleBindingTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/persistence/util/BundleBindingTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/persistence/util/BundleBindingTest.java (working copy) @@ -50,11 +50,11 @@ protected void setUp() throws Exception { final String[] strings = new String[] { - "http://www.jcp.org/jcr/1.0", - "http://www.jcp.org/jcr/nt/1.0", - "http://www.jcp.org/jcr/mix/1.0", + "http://www.jcp.org/jcr/1.0", + "http://www.jcp.org/jcr/nt/1.0", + "http://www.jcp.org/jcr/mix/1.0", "unstructured", - "created", + "created", "createdBy", "", "binary", @@ -87,7 +87,7 @@ } public void testEmptyBundle() throws Exception { - NodePropBundle bundle = new NodePropBundle(new NodeId()); + NodePropBundle bundle = new NodePropBundle(NodeId.randomId()); bundle.setParentId(new NodeId(1, 2)); bundle.setNodeTypeName(NameConstants.NT_UNSTRUCTURED); bundle.setMixinTypeNames(Collections.emptySet()); @@ -286,27 +286,27 @@ * Tests serialization of custom namespaces. */ public void testCustomNamespaces() throws Exception { - NodePropBundle bundle = new NodePropBundle(new NodeId()); - bundle.setParentId(new NodeId()); + NodePropBundle bundle = new NodePropBundle(NodeId.randomId()); + bundle.setParentId(NodeId.randomId()); bundle.setNodeTypeName(NameConstants.NT_UNSTRUCTURED); bundle.setMixinTypeNames(Collections.emptySet()); bundle.setSharedSet(Collections.emptySet()); - bundle.addChildNodeEntry(factory.create("ns1", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns2", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns3", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns4", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns5", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns6", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns7", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns8", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns1", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns1", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns2", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns3", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns1", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns2", "test"), new NodeId()); - bundle.addChildNodeEntry(factory.create("ns3", "test"), new NodeId()); + bundle.addChildNodeEntry(factory.create("ns1", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns2", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns3", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns4", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns5", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns6", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns7", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns8", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns1", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns1", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns2", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns3", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns1", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns2", "test"), NodeId.randomId()); + bundle.addChildNodeEntry(factory.create("ns3", "test"), NodeId.randomId()); assertBundleRoundtrip(bundle); } @@ -344,8 +344,8 @@ private void assertValueSerialization(InternalValue value) throws Exception { - NodePropBundle bundle = new NodePropBundle(new NodeId()); - bundle.setParentId(new NodeId()); + NodePropBundle bundle = new NodePropBundle(NodeId.randomId()); + bundle.setParentId(NodeId.randomId()); bundle.setNodeTypeName(NameConstants.NT_UNSTRUCTURED); bundle.setMixinTypeNames(Collections.emptySet()); bundle.setSharedSet(Collections.emptySet()); Index: src/test/java/org/apache/jackrabbit/core/query/lucene/IDFieldTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/query/lucene/IDFieldTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/query/lucene/IDFieldTest.java (working copy) @@ -27,7 +27,7 @@ public class IDFieldTest extends TestCase { public void testPerformance() { - NodeId id = new NodeId(); + NodeId id = NodeId.randomId(); long time = System.currentTimeMillis(); for (int i = 0; i < 1000 * 1000; i++) { new IDField(id); Index: src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/query/lucene/SlowQueryHandler.java (working copy) @@ -36,7 +36,7 @@ } catch (InterruptedException e) { // ignore } - getContext().getItemStateManager().hasItemState(new NodeId()); + getContext().getItemStateManager().hasItemState(NodeId.randomId()); super.doInit(); } Index: src/test/java/org/apache/jackrabbit/core/security/AccessManagerTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/security/AccessManagerTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/security/AccessManagerTest.java (working copy) @@ -118,7 +118,7 @@ public void testCheckPermissionWithUnknowId() throws RepositoryException, NotExecutableException { Session s = getHelper().getReadOnlySession(); - NodeId id = new NodeId(); + NodeId id = NodeId.randomId(); try { AccessManager acMgr = getAccessManager(s); acMgr.checkPermission(id, AccessManager.READ); Index: src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EntryTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EntryTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/security/authorization/acl/EntryTest.java (working copy) @@ -62,7 +62,7 @@ // false since acl has been created from path only -> no id assertFalse(entry.isLocal(((NodeImpl) testRootNode).getNodeId())); // false since internal id is null -> will never match. - assertFalse(entry.isLocal(new NodeId())); + assertFalse(entry.isLocal(NodeId.randomId())); } public void testIsLocal2() throws NotExecutableException, RepositoryException { @@ -80,14 +80,14 @@ assertTrue(acls[0] instanceof ACLTemplate); ACLTemplate acl = (ACLTemplate) acls[0]; - assertEquals(path, acl.getPath()); + assertEquals(path, acl.getPath()); ACLTemplate.Entry entry = acl.createEntry(testPrincipal, new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_READ)}, true, Collections.emptyMap()); // node is must be present + must match to testrootnodes id. assertTrue(entry.isLocal(((NodeImpl) testRootNode).getNodeId())); // but not to a random id. - assertFalse(entry.isLocal(new NodeId())); + assertFalse(entry.isLocal(NodeId.randomId())); } public void testRestrictions() throws RepositoryException { Index: src/test/java/org/apache/jackrabbit/core/state/AbstractISMLockingTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/state/AbstractISMLockingTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/state/AbstractISMLockingTest.java (working copy) @@ -55,7 +55,7 @@ protected void setUp() throws Exception { super.setUp(); locking = createISMLocking(); - NodeId id = new NodeId(); + NodeId id = NodeId.randomId(); state = new NodeState(id, NameConstants.NT_BASE, null, ItemState.STATUS_EXISTING, true); refs = new NodeReferences(state.getNodeId()); logs = new ArrayList(); @@ -82,7 +82,7 @@ * Checks the following requirement:

While a read lock is held for a given item with id * I an implementation must ensure that no write lock is issued for a change log that * contains a reference to an item with id I. - * + * * @throws InterruptedException on interruption; this will err the test */ public void testReadBlocksWrite() throws InterruptedException { @@ -98,7 +98,7 @@ * C an implementation must ensure that no read lock is issued for an item that is contained * in C, unless the current thread is the owner of the write lock!

The "unless" * clause is tested by {@link #testWriteBlocksRead_notIfSameThread()} test. - * + * * @throws InterruptedException on interruption; this will err the test */ public void testWriteBlocksRead() throws InterruptedException { @@ -132,7 +132,7 @@ * with C. That is both change logs contain a reference to the same item. Please note that an * implementation is free to block requests entirely for additional write lock while a write lock is * active. It is not a requirement to support concurrent write locks. - * + * * @throws InterruptedException on interruption; this will err the test */ public void testIntersectingWrites() throws InterruptedException { @@ -147,7 +147,7 @@ /** * Checks if a downgraded write lock allows other threads to read again. - * + * * @throws InterruptedException on interruption; this will err the test */ public void testDowngrade() throws InterruptedException { @@ -166,7 +166,7 @@ * Creates and starts a thread that acquires and releases the write lock of the given * ISMLocking for the given changelog. The thread's interrupted status is set if it was * interrupted during the acquire-release sequence and could therefore not finish it. - * + * * @param lock the ISMLocking to use * @param changeLog the ChangeLog to use * @return a thread that has been started @@ -190,7 +190,7 @@ * Creates and starts an thread that acquires and releases the read lock of the given * ISMLocking for the given id. The thread's interrupted status is set if it was interrupted * during the acquire-release sequence and could therefore not finish it. - * + * * @param lock the ISMLocking to use * @param id the id to use * @return a thread that has been started @@ -214,7 +214,7 @@ * Verifies that the given thread is blocked. Then it interrupts the thread and waits a certain amount of * time for it to complete. (If it doesn't complete within that time then the test that calls this method * fails). - * + * * @param other a started thread * @throws InterruptedException on interruption */ @@ -230,7 +230,7 @@ * Verifies that the given thread is not blocked and runs to completion within a certain amount of time * and without interruption. (If it doesn't complete within that time without interruption then the test * that calls this method fails). - * + * * @param other a started thread * @throws InterruptedException on interruption */ Index: src/test/java/org/apache/jackrabbit/core/state/ChangeLogTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/state/ChangeLogTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/state/ChangeLogTest.java (working copy) @@ -40,7 +40,7 @@ * entry in either the added nor the removed states */ public void testAddDelete() throws Exception { - PropertyId id = new PropertyId(new NodeId(), factory.create("", "a")); + PropertyId id = new PropertyId(NodeId.randomId(), factory.create("", "a")); ItemState state = new PropertyState(id, ItemState.STATUS_NEW, false); ChangeLog log = new ChangeLog(); @@ -59,7 +59,7 @@ * in the added states. */ public void testAddModify() throws Exception { - PropertyId id = new PropertyId(new NodeId(), factory.create("", "a")); + PropertyId id = new PropertyId(NodeId.randomId(), factory.create("", "a")); ItemState state = new PropertyState(id, ItemState.STATUS_NEW, false); ChangeLog log = new ChangeLog(); @@ -80,7 +80,7 @@ public void testPreserveOrder() throws Exception { ItemState[] states = new ItemState[10]; for (int i = 0; i < states.length; i++) { - PropertyId id = new PropertyId(new NodeId(), factory.create("", "a" + i)); + PropertyId id = new PropertyId(NodeId.randomId(), factory.create("", "a" + i)); states[i] = new PropertyState(id, ItemState.STATUS_NEW, false); } Index: src/test/java/org/apache/jackrabbit/core/value/InternalValueFactoryTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/value/InternalValueFactoryTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/value/InternalValueFactoryTest.java (working copy) @@ -38,7 +38,7 @@ factory = InternalValueFactory.getInstance(); rootPath = PathFactoryImpl.getInstance().getRootPath(); testName = NameFactoryImpl.getInstance().create(Name.NS_JCR_URI, "data"); - reference = new NodeId().toString(); + reference = NodeId.randomId().toString(); } protected void tearDown() throws Exception { Index: src/test/java/org/apache/jackrabbit/core/value/InternalValueTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/value/InternalValueTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/value/InternalValueTest.java (working copy) @@ -38,7 +38,7 @@ factory = InternalValueFactory.getInstance(); rootPath = PathFactoryImpl.getInstance().getRootPath(); testName = NameFactoryImpl.getInstance().create(Name.NS_JCR_URI, "data"); - reference = new NodeId().toString(); + reference = NodeId.randomId().toString(); } protected void tearDown() throws Exception { Index: src/test/java/org/apache/jackrabbit/core/version/VersionIteratorImplTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/version/VersionIteratorImplTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/version/VersionIteratorImplTest.java (working copy) @@ -64,9 +64,9 @@ public void testVersionIterator() throws Exception { - InternalVersion version = new DummyInternalVersion(new InternalVersion[] {}, new NodeId()); + InternalVersion version = new DummyInternalVersion(new InternalVersion[] {}, NodeId.randomId()); for (int i = 1; i < VERSION_COUNT; i++) { - version = new DummyInternalVersion(new InternalVersion[] {version}, new NodeId()); + version = new DummyInternalVersion(new InternalVersion[] {version}, NodeId.randomId()); } try { Index: src/test/java/org/apache/jackrabbit/core/xml/WorkspaceImporterTest.java =================================================================== --- src/test/java/org/apache/jackrabbit/core/xml/WorkspaceImporterTest.java (revision 1055081) +++ src/test/java/org/apache/jackrabbit/core/xml/WorkspaceImporterTest.java (working copy) @@ -53,7 +53,7 @@ */ public void testReferenceImport() throws Exception { try { - NodeId id = new NodeId(); + NodeId id = NodeId.randomId(); String xml = "