Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 82085 invoked from network); 21 Jul 2009 23:41:08 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 21 Jul 2009 23:41:08 -0000 Received: (qmail 36285 invoked by uid 500); 21 Jul 2009 23:42:13 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 36207 invoked by uid 500); 21 Jul 2009 23:42:13 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 36198 invoked by uid 99); 21 Jul 2009 23:42:13 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jul 2009 23:42:13 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jul 2009 23:42:01 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 2CF972388965; Tue, 21 Jul 2009 23:41:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r796586 [1/2] - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/ jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/ jackra... Date: Tue, 21 Jul 2009 23:41:40 -0000 To: commits@jackrabbit.apache.org From: tripod@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090721234141.2CF972388965@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: tripod Date: Tue Jul 21 23:41:39 2009 New Revision: 796586 URL: http://svn.apache.org/viewvc?rev=796586&view=rev Log: JCR-2140 Configurations and Baselines Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplConfig.java - copied, changed from r795866, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSet.java (contents, props changed) - copied, changed from r795866, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JcrVersionManagerImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaseline.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaselineImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameConstants.java Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JcrVersionManagerImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JcrVersionManagerImpl.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JcrVersionManagerImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/JcrVersionManagerImpl.java Tue Jul 21 23:41:39 2009 @@ -38,12 +38,16 @@ import org.apache.jackrabbit.core.state.ItemStateException; import org.apache.jackrabbit.core.state.NodeState; import org.apache.jackrabbit.core.state.UpdatableItemStateManager; +import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.core.version.InternalActivity; +import org.apache.jackrabbit.core.version.InternalBaseline; +import org.apache.jackrabbit.core.version.InternalConfiguration; import org.apache.jackrabbit.core.version.InternalVersion; import org.apache.jackrabbit.core.version.InternalVersionHistory; -import org.apache.jackrabbit.core.version.JcrVersionManagerImplMerge; +import org.apache.jackrabbit.core.version.JcrVersionManagerImplConfig; import org.apache.jackrabbit.core.version.NodeStateEx; import org.apache.jackrabbit.core.version.VersionImpl; +import org.apache.jackrabbit.core.version.VersionSet; import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.spi.Path; import org.apache.jackrabbit.spi.commons.name.NameConstants; @@ -60,7 +64,7 @@ * Note: For a cleaner architecture, we should probably rename the existing classes * that implement the internal version manager, and name this VersionManagerImpl. */ -public class JcrVersionManagerImpl extends JcrVersionManagerImplMerge +public class JcrVersionManagerImpl extends JcrVersionManagerImplConfig implements javax.jcr.version.VersionManager { /** @@ -84,11 +88,16 @@ * {@inheritDoc} */ public Version checkin(String absPath) throws RepositoryException { - // check lock status, holds and permissions - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | - ItemValidator.CHECK_PENDING_CHANGES_ON_NODE; - NodeStateEx state = getNodeState(absPath, options, Permission.VERSION_MNGMT); - NodeId baseId = checkoutCheckin(state, true, false); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE, + Permission.VERSION_MNGMT); + NodeId baseId; + if (isConfiguration(state)) { + InternalConfiguration config = vMgr.getConfiguration(state.getNodeId()); + baseId = checkin(config); + } else { + baseId = checkoutCheckin(state, true, false); + } return (VersionImpl) session.getNodeById(baseId); } @@ -96,20 +105,30 @@ * {@inheritDoc} */ public void checkout(String absPath) throws RepositoryException { - // check lock status, holds and permissions - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.VERSION_MNGMT); - checkoutCheckin(state, false, true); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.VERSION_MNGMT); + if (isConfiguration(state)) { + // currently has no effect + } else { + checkoutCheckin(state, false, true); + } } /** * {@inheritDoc} */ public Version checkpoint(String absPath) throws RepositoryException { - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | - ItemValidator.CHECK_PENDING_CHANGES_ON_NODE; - NodeStateEx state = getNodeState(absPath, options, Permission.VERSION_MNGMT); - NodeId baseId = checkoutCheckin(state, true, true); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE, + Permission.VERSION_MNGMT); + NodeId baseId; + if (isConfiguration(state)) { + InternalConfiguration config = vMgr.getConfiguration(state.getNodeId()); + baseId = checkin(config); + } else { + baseId = checkoutCheckin(state, true, true); + } return (VersionImpl) session.getNodeById(baseId); } @@ -160,43 +179,72 @@ throw new InvalidItemStateException(msg); } // add all versions to map of versions to restore - final Map toRestore = new HashMap(); + Map toRestore = new HashMap(); for (Version version : versions) { InternalVersion v = vMgr.getVersion(((VersionImpl) version).getNodeId()); - NodeId historyId = v.getVersionHistory().getId(); - // check for collision - if (toRestore.containsKey(historyId)) { - throw new VersionException("Unable to restore. Two or more versions have same version history."); + if (v instanceof InternalBaseline) { + // do simple explode, ignore restoring of nt:configuration node for now. + for (InternalVersion bv: ((InternalBaseline) v).getBaseVersions().versions().values()) { + // check for collision + NodeId historyId = bv.getVersionHistory().getId(); + if (toRestore.containsKey(historyId)) { + throw new VersionException("Unable to restore. Two or more versions have same version history."); + } + toRestore.put(historyId, bv); + } + } else { + // check for collision + NodeId historyId = v.getVersionHistory().getId(); + if (toRestore.containsKey(historyId)) { + throw new VersionException("Unable to restore. Two or more versions have same version history."); + } + toRestore.put(historyId, v); } - toRestore.put(historyId, v); } - restore(toRestore, removeExisting); + WriteOperation ops = startWriteOperation(); + try { + internalRestore(new VersionSet(toRestore, true), removeExisting); + ops.save(); + } catch (ItemStateException e) { + throw new RepositoryException(e); + } finally { + ops.close(); + } } /** * {@inheritDoc} */ - public void restore(String absPath, String versionName, - boolean removeExisting) + public void restore(String absPath, String versionName, boolean removeExisting) throws RepositoryException { - int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.NONE); - restore(state, session.getQName(versionName), removeExisting); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.NONE); + if (isConfiguration(state)) { + InternalConfiguration config = vMgr.getConfiguration(state.getNodeId()); + restore(config, session.getQName(versionName), removeExisting); + } else { + restore(state, session.getQName(versionName), removeExisting); + } } - /** * {@inheritDoc} */ public void restore(String absPath, Version version, boolean removeExisting) throws RepositoryException { - // first check if node exists if (session.nodeExists(absPath)) { // normal restore - int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.NONE); - restore(state, version, removeExisting); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.NONE); + if (isConfiguration(state)) { + InternalConfiguration config = vMgr.getConfiguration(state.getNodeId()); + restore(config, version, removeExisting); + } else { + restore(state, version, removeExisting); + } } else { // parent has to exist Path path = session.getQPath(absPath); @@ -204,8 +252,9 @@ Name name = path.getNameElement().getName(); NodeImpl parent = session.getItemManager().getNode(parentPath); - int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(parent, options, Permission.NONE); + NodeStateEx state = getNodeState(parent, + ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.NONE); restore(state, name, version, removeExisting); } } @@ -213,12 +262,17 @@ /** * {@inheritDoc} */ - public void restoreByLabel(String absPath, String versionLabel, - boolean removeExisting) + public void restoreByLabel(String absPath, String versionLabel, boolean removeExisting) throws RepositoryException { - int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.NONE); - restoreByLabel(state, session.getQName(versionLabel), removeExisting); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.NONE); + if (isConfiguration(state)) { + InternalConfiguration config = vMgr.getConfiguration(state.getNodeId()); + restoreByLabel(config, session.getQName(versionLabel), removeExisting); + } else { + restoreByLabel(state, session.getQName(versionLabel), removeExisting); + } } /** @@ -231,7 +285,9 @@ */ public void update(NodeImpl node, String srcWorkspaceName) throws RepositoryException { - NodeStateEx state = getNodeState(node, ItemValidator.CHECK_PENDING_CHANGES, Permission.VERSION_MNGMT); + NodeStateEx state = getNodeState(node, + ItemValidator.CHECK_PENDING_CHANGES, + Permission.VERSION_MNGMT); mergeOrUpdate(state, srcWorkspaceName, null, false, false); } @@ -250,7 +306,9 @@ public NodeIterator merge(String absPath, String srcWorkspaceName, boolean bestEffort, boolean isShallow) throws RepositoryException { - NodeStateEx state = getNodeState(absPath, ItemValidator.CHECK_PENDING_CHANGES, Permission.VERSION_MNGMT); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_PENDING_CHANGES, + Permission.VERSION_MNGMT); List failedIds = new LinkedList(); mergeOrUpdate(state, srcWorkspaceName, failedIds, bestEffort, isShallow); return new LazyItemIterator(session.getItemManager(), failedIds); @@ -306,8 +364,9 @@ */ public void doneMerge(String absPath, Version version) throws RepositoryException { - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_VERSIONING | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.VERSION_MNGMT); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD, + Permission.VERSION_MNGMT); finishMerge(state, version, false); } @@ -316,8 +375,9 @@ */ public void cancelMerge(String absPath, Version version) throws RepositoryException { - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_VERSIONING | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD; - NodeStateEx state = getNodeState(absPath, options, Permission.VERSION_MNGMT); + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD, + Permission.VERSION_MNGMT); finishMerge(state, version, true); } @@ -326,7 +386,61 @@ */ public Node createConfiguration(String absPath, Version baseline) throws RepositoryException { - throw new UnsupportedRepositoryOperationException("comming soon..."); + if (session.nodeExists(absPath)) { + // refuse to create a configuration if a baseline is specified. + if (baseline != null) { + throw new UnsupportedRepositoryOperationException( + "Create configuration to existing nodes only allowed without specifying a basline: " + absPath); + } + + NodeStateEx state = getNodeState(absPath, + ItemValidator.CHECK_LOCK | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD, + Permission.VERSION_MNGMT); + // check versionable + if (!checkVersionable(state)) { + throw new UnsupportedRepositoryOperationException("Node not full versionable: " + absPath); + } + if (state.getPropertyValue(NameConstants.JCR_CONFIGURATION) != null) { + throw new UnsupportedRepositoryOperationException("Node is already a configuration root: " + absPath); + } + + WriteOperation ops = startWriteOperation(); + try { + NodeId configId = vMgr.createConfiguration(session, state.getNodeId()); + state.setPropertyValue(NameConstants.JCR_CONFIGURATION, InternalValue.create(configId)); + state.store(); + ops.save(); + return session.getNodeById(configId); + } catch (ItemStateException e) { + throw new RepositoryException(e); + } finally { + ops.close(); + } + } else { + // check if supplied baseline is valid + if (baseline == null) { + throw new UnsupportedRepositoryOperationException( + "CreateConfiguration on non-existing path must supply a baseline: " + absPath); + } + VersionImpl v = (VersionImpl) baseline; + InternalBaseline bl = vMgr.getBaseline(v.getNodeId()); + if (bl == null) { + throw new UnsupportedRepositoryOperationException( + "Supplied version is not a baseline: " + v.safeGetJCRPath()); + } + + // parent has to exist + Path path = session.getQPath(absPath); + Path parentPath = path.getAncestor(1); + Name name = path.getNameElement().getName(); + NodeImpl parent = session.getItemManager().getNode(parentPath); + + NodeStateEx state = getNodeState(parent, + ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD, + Permission.NONE); + InternalConfiguration config = restore(state, name, bl); + return session.getNodeById(config.getId()); + } } /** @@ -443,4 +557,19 @@ throw new RepositoryException(e); } } + + /** + * Checks if the given node state is a nt:configuration. Note that this check + * is currently used to either avoid versioning operations on nt:configuration + * nodes or to use a differnt strategy for such nodes. + * + * @param state the state to check + * @return true if it is a configuration + * @throws RepositoryException if an error occurs + */ + private boolean isConfiguration(NodeStateEx state) throws RepositoryException { + return state.getEffectiveNodeType().includesNodeType(NameConstants.NT_CONFIGURATION); + } + + } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java Tue Jul 21 23:41:39 2009 @@ -16,18 +16,16 @@ */ package org.apache.jackrabbit.core.version; +import java.util.Set; + import javax.jcr.ItemNotFoundException; import javax.jcr.ReferentialIntegrityException; import javax.jcr.RepositoryException; import javax.jcr.Session; -import javax.jcr.Value; -import javax.jcr.UnsupportedRepositoryOperationException; +import javax.jcr.PropertyType; import javax.jcr.version.VersionException; -import org.apache.jackrabbit.core.NodeImpl; -import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.core.id.NodeId; -import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; import org.apache.jackrabbit.core.state.DefaultISMLocking; import org.apache.jackrabbit.core.state.ISMLocking.ReadLock; @@ -36,6 +34,7 @@ import org.apache.jackrabbit.core.state.LocalItemStateManager; import org.apache.jackrabbit.core.state.NodeReferences; import org.apache.jackrabbit.core.state.NodeState; +import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.spi.Name; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl; @@ -106,6 +105,18 @@ /** * {@inheritDoc} */ + public InternalBaseline getBaseline(NodeId id) throws RepositoryException { + // lock handling via getItem() + InternalBaseline v = (InternalBaseline) getItem(id); + if (v == null) { + log.warn("Versioning item not found: " + id); + } + return v; + } + + /** + * {@inheritDoc} + */ public InternalActivity getActivity(NodeId id) throws RepositoryException { // lock handling via getItem() InternalActivity v = (InternalActivity) getItem(id); @@ -445,37 +456,33 @@ } /** - * Creates aew configuration node + * Creates a new configuration node. + *

+ * The nt:confguration is stored within the nt:configurations storage using + * the nodeid of the configuration root (rootId) as path. + * * @param rootId the id of the root node of the workspace configuration - * @param baseline the optional baseline * @return a node state of the created configuration * @throws RepositoryException if an error occurs */ - NodeStateEx internalCreateConfiguration(NodeId rootId, InternalBaseline baseline) + NodeStateEx internalCreateConfiguration(NodeId rootId) throws RepositoryException { - if (baseline != null) { - // the exact behavior is not clarified yet. - // see http://jsr-283.dev.java.net/issues/show_bug.cgi?id=795 - throw new UnsupportedRepositoryOperationException( - "creating configurations based on a baseline not supported, yet"); - } - WriteOperation ops = startWriteOperation(); try { // If the parameter baseline is null, a new version history is created // to store baselines of the new configuration, and the jcr:baseVersion // of the new configuration references the root of the new version history. - NodeId configId = new NodeId(); NodeStateEx configParent = getParentNode(configurationsRoot, - configId.toString(), NameConstants.REP_CONFIGURATIONS); - Name name = getName(configId.toString()); + rootId.toString(), NameConstants.REP_CONFIGURATIONS); + Name name = getName(rootId.toString()); + + NodeId configId = new NodeId(); NodeStateEx config = configParent.addNode(name, NameConstants.NT_CONFIGURATION, configId, true); config.setPropertyValue(NameConstants.JCR_ROOT, InternalValue.create(rootId)); // now create the version history of the baseline - String uuid = new NodeId().toString(); - NodeStateEx histParent = getParentNode(historyRoot, uuid, NameConstants.REP_VERSIONSTORAGE); - Name histName = getName(uuid); + NodeStateEx histParent = getParentNode(historyRoot, configId.toString(), NameConstants.REP_VERSIONSTORAGE); + Name histName = getName(configId.toString()); NodeStateEx history = InternalVersionHistoryImpl.create(this, histParent, histName, config.getState(), null); InternalVersionHistory vh = new InternalVersionHistoryImpl(this, history); @@ -484,6 +491,9 @@ NodeId blId = vh.getRootVersion().getId(); config.setPropertyValue(NameConstants.JCR_BASEVERSION, InternalValue.create(blId)); config.setPropertyValue(NameConstants.JCR_VERSIONHISTORY, InternalValue.create(vh.getId())); + config.setPropertyValue(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(true)); + InternalValue[] preds = new InternalValue[]{InternalValue.create(blId)}; + config.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, preds, true); configParent.store(); ops.save(); @@ -496,6 +506,40 @@ } /** + * {@inheritDoc} + */ + public InternalConfiguration getConfigurationForNode(NodeId rootId) throws RepositoryException { + ReadLock lock = acquireReadLock(); + try { + String uuid = rootId.toString(); + Name name = getName(uuid); + + NodeStateEx parent = getParentNode(configurationsRoot, uuid, null); + if (parent != null && parent.hasNode(name)) { + NodeStateEx config = parent.getNode(name, 1); + return new InternalConfigurationImpl(this, config); + } else { + return null; + } + } finally { + lock.release(); + } + } + + /** + * {@inheritDoc} + */ + public InternalConfiguration getConfiguration(NodeId nodeId) + throws RepositoryException { + // lock handling via getItem() + InternalConfiguration config = (InternalConfiguration) getItem(nodeId); + if (config == null) { + throw new ItemNotFoundException(nodeId.toString()); + } + return config; + } + + /** * Removes the specified activity * * @param activity the acitvity to remove @@ -599,7 +643,8 @@ WriteOperation operation = startWriteOperation(); try { String versionName = calculateCheckinVersionName(history, node, simple); - InternalVersionImpl v = history.checkin(NameFactoryImpl.getInstance().create("", versionName), node); + InternalVersionImpl v = history.checkin( + NameFactoryImpl.getInstance().create("", versionName), node, null); // check for jcr:activity if (node.hasProperty(NameConstants.JCR_ACTIVITY)) { @@ -617,6 +662,44 @@ } /** + * internally checks in a configuration + * @param config the config + * @param baseVersions the base versions to record + * @return the new baseline + * @throws RepositoryException if an error occurs + */ + protected InternalBaseline internalCheckin(InternalConfigurationImpl config, + Set baseVersions) + throws RepositoryException { + InternalVersionHistoryImpl vh = (InternalVersionHistoryImpl) getVersionHistoryOfNode(config.getId()); + WriteOperation operation = startWriteOperation(); + try { + NodeStateEx node = config.node; + String versionName = calculateCheckinVersionName(vh, node, false); + InternalBaseline v = (InternalBaseline) vh.checkin( + NameFactoryImpl.getInstance().create("", versionName), + node, baseVersions); + // update properties on 'node' to point to the new base version + // but leave it checked out + node.setPropertyValue( + NameConstants.JCR_BASEVERSION, + InternalValue.create(v.getId())); + node.setPropertyValues( + NameConstants.JCR_PREDECESSORS, + PropertyType.REFERENCE, + new InternalValue[]{InternalValue.create(v.getId())} + ); + node.store(); + operation.save(); + return v; + } catch (ItemStateException e) { + throw new RepositoryException(e); + } finally { + operation.close(); + } + } + + /** * Calculates the name of the new version that will be created by a * checkin call. The name is determined as follows: *

    @@ -796,6 +879,8 @@ return new InternalVersionHistoryImpl(this, pNode); } else if (ntName.equals(NameConstants.NT_ACTIVITY)) { return new InternalActivityImpl(this, pNode); + } else if (ntName.equals(NameConstants.NT_CONFIGURATION)) { + return new InternalConfigurationImpl(this, pNode); } else { return null; } Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java Tue Jul 21 23:41:39 2009 @@ -16,12 +16,8 @@ */ package org.apache.jackrabbit.core.version; -import java.util.Map; - import javax.jcr.RepositoryException; -import org.apache.jackrabbit.core.id.NodeId; - /** * This interface defines the internal activity. */ @@ -39,11 +35,11 @@ /** * Returns the changeset of this activity. * This is the set of versions that are the latest members of this activity - * in their respective version histories. the changeset is a map grouped by - * the nodeid of the respective histories. + * in their respective version histories. + * * @return the changeset * @throws RepositoryException if an error occurs */ - Map getChangeSet() throws RepositoryException; + VersionSet getChangeSet() throws RepositoryException; } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java Tue Jul 21 23:41:39 2009 @@ -156,7 +156,7 @@ /** * {@inheritDoc} */ - public Map getChangeSet() throws RepositoryException { + public VersionSet getChangeSet() throws RepositoryException { Map changeset = new HashMap(); if (node.hasProperty(NameConstants.REP_VERSIONS)) { for (InternalValue ref: node.getPropertyValues(NameConstants.REP_VERSIONS)) { @@ -164,6 +164,6 @@ changeset.put(v.getVersionHistory().getId(), v); } } - return changeset; + return new VersionSet(changeset); } } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaseline.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaseline.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaseline.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaseline.java Tue Jul 21 23:41:39 2009 @@ -16,12 +16,8 @@ */ package org.apache.jackrabbit.core.version; -import java.util.Map; - import javax.jcr.RepositoryException; -import org.apache.jackrabbit.core.id.NodeId; - /** * This interface defines the internal baseline. *

    @@ -42,6 +38,14 @@ * version history. * @throws RepositoryException if an error occurs */ - Map getBaseVersions() throws RepositoryException; + VersionSet getBaseVersions() throws RepositoryException; + /** + * Returns the configuration of this baseline. this is basically the + * versionable node. + * + * @return the configuration + * @throws RepositoryException if an error occurs or the configuration does not exist. + */ + InternalConfiguration getConfiguration() throws RepositoryException; } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaselineImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaselineImpl.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaselineImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalBaselineImpl.java Tue Jul 21 23:41:39 2009 @@ -16,14 +16,10 @@ */ package org.apache.jackrabbit.core.version; -import java.util.Map; - import javax.jcr.RepositoryException; import javax.jcr.UnsupportedRepositoryOperationException; import org.apache.jackrabbit.core.id.NodeId; -import org.apache.jackrabbit.core.value.InternalValue; -import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.Name; /** @@ -48,7 +44,15 @@ /** * {@inheritDoc} */ - public Map getBaseVersions() throws RepositoryException { + public VersionSet getBaseVersions() throws RepositoryException { throw new UnsupportedRepositoryOperationException("InternalBaseline.getBaseversions()"); } + + /** + * {@inheritDoc} + */ + public InternalConfiguration getConfiguration() throws RepositoryException { + NodeId configId = getVersionHistory().getVersionableId(); + return (InternalConfiguration) vMgr.getItem(configId); + } } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java Tue Jul 21 23:41:39 2009 @@ -22,6 +22,8 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import java.util.Arrays; +import java.util.HashSet; import javax.jcr.PropertyType; import javax.jcr.ReferentialIntegrityException; @@ -226,7 +228,12 @@ if (v != null) { v.clear(); } else { - v = new InternalVersionImpl(this, child, child.getName()); + // check if baseline + if (child.getState().getMixinTypeNames().contains(NameConstants.REP_BASELINE)) { + v = new InternalBaselineImpl(this, child, child.getName()); + } else { + v = new InternalVersionImpl(this, child, child.getName()); + } } return v; } @@ -485,10 +492,11 @@ * * @param name new version name * @param src source node to version + * @param configuration the set of versions in case a configuration is checked in * @return the newly created version * @throws RepositoryException if an error occurs */ - InternalVersionImpl checkin(Name name, NodeStateEx src) + InternalVersionImpl checkin(Name name, NodeStateEx src, Set configuration) throws RepositoryException { // copy predecessors from src node @@ -527,6 +535,16 @@ InternalValue act = src.getPropertyValue(NameConstants.JCR_ACTIVITY); vNode.setPropertyValue(NameConstants.JCR_ACTIVITY, act); } + // check configuration + if (configuration != null) { + vNode.setMixins(new HashSet(Arrays.asList(NameConstants.REP_BASELINE))); + InternalValue[] values = new InternalValue[configuration.size()]; + int i=0; + for (NodeId id: configuration) { + values[i++] = InternalValue.create(id); + } + vNode.setPropertyValues(NameConstants.REP_BASEVERSIONS, PropertyType.REFERENCE, values, true); + } // initialize 'created', 'predecessors' and 'successors' vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime())); @@ -537,7 +555,9 @@ InternalFrozenNodeImpl.checkin(vNode, NameConstants.JCR_FROZENNODE, src); // update version graph - InternalVersionImpl version = new InternalVersionImpl(this, vNode, name); + InternalVersionImpl version = configuration == null + ? new InternalVersionImpl(this, vNode, name) + : new InternalBaselineImpl(this, vNode, name); version.internalAttach(); // and store @@ -583,10 +603,14 @@ if (copiedFrom != null) { pNode.setPropertyValue(NameConstants.JCR_COPIEDFROM, InternalValue.create(copiedFrom, true)); } - + // create root version NodeId versionId = new NodeId(); NodeStateEx vNode = pNode.addNode(NameConstants.JCR_ROOTVERSION, NameConstants.NT_VERSION, versionId, true); + if (nodeState.getNodeTypeName().equals(NameConstants.NT_CONFIGURATION)) { + // add baseline mixin for configurations + vNode.setMixins(new HashSet(Arrays.asList(NameConstants.REP_BASELINE))); + } // initialize 'created' and 'predecessors' vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime())); Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java Tue Jul 21 23:41:39 2009 @@ -260,10 +260,9 @@ throws RepositoryException { InternalValue[] values = new InternalValue[cessors.size()]; for (int i = 0; i < values.length; i++) { - values[i] = InternalValue.create( - ((InternalVersion) cessors.get(i)).getId()); + values[i] = InternalValue.create((cessors.get(i)).getId()); } - node.setPropertyValues(propname, PropertyType.STRING, values); + node.setPropertyValues(propname, PropertyType.REFERENCE, values); if (store) { node.store(); } Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java Tue Jul 21 23:41:39 2009 @@ -290,7 +290,11 @@ * @throws RepositoryException if an error occurs */ protected InternalVersion getVersion(Version v) throws RepositoryException { - return vMgr.getVersion(((VersionImpl) v).getNodeId()); + if (v == null) { + return null; + } else { + return vMgr.getVersion(((VersionImpl) v).getNodeId()); + } } /** Copied: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplConfig.java (from r795866, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java) URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplConfig.java?p2=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplConfig.java&p1=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java&r1=795866&r2=796586&rev=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplConfig.java Tue Jul 21 23:41:39 2009 @@ -16,35 +16,20 @@ */ package org.apache.jackrabbit.core.version; -import java.util.ArrayList; import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; import java.util.Set; -import javax.jcr.ItemExistsException; -import javax.jcr.PropertyType; +import javax.jcr.ItemNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.UnsupportedRepositoryOperationException; -import javax.jcr.version.OnParentVersionAction; import javax.jcr.version.Version; -import javax.jcr.version.VersionException; -import javax.jcr.version.VersionManager; -import org.apache.jackrabbit.core.BatchedItemOperations; import org.apache.jackrabbit.core.HierarchyManager; -import org.apache.jackrabbit.core.ItemValidator; import org.apache.jackrabbit.core.SessionImpl; import org.apache.jackrabbit.core.id.NodeId; -import org.apache.jackrabbit.core.nodetype.PropDef; -import org.apache.jackrabbit.core.security.authorization.Permission; -import org.apache.jackrabbit.core.state.ChildNodeEntry; import org.apache.jackrabbit.core.state.ItemStateException; -import org.apache.jackrabbit.core.state.PropertyState; import org.apache.jackrabbit.core.state.UpdatableItemStateManager; -import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.spi.Name; -import org.apache.jackrabbit.spi.Path; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,15 +37,13 @@ /** * The JCR Version Manager impementation is split in several classes in order to * group related methods together. - *

    - * this class provides methods for the restore operations. + *

    + * this class provides methods for the configuration and baselines related operations. + *

    + * Implementation note: methods starting with "internal" are considered to be + * executed within a "write operations" block. */ -abstract public class JcrVersionManagerImplRestore extends JcrVersionManagerImplBase { - - /** - * default logger - */ - private static final Logger log = LoggerFactory.getLogger(JcrVersionManagerImplRestore.class); +abstract public class JcrVersionManagerImplConfig extends JcrVersionManagerImplMerge { /** * Creates a new version manager for the given session @@ -68,56 +51,55 @@ * @param stateMgr the underlying state manager * @param hierMgr local hierarchy manager */ - protected JcrVersionManagerImplRestore(SessionImpl session, + protected JcrVersionManagerImplConfig(SessionImpl session, UpdatableItemStateManager stateMgr, HierarchyManager hierMgr) { super(session, stateMgr, hierMgr); } - /** - * @param state the state to restore - * @param version the version to restore - * @param removeExisting remove existing flag + /** + * Restores the versions recorded in the given baseline below the specified + * path. + * @param parent the parent state + * @param name the name of the new node (tree) + * @param baseline the baseline that recorded the versions + * @return the configuration * @throws RepositoryException if an error occurs - * - * @see javax.jcr.version.VersionManager#restore(String, Version, boolean) */ - protected void restore(NodeStateEx state, Version version, boolean removeExisting) + protected InternalConfiguration restore(NodeStateEx parent, Name name, InternalBaseline baseline) throws RepositoryException { - checkVersionable(state); - InternalVersion v = getVersion(version); - // check if 'own' version - if (!v.getVersionHistory().equals(getVersionHistory(state))) { - throw new VersionException("Unable to restore version. Not same version history."); + InternalConfiguration config = baseline.getConfiguration(); + NodeId rootId = config.getRootId(); + if (stateMgr.hasItemState(rootId)) { + NodeStateEx existing = parent.getNode(rootId); + throw new UnsupportedRepositoryOperationException( + "Configuration for the given baseline already exists at: " + safeGetJCRPath(existing)); } - WriteOperation ops = startWriteOperation(); - try { - internalRestore(state, v, new DateVersionSelector(version.getCreated()), removeExisting); - ops.save(); - } catch (ItemStateException e) { - throw new RepositoryException(e); - } finally { - ops.close(); + + // find version for configuration root + VersionSet versions = baseline.getBaseVersions(); + InternalVersion rootVersion = null; + for (InternalVersion v: versions.versions().values()) { + if (v.getVersionHistory().getVersionableId().equals(rootId)) { + rootVersion = v; + break; + } + } + if (rootVersion == null) { + throw new RepositoryException("Internal error: supplied baseline has no version for its configuration root."); } - } - /** - * @param state the state to restore - * @param versionName the name of the version to restore - * @param removeExisting remove existing flag - * @throws RepositoryException if an error occurs - * - * @see VersionManager#restore(String, String, boolean) - */ - protected void restore(NodeStateEx state, Name versionName, boolean removeExisting) - throws RepositoryException { - checkVersionable(state); - InternalVersion v = getVersionHistory(state).getVersion(versionName); - DateVersionSelector gvs = new DateVersionSelector(v.getCreated()); + // create new node below parent WriteOperation ops = startWriteOperation(); try { - internalRestore(state, v, gvs, removeExisting); + InternalFrozenNode fn = rootVersion.getFrozenNode(); + NodeStateEx state = parent.addNode(name, fn.getFrozenPrimaryType(), fn.getFrozenId()); + state.setMixins(fn.getFrozenMixinTypes()); + parent.store(); + // now just restore all versions + internalRestore(versions, true); ops.save(); + return config; } catch (ItemStateException e) { throw new RepositoryException(e); } finally { @@ -126,427 +108,87 @@ } /** - * @param state the state to restore - * @param versionLabel the name of the version to restore - * @param removeExisting remove existing flag + * Performs a configuration checkin + * @param config the config + * @return the id of the new base version * @throws RepositoryException if an error occurs - * - * @see VersionManager#restoreByLabel(String, String, boolean) */ - protected void restoreByLabel(NodeStateEx state, Name versionLabel, boolean removeExisting) - throws RepositoryException { - checkVersionable(state); - InternalVersion v = getVersionHistory(state).getVersionByLabel(versionLabel); - if (v == null) { - throw new VersionException("No version for label " + versionLabel + " found."); - } - WriteOperation ops = startWriteOperation(); - try { - internalRestore(state, v, new LabelVersionSelector(versionLabel), removeExisting); - ops.save(); - } catch (ItemStateException e) { - throw new RepositoryException(e); - } finally { - ops.close(); - } + protected NodeId checkin(InternalConfiguration config) throws RepositoryException { + NodeStateEx root = getRootNode(config); + Set baseVersions = new HashSet(); + baseVersions.add(root.getPropertyValue(NameConstants.JCR_BASEVERSION).getNodeId()); + collectBaseVersions(root, baseVersions); + return vMgr.checkin(session, config, baseVersions).getId(); } /** - * Restores the version below the parent node - * using the indicated name - * - * @param parent parent node - * @param name desired name - * @param version version to restore - * @param removeExisting remove exiting flag + * Recursivly collects all base versions of this configuration tree. + * @param root node to traverse + * @param baseVersions set of base versions to fill * @throws RepositoryException if an error occurs */ - protected void restore(NodeStateEx parent, Name name, Version version, boolean removeExisting) + private void collectBaseVersions(NodeStateEx root, Set baseVersions) throws RepositoryException { - // check if versionable node exists - InternalFrozenNode fn = ((VersionImpl) version).getInternalFrozenNode(); - if (stateMgr.hasItemState(fn.getFrozenId())) { - if (removeExisting) { - NodeStateEx existing = parent.getNode(fn.getFrozenId()); - checkVersionable(existing); - InternalVersion v = getVersion(version); - - // move versionable node below this one using the given "name" - WriteOperation ops = startWriteOperation(); - try { - NodeStateEx exParent = existing.getParent(); - NodeStateEx state = parent.moveFrom(existing, name, false); - exParent.store(); - parent.store(); - // and restore it - internalRestore(state, v, new DateVersionSelector(v.getCreated()), removeExisting); - ops.save(); - } catch (ItemStateException e) { - throw new RepositoryException(e); - } finally { - ops.close(); + for (NodeStateEx child: root.getChildNodes()) { + if (child.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) { + if (child.hasProperty(NameConstants.JCR_CONFIGURATION)) { + // don't traverse into child nodes that have a jcr:configuration + // property as they belong to a different configuration. + continue; } - } else { - throw new ItemExistsException("Unable to restore version. Versionable node already exists."); + baseVersions.add(child.getPropertyValue(NameConstants.JCR_BASEVERSION).getNodeId()); } - } else { - // create new node below parent - NodeStateEx state = parent.addNode(name, fn.getFrozenPrimaryType(), fn.getFrozenId()); - state.setMixins(fn.getFrozenMixinTypes()); - restore(state, version, removeExisting); + collectBaseVersions(child, baseVersions); } } /** - * @param versions Versions to restore + * Performs a configuration restore + * @param config config to restore + * @param name name of the baseline version * @param removeExisting remove existing flag * @throws RepositoryException if an error occurs - * - * @see VersionManager#restore(Version[], boolean) - * @see VersionManager#restore(Version, boolean) */ - protected void restore(final Map versions, - boolean removeExisting) + protected void restore(InternalConfiguration config, Name name, boolean removeExisting) throws RepositoryException { - - // create a version selector to the set of versions - VersionSelector vsel = new VersionSelector() { - public InternalVersion select(InternalVersionHistory versionHistory) throws RepositoryException { - // try to select version as specified - InternalVersion v = versions.get(versionHistory.getId()); - if (v == null) { - // select latest one - v = DateVersionSelector.selectByDate(versionHistory, null); - } - return v; - } - }; - - WriteOperation ops = startWriteOperation(); - try { - // now restore all versions that have a node in the workspace - int numRestored = 0; - while (versions.size() > 0) { - Set restored = null; - for (InternalVersion v : versions.values()) { - NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId()); - if (state != null) { - // todo: check should operate on workspace states, too - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - checkModify(state, options, Permission.NONE); - restored = internalRestore(state, v, vsel, removeExisting); - // remove restored versions from set - for (InternalVersion r : restored) { - versions.remove(r.getVersionHistory().getId()); - } - numRestored += restored.size(); - break; - } - } - if (restored == null) { - if (numRestored == 0) { - throw new VersionException("Unable to restore. At least one version needs" - + " existing versionable node in workspace."); - } else { - throw new VersionException("Unable to restore. All versions with non" - + " existing versionable nodes need parent."); - } - } - } - ops.save(); - } catch (ItemStateException e) { - log.error("Error while reverting changes applied during restore.", e); - throw new RepositoryException(e); - } finally { - ops.close(); - } + throw new UnsupportedRepositoryOperationException("not implemented, yet"); } - + /** - * Internal method to restore a version. - * - * @param state the state to restore - * @param version version to restore - * @param vsel the version selector that will select the correct version for - * OPV=Version child nodes. + * Performs a configuration restore + * @param config config to restore + * @param name label of the baseline version * @param removeExisting remove existing flag - * @return set of restored versions * @throws RepositoryException if an error occurs - * @throws ItemStateException if an error occurs */ - protected Set internalRestore(NodeStateEx state, - InternalVersion version, - VersionSelector vsel, - boolean removeExisting) - throws RepositoryException, ItemStateException { - - // fail if root version - if (version.isRootVersion()) { - throw new VersionException("Restore of root version not allowed."); - } - - boolean isFull = checkVersionable(state); - - // check permission - Path path = hierMgr.getPath(state.getNodeId()); - session.getAccessManager().checkPermission(path, Permission.VERSION_MNGMT); - - // 1. The child node and properties of N will be changed, removed or - // added to, depending on their corresponding copies in V and their - // own OnParentVersion attributes (see 7.2.8, below, for details). - Set restored = new HashSet(); - restoreFrozenState(state, version.getFrozenNode(), vsel, restored, removeExisting); - restored.add(version); - - if (isFull) { - // 2. N's jcr:baseVersion property will be changed to point to V. - state.setPropertyValue( - NameConstants.JCR_BASEVERSION, InternalValue.create(version.getId())); - - // 4. N's jcr:predecessor property is set to null - state.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY); - - // also clear mergeFailed - state.removeProperty(NameConstants.JCR_MERGEFAILED); - - } else { - // with simple versioning, the node is checked in automatically, - // thus not allowing any branches - vMgr.checkin(session, state); - } - // 3. N's jcr:isCheckedOut property is set to false. - state.setPropertyValue(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false)); - state.store(); - return restored; + protected void restoreByLabel(InternalConfiguration config, Name name, boolean removeExisting) + throws RepositoryException { + throw new UnsupportedRepositoryOperationException("not implemented, yet"); } /** - * Restores the properties and child nodes from the frozen state. - * - * @param state state to restore - * @param freeze the frozen node - * @param vsel version selector - * @param restored set of restored versions + * Performs a configuration restore + * @param config config to restore + * @param version baseline version to restore * @param removeExisting remove existing flag * @throws RepositoryException if an error occurs - * @throws ItemStateException if an error occurs */ - protected void restoreFrozenState(NodeStateEx state, InternalFrozenNode freeze, VersionSelector vsel, - Set restored, boolean removeExisting) - throws RepositoryException, ItemStateException { - - // check uuid - if (state.getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE)) { - if (!state.getNodeId().equals(freeze.getFrozenId())) { - throw new ItemExistsException("Unable to restore version of " + safeGetJCRPath(state) + ". UUID changed."); - } - } - - // check primary type - if (!freeze.getFrozenPrimaryType().equals(state.getState().getNodeTypeName())) { - // todo: implement - throw new UnsupportedRepositoryOperationException("Unable to restore version of " + safeGetJCRPath(state) + ". PrimaryType change not supported yet."); - } - - // adjust mixins - state.setMixins(freeze.getFrozenMixinTypes()); - - // copy frozen properties - PropertyState[] props = freeze.getFrozenProperties(); - HashSet propNames = new HashSet(); - for (PropertyState prop : props) { - // skip properties that should not to be reverted back - if (prop.getName().equals(NameConstants.JCR_ACTIVITY)) { - continue; - } - propNames.add(prop.getName()); - state.copyFrom(prop); - } - // remove properties that do not exist in the frozen representation - for (PropertyState prop: state.getProperties()) { - // ignore some props that are not well guarded by the OPV - Name propName = prop.getName(); - if (propName.equals(NameConstants.JCR_VERSIONHISTORY)) { - // ignore - } else if (propName.equals(NameConstants.JCR_PREDECESSORS)) { - // ignore - } else if (!propNames.contains(propName)) { - int opv = state.getDefinition(prop).getOnParentVersion(); - if (opv == OnParentVersionAction.COPY || opv == OnParentVersionAction.VERSION) { - state.removeProperty(propName); - } - } - } - - // add 'auto-create' properties that do not exist yet - for (PropDef def: state.getEffectiveNodeType().getAutoCreatePropDefs()) { - if (!state.hasProperty(def.getName())) { - // compute system generated values if necessary - // todo: use NodeTypeInstanceHandler - InternalValue[] values = - BatchedItemOperations.computeSystemGeneratedPropertyValues(state.getState(), def); - if (values == null) { - values = def.getDefaultValues(); - } - if (values != null) { - state.setPropertyValues(def.getName(), def.getRequiredType(), values, def.isMultiple()); - } - } - } - - // first delete some of the child nodes. this is a bit tricky, in case - // the child node index changed. mark an sweep - LinkedList toDelete = new LinkedList(); - for (ChildNodeEntry entry: state.getState().getChildNodeEntries()) { - NodeStateEx child = state.getNode(entry.getName(), entry.getIndex()); - int opv = child.getDefinition().getOnParentVersion(); - if (opv == OnParentVersionAction.COPY) { - // only remove OPV=Copy nodes - toDelete.addFirst(entry); - } else if (opv == OnParentVersionAction.VERSION) { - // only remove, if node to be restored does not contain child, - // or if restored child is not versionable - NodeId vhId = child.hasProperty(NameConstants.JCR_VERSIONHISTORY) - ? child.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId() - : null; - if (vhId == null || !freeze.hasFrozenHistory(vhId)) { - toDelete.addFirst(entry); - } - } - } - for (ChildNodeEntry entry: toDelete) { - state.removeNode(entry.getName(), entry.getIndex()); - } - // need to sync with state manager - state.store(); - - // restore the frozen nodes - InternalFreeze[] frozenNodes = freeze.getFrozenChildNodes(); - for (InternalFreeze child : frozenNodes) { - NodeStateEx restoredChild = null; - if (child instanceof InternalFrozenNode) { - InternalFrozenNode f = (InternalFrozenNode) child; - // check for existing - if (f.getFrozenId() != null) { - if (stateMgr.hasItemState(f.getFrozenId())) { - NodeStateEx existing = state.getNode(f.getFrozenId()); - if (removeExisting) { - NodeStateEx parent = existing.getParent(); - parent.removeNode(existing); - parent.store(); - } else if (existing.getState().isShareable()) { - // if existing node is shareable, then clone it - restoredChild = state.moveFrom(existing, existing.getName(), true); - } else { - // since we delete the OPV=Copy children beforehand, all - // found nodes must be outside of this tree - throw new ItemExistsException( - "Unable to restore node, item already" - + " exists outside of restored tree: " - + existing); - } - - } - } - if (restoredChild == null) { - restoredChild = state.addNode(f.getName(), f.getFrozenPrimaryType(), f.getFrozenId()); - restoredChild.setMixins(f.getFrozenMixinTypes()); - restoreFrozenState(restoredChild, f, vsel, restored, removeExisting); - } - - } else if (child instanceof InternalFrozenVersionHistory) { - InternalFrozenVersionHistory fh = (InternalFrozenVersionHistory) child; - InternalVersionHistory vh = vMgr.getVersionHistory(fh.getVersionHistoryId()); - Name oldVersion = null; - - // check if representing versionable already exists somewhere - NodeId nodeId = vh.getVersionableId(); - if (stateMgr.hasItemState(nodeId)) { - NodeStateEx existing = state.getNode(nodeId); - if (existing.getParentId() == state.getNodeId()) { - // remove - state.removeNode(existing); - } else if (removeExisting) { - NodeStateEx parent = existing.getNode(existing.getNodeId()); - state.moveFrom(existing, fh.getName(), false); - parent.store(); - - // get old version name - oldVersion = getBaseVersion(existing).getName(); - } else { - // since we delete the OPV=Copy children beforehand, all - // found nodes must be outside of this tree - throw new ItemExistsException( - "Unable to restore node, item already exists" - + " outside of restored tree: " + existing); - } - } - // get desired version from version selector - InternalVersion v = vsel.select(vh); + protected void restore(InternalConfiguration config, Version version, boolean removeExisting) + throws RepositoryException { + throw new UnsupportedRepositoryOperationException("not implemented, yet"); + } - // check existing version of item exists - if (!stateMgr.hasItemState(nodeId)) { - if (v == null) { - // if version selector was unable to select version, - // choose the initial one - InternalVersion[] vs = vh.getRootVersion().getSuccessors(); - if (vs.length == 0) { - String msg = "Unable to select appropariate version for " - + child.getName() + " using " + vsel; - log.error(msg); - throw new VersionException(msg); - } - v = vs[0]; - } - InternalFrozenNode f = v.getFrozenNode(); - restoredChild = state.addNode(fh.getName(), f.getFrozenPrimaryType(), f.getFrozenId()); - restoredChild.setMixins(f.getFrozenMixinTypes()); - } else { - restoredChild = state.getNode(nodeId); - if (v == null || oldVersion == null || v.getName().equals(oldVersion)) { - v = null; - } - } - if (v != null) { - try { - internalRestore(restoredChild, v, vsel, removeExisting); - } catch (RepositoryException e) { - log.error("Error while restoring node: " + e); - log.error(" child path: " + restoredChild); - log.error(" selected version: " + v.getName()); - StringBuffer avail = new StringBuffer(); - for (Name name: vh.getVersionNames()) { - avail.append(name); - avail.append(", "); - } - log.error(" available versions: " + avail); - log.error(" versionselector: " + vsel); - throw e; - } - // add this version to set - restored.add(v); - } - } - // ensure proper ordering (issue JCR-469) - if (restoredChild != null && state.getEffectiveNodeType().hasOrderableChildNodes()) { - // order at end - ArrayList list = new ArrayList(state.getState().getChildNodeEntries()); - ChildNodeEntry toReorder = null; - boolean isLast = true; - for (ChildNodeEntry e: list) { - if (e.getId().equals(restoredChild.getNodeId())) { - toReorder = e; - } else if (toReorder != null) { - isLast = false; - } - } - if (toReorder != null && !isLast) { - list.remove(toReorder); - list.add(toReorder); - state.getState().setChildNodeEntries(list); - } - } + /** + * Returns the configuration root node for the given config. + * @param config the config + * @return the root node + * @throws RepositoryException if an error occurs or the root node does not exist + */ + private NodeStateEx getRootNode(InternalConfiguration config) throws RepositoryException { + NodeStateEx root = getNodeStateEx(config.getRootId()); + if (root == null) { + throw new ItemNotFoundException("Configuration root node for " + config.getId() + " not found."); } + return root; } - } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java Tue Jul 21 23:41:39 2009 @@ -20,7 +20,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; import javax.jcr.AccessDeniedException; @@ -454,13 +453,12 @@ protected void merge(InternalActivity activity, List failedIds) throws RepositoryException { - Map changeSet = activity.getChangeSet(); - ChangeSetVersionSelector vsel = new ChangeSetVersionSelector(changeSet); + VersionSet changeSet = activity.getChangeSet(); WriteOperation ops = startWriteOperation(); try { - Iterator iter = changeSet.keySet().iterator(); + Iterator iter = changeSet.versions().keySet().iterator(); while (iter.hasNext()) { - InternalVersion v = changeSet.remove(iter.next()); + InternalVersion v = changeSet.versions().remove(iter.next()); NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId()); if (state != null) { InternalVersion base = getBaseVersion(state); @@ -474,14 +472,14 @@ setMergeFailed(state, set); state.store(); } else { - for (InternalVersion restored: internalRestore(state, v, vsel, true)) { - changeSet.remove(restored.getVersionHistory().getId()); + for (InternalVersion restored: internalRestore(state, v, changeSet, true)) { + changeSet.versions().remove(restored.getVersionHistory().getId()); } } } // reset iterator - iter = changeSet.keySet().iterator(); + iter = changeSet.versions().keySet().iterator(); } ops.save(); } catch (ItemStateException e) { @@ -491,32 +489,4 @@ } } - /** - * Internal version selector that selects the version in the changeset. - */ - private static class ChangeSetVersionSelector implements VersionSelector { - - /** - * the change set. - */ - private final Map changeSet; - - /** - * creates a changeset version selector - * @param changeSet the changeset map from history id -> version - */ - private ChangeSetVersionSelector(Map changeSet) { - this.changeSet = changeSet; - } - - /** - * {@inheritDoc} - * - * Selects the version in the changeset - */ - public InternalVersion select(InternalVersionHistory vh) throws RepositoryException { - return changeSet.get(vh.getId()); - } - } - } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java Tue Jul 21 23:41:39 2009 @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; -import java.util.Map; import java.util.Set; import javax.jcr.ItemExistsException; @@ -52,8 +51,11 @@ /** * The JCR Version Manager impementation is split in several classes in order to * group related methods together. - *

    + *

    * this class provides methods for the restore operations. + *

    + * Implementation note: methods starting with "internal" are considered to be + * executed within a "write operations" block. */ abstract public class JcrVersionManagerImplRestore extends JcrVersionManagerImplBase { @@ -74,7 +76,7 @@ super(session, stateMgr, hierMgr); } - /** + /** * @param state the state to restore * @param version the version to restore * @param removeExisting remove existing flag @@ -201,64 +203,41 @@ * @param versions Versions to restore * @param removeExisting remove existing flag * @throws RepositoryException if an error occurs + * @throws ItemStateException if an error occurs * * @see VersionManager#restore(Version[], boolean) * @see VersionManager#restore(Version, boolean) */ - protected void restore(final Map versions, - boolean removeExisting) - throws RepositoryException { - - // create a version selector to the set of versions - VersionSelector vsel = new VersionSelector() { - public InternalVersion select(InternalVersionHistory versionHistory) throws RepositoryException { - // try to select version as specified - InternalVersion v = versions.get(versionHistory.getId()); - if (v == null) { - // select latest one - v = DateVersionSelector.selectByDate(versionHistory, null); - } - return v; - } - }; - - WriteOperation ops = startWriteOperation(); - try { - // now restore all versions that have a node in the workspace - int numRestored = 0; - while (versions.size() > 0) { - Set restored = null; - for (InternalVersion v : versions.values()) { - NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId()); - if (state != null) { - // todo: check should operate on workspace states, too - int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; - checkModify(state, options, Permission.NONE); - restored = internalRestore(state, v, vsel, removeExisting); - // remove restored versions from set - for (InternalVersion r : restored) { - versions.remove(r.getVersionHistory().getId()); - } - numRestored += restored.size(); - break; + protected void internalRestore(VersionSet versions, boolean removeExisting) + throws RepositoryException, ItemStateException { + // now restore all versions that have a node in the workspace + int numRestored = 0; + while (versions.versions().size() > 0) { + Set restored = null; + for (InternalVersion v : versions.versions().values()) { + NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId()); + if (state != null) { + // todo: check should operate on workspace states, too + int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD; + checkModify(state, options, Permission.NONE); + restored = internalRestore(state, v, versions, removeExisting); + // remove restored versions from set + for (InternalVersion r : restored) { + versions.versions().remove(r.getVersionHistory().getId()); } + numRestored += restored.size(); + break; } - if (restored == null) { - if (numRestored == 0) { - throw new VersionException("Unable to restore. At least one version needs" - + " existing versionable node in workspace."); - } else { - throw new VersionException("Unable to restore. All versions with non" - + " existing versionable nodes need parent."); - } + } + if (restored == null) { + if (numRestored == 0) { + throw new VersionException("Unable to restore. At least one version needs" + + " existing versionable node in workspace."); + } else { + throw new VersionException("Unable to restore. All versions with non" + + " existing versionable nodes need parent."); } } - ops.save(); - } catch (ItemStateException e) { - log.error("Error while reverting changes applied during restore.", e); - throw new RepositoryException(e); - } finally { - ops.close(); } } @@ -295,7 +274,7 @@ // added to, depending on their corresponding copies in V and their // own OnParentVersion attributes (see 7.2.8, below, for details). Set restored = new HashSet(); - restoreFrozenState(state, version.getFrozenNode(), vsel, restored, removeExisting); + internalRestoreFrozen(state, version.getFrozenNode(), vsel, restored, removeExisting); restored.add(version); if (isFull) { @@ -331,7 +310,7 @@ * @throws RepositoryException if an error occurs * @throws ItemStateException if an error occurs */ - protected void restoreFrozenState(NodeStateEx state, InternalFrozenNode freeze, VersionSelector vsel, + protected void internalRestoreFrozen(NodeStateEx state, InternalFrozenNode freeze, VersionSelector vsel, Set restored, boolean removeExisting) throws RepositoryException, ItemStateException { @@ -451,7 +430,7 @@ if (restoredChild == null) { restoredChild = state.addNode(f.getName(), f.getFrozenPrimaryType(), f.getFrozenId()); restoredChild.setMixins(f.getFrozenMixinTypes()); - restoreFrozenState(restoredChild, f, vsel, restored, removeExisting); + internalRestoreFrozen(restoredChild, f, vsel, restored, removeExisting); } } else if (child instanceof InternalFrozenVersionHistory) { @@ -548,5 +527,4 @@ } } } - } \ No newline at end of file Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java Tue Jul 21 23:41:39 2009 @@ -18,6 +18,7 @@ import java.util.List; import java.util.Set; +import java.util.Arrays; import javax.jcr.ItemExistsException; import javax.jcr.PropertyType; Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java?rev=796586&r1=796585&r2=796586&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java Tue Jul 21 23:41:39 2009 @@ -16,6 +16,8 @@ */ package org.apache.jackrabbit.core.version; +import java.util.Set; + import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -132,12 +134,62 @@ * Returns the version with the given id * * @param id id of the version to retrieve - * @return the version. + * @return the version or null * @throws RepositoryException if an error occurs */ InternalVersion getVersion(NodeId id) throws RepositoryException; /** + * Returns the baseline with the given id + * + * @param id id of the baseline version to retrieve + * @return the baseline or null if not found + * @throws RepositoryException if an error occurs + */ + InternalBaseline getBaseline(NodeId id) throws RepositoryException; + + /** + * Creates a new internal configuration that represents a configuration + * of the tree rooted at the node specified by rootId + * + * @param session the session that creates the configuration + * @param rootId root id of the configuration + * @return the node id of the new internal configuration + * @throws RepositoryException if an error occurs + */ + NodeId createConfiguration(Session session, NodeId rootId) + throws RepositoryException; + + /** + * Returns the configuration for the workspace node with the given id. + * @param rootId the node id for the configuration root node. + * @return the configuration or null if it does not exist. + * @throws RepositoryException if an error occurs + */ + InternalConfiguration getConfigurationForNode(NodeId rootId) throws RepositoryException; + + /** + * Returns the configuration for the given id. + * @param nodeId the node id + * @return the configuration + * @throws RepositoryException if not exist or an error occurs + */ + InternalConfiguration getConfiguration(NodeId nodeId) throws RepositoryException; + + /** + * Performs a checkin of the configuration. + * + * @param session session that performs the checkin + * @param config internal configuration + * @param baseVersions set of base versions to record in the baseline + * @return the new baseline + * @throws RepositoryException if an error occurs + */ + InternalBaseline checkin(Session session, InternalConfiguration config, + Set baseVersions) + throws RepositoryException; + + /** * Returns the activity with the given id * * @param id id of the activity to retrieve @@ -158,20 +210,6 @@ InternalVersion getHeadVersionOfNode(NodeId id) throws RepositoryException; /** - * Creates a new internal configuration that represents a configuration - * of the tree rooted at the node specified by rootId - * - * @param session the session that creates the configuration - * @param rootId root id of the configuration - * @param baseline the baseline or null - * @return a new internal configuration - * @throws RepositoryException if an error occurs - */ - InternalConfiguration createConfiguration(Session session, NodeId rootId, - InternalBaseline baseline) - throws RepositoryException; - - /** * Creates a new activity * @param session the current session * @param title title of the new activity @@ -196,4 +234,5 @@ * @throws Exception if an error occurs */ void close() throws Exception; + }