jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
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 GMT
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<NodeId, InternalVersion> toRestore = new HashMap<NodeId, InternalVersion>();
+        Map<NodeId, InternalVersion> toRestore = new HashMap<NodeId, InternalVersion>();
         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<ItemId> failedIds = new LinkedList<ItemId>();
         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 <code>true</code> 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.
+     * <p/>
+     * 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<NodeId> 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:
      * <ul>
@@ -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<NodeId, InternalVersion> 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<NodeId, InternalVersion> getChangeSet() throws RepositoryException {
+    public VersionSet getChangeSet() throws RepositoryException {
         Map<NodeId, InternalVersion> changeset = new HashMap<NodeId, InternalVersion>();
         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.
  * <p/>
@@ -42,6 +38,14 @@
      * version history.
      * @throws RepositoryException if an error occurs
      */
-    Map<NodeId, InternalVersion> 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<NodeId, InternalVersion> 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<NodeId> 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<Name>(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<Name>(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.
- * </p>
- * this class provides methods for the restore operations.
+ * <p/>
+ * this class provides methods for the configuration and baselines related operations.
+ * <p/>
+ * 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<NodeId> baseVersions = new HashSet<NodeId>();
+        baseVersions.add(root.getPropertyValue(NameConstants.JCR_BASEVERSION).getNodeId());
+        collectBaseVersions(root, baseVersions);
+        return vMgr.checkin(session, config, baseVersions).getId();
     }
 
     /**
-     * Restores the <code>version</code> below the <code>parent</code> node
-     * using the indicated <code>name</code>
-     *
-     * @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<NodeId> 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<NodeId, InternalVersion> 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<InternalVersion> 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<InternalVersion> 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<InternalVersion> restored = new HashSet<InternalVersion>();
-        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<InternalVersion> 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<Name> propNames = new HashSet<Name>();
-        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<ChildNodeEntry> toDelete = new LinkedList<ChildNodeEntry>();
-        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<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(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<ItemId> failedIds)
             throws RepositoryException {
 
-        Map<NodeId, InternalVersion> changeSet = activity.getChangeSet();
-        ChangeSetVersionSelector vsel = new ChangeSetVersionSelector(changeSet);
+        VersionSet changeSet = activity.getChangeSet();
         WriteOperation ops = startWriteOperation();
         try {
-            Iterator<NodeId> iter = changeSet.keySet().iterator();
+            Iterator<NodeId> 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<NodeId, InternalVersion> changeSet;
-
-        /**
-         * creates a changeset version selector
-         * @param changeSet the changeset map from history id -> version
-         */
-        private ChangeSetVersionSelector(Map<NodeId, InternalVersion> 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.
- * </p>
+ * <p/>
  * this class provides methods for the restore operations.
+ * <p/>
+ * 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<NodeId, InternalVersion> 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<InternalVersion> 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<InternalVersion> 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<InternalVersion> restored = new HashSet<InternalVersion>();
-        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<InternalVersion> 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 <code>null</code>
      * @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 <code>null</code> 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 <code>rootId</code>
+     *
+     * @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 <code>null</code> 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<NodeId> 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 <code>rootId</code>
-     * 
-     * @param session the session that creates the configuration
-     * @param rootId root id of the configuration
-     * @param baseline the baseline or <code>null</code>
-     * @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;
+
 }



Mime
View raw message