jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r795452 [1/3] - in /jackrabbit/sandbox/tripod-JCR-2209: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/
Date Sun, 19 Jul 2009 00:09:41 GMT
Author: tripod
Date: Sun Jul 19 00:09:40 2009
New Revision: 795452

URL: http://svn.apache.org/viewvc?rev=795452&view=rev
Log:
JCR-2209  Versioning operations should be done on the workspace (work in progress)

Added:
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplBase.java
      - copied, changed from r795442, jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplMerge.java   (with props)
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImplRestore.java   (with props)
Modified:
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/DateVersionSelector.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/LabelVersionSelector.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionSelector.java
    jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
    jackrabbit/sandbox/tripod-JCR-2209/pom.xml

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java Sun Jul 19 00:09:40 2009
@@ -1508,7 +1508,7 @@
      * @param def
      * @return the computed values
      */
-    private InternalValue[] computeSystemGeneratedPropertyValues(NodeState parent,
+    public static InternalValue[] computeSystemGeneratedPropertyValues(NodeState parent,
                                                                  PropDef def) {
         InternalValue[] genValues = null;
 

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Sun Jul 19 00:09:40 2009
@@ -102,6 +102,7 @@
 import org.apache.jackrabbit.core.version.LabelVersionSelector;
 import org.apache.jackrabbit.core.version.VersionImpl;
 import org.apache.jackrabbit.core.version.VersionSelector;
+import org.apache.jackrabbit.core.version.JcrVersionManagerImpl;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
@@ -3321,169 +3322,65 @@
     }
 
     //------------------------------< versioning support: public Node methods >
+
     /**
      * {@inheritDoc}
      */
+    public void update(String srcWorkspaceName)
+            throws NoSuchWorkspaceException, AccessDeniedException,
+            LockException, InvalidItemStateException, RepositoryException {
+        ((JcrVersionManagerImpl) session.getWorkspace().getVersionManager()).update(this, srcWorkspaceName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Deprecated
     public Version checkin()
             throws VersionException, UnsupportedRepositoryOperationException,
             InvalidItemStateException, LockException, RepositoryException {
-        // check state of this instance
-        sanityCheck();
-
-        // check if versionable
-        boolean isFull = checkVersionable();
-
-        // check if checked out
-        if (!internalIsCheckedOut()) {
-            String msg = this + ": Node is already checked-in. ignoring.";
-            log.debug(msg);
-            return getBaseVersion();
-        }
-
-        // check lock status, holds and permissions
-        int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE;
-        session.getValidator().checkModify(this, options, Permission.VERSION_MNGMT);
-
-        Version v = session.getVersionManager().checkin(this);
-        boolean success = false;
-        try {
-            internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
-            if (isFull) {
-                internalSetProperty(
-                        NameConstants.JCR_BASEVERSION,
-                        InternalValue.create(new NodeId(v.getUUID())));
-                internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
-                if (hasProperty(NameConstants.JCR_ACTIVITY)) {
-                    removeChildProperty(NameConstants.JCR_ACTIVITY);
-                }
-            }
-            save();
-            success = true;
-        } finally {
-            if (!success) {
-                try {
-                    // TODO: need to revert changes made within the version manager as well.
-                    refresh(false);
-                } catch (RepositoryException e) {
-                    // cleanup failed
-                    log.error("Error while cleaning up after failed Node.checkin", e);
-                }
-            }
-        }
-        return v;
+        return session.getWorkspace().getVersionManager().checkin(getPath());
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void checkout()
             throws UnsupportedRepositoryOperationException, LockException,
             RepositoryException {
-        // check state of this instance
-        sanityCheck();
-
-        // check if versionable
-        boolean isFull = checkVersionable();
-
-        // check checked-out status
-        if (internalIsCheckedOut()) {
-            String msg = this + ": Node is already checked-out. ignoring.";
-            log.debug(msg);
-            return;
-        }
-
-        int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.VERSION_MNGMT);
-
-        boolean hasPendingChanges = hasPendingChanges();
-        Property[] props = new Property[3];
-        boolean success = false;
-        try {
-            props[0] = internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(true));
-            if (isFull) {
-                NodeImpl activity = (NodeImpl) session.getWorkspace().getVersionManager().getActivity();
-                Version baseVersion = session.getVersionManager().checkout(this);
-                props[1] = internalSetProperty(NameConstants.JCR_PREDECESSORS,
-                        new InternalValue[]{
-                                InternalValue.create(new NodeId(baseVersion.getUUID()))
-                        });
-                if (activity != null) {
-                    props[2] = internalSetProperty(NameConstants.JCR_ACTIVITY,
-                            InternalValue.create(activity.getNodeId()));
-                }
-            }
-            if (hasPendingChanges) {
-                for (Property prop : props) {
-                    if (prop != null) {
-                        prop.save();
-                    }
-                }
-            } else {
-                save();
-            }
-            success = true;
-        } finally {
-            if (!success) {
-                for (Property prop : props) {
-                    if (prop != null) {
-                        try {
-                            prop.refresh(false);
-                        } catch (RepositoryException e) {
-                            log.error("Error while cleaning up after failed Node.checkout", e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void update(String srcWorkspaceName)
-            throws NoSuchWorkspaceException, AccessDeniedException,
-            LockException, InvalidItemStateException, RepositoryException {
-        internalMerge(srcWorkspaceName, null, false, false);
+        session.getWorkspace().getVersionManager().checkout(getPath());
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public NodeIterator merge(String srcWorkspace, boolean bestEffort)
             throws NoSuchWorkspaceException, AccessDeniedException,
             VersionException, LockException, InvalidItemStateException,
             RepositoryException {
-        return merge(srcWorkspace, bestEffort, false);
-    }
-
-    /**
-     * @see VersionManager#merge(String, String, boolean, boolean)
-     */
-    public NodeIterator merge(String srcWorkspace, boolean bestEffort, boolean isShallow)
-            throws NoSuchWorkspaceException, AccessDeniedException,
-            VersionException, LockException, InvalidItemStateException,
-            RepositoryException {
-        List<ItemId> failedIds = new ArrayList<ItemId>();
-        internalMerge(srcWorkspace, failedIds, bestEffort, isShallow);
-        return new LazyItemIterator(itemMgr, failedIds);
+        return session.getWorkspace().getVersionManager().merge(getPath(), srcWorkspace, bestEffort);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void cancelMerge(Version version)
             throws VersionException, InvalidItemStateException,
             UnsupportedRepositoryOperationException, RepositoryException {
-        internalFinishMerge(version, true);
+        session.getWorkspace().getVersionManager().cancelMerge(getPath(), version);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void doneMerge(Version version) throws VersionException,
             InvalidItemStateException, UnsupportedRepositoryOperationException,
             RepositoryException {
-        internalFinishMerge(version, false);
+        session.getWorkspace().getVersionManager().doneMerge(getPath(), version);
     }
 
     /**
@@ -3492,13 +3389,13 @@
     public boolean isCheckedOut() throws RepositoryException {
         // check state of this instance
         sanityCheck();
-
         return internalIsCheckedOut();
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void restore(String versionName, boolean removeExisting)
             throws VersionException, ItemExistsException,
             UnsupportedRepositoryOperationException, LockException,
@@ -3506,18 +3403,13 @@
 
         // checks
         sanityCheck();
-        int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.NONE);
-
-        Version v = getVersionHistory().getVersion(versionName);
-        DateVersionSelector gvs = new DateVersionSelector(v.getCreated());
-        internalRestore(v, gvs, removeExisting);
-        // session.save/revert is done in internal restore
+        session.getWorkspace().getVersionManager().restore(getPath(), versionName, removeExisting);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void restore(Version version, boolean removeExisting)
             throws VersionException, ItemExistsException,
             UnsupportedRepositoryOperationException, LockException,
@@ -3525,22 +3417,13 @@
 
         // do checks
         sanityCheck();
-        checkVersionable();
-        int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.NONE);
-
-        // check if 'own' version
-        if (!version.getContainingHistory().isSame(getVersionHistory())) {
-            throw new VersionException("Unable to restore version. Not same version history.");
-        }
-
-        internalRestore(version, new DateVersionSelector(version.getCreated()), removeExisting);
-        // session.save/revert is done in internal restore
+        session.getWorkspace().getVersionManager().restore(getPath(), version, removeExisting);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void restore(Version version, String relPath, boolean removeExisting)
             throws PathNotFoundException, ItemExistsException, VersionException,
             ConstraintViolationException, UnsupportedRepositoryOperationException,
@@ -3548,48 +3431,14 @@
 
         // do checks
         sanityCheck();
-        int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.NONE);
-
-        // if node exists, do a 'normal' restore
-        if (hasNode(relPath)) {
-            getNode(relPath).restore(version, removeExisting);
-        } else {
-            NodeImpl node;
-            try {
-                // check if versionable node exists
-                InternalFrozenNode fn = ((VersionImpl) version).getInternalFrozenNode();
-                node = (NodeImpl) session.getNodeById(fn.getFrozenId());
-                if (removeExisting) {
-                    try {
-                        Path relative = session.getQPath(relPath);
-                        Path dstPath =
-                            PathFactoryImpl.getInstance().create(getPrimaryPath(), relative, false)
-                            .getCanonicalPath();
-                        // move to respective location
-                        session.move(node.getPath(), session.getJCRPath(dstPath));
-                        // need to refetch ?
-                        node = (NodeImpl) session.getNodeById(fn.getFrozenId());
-                    } catch (NameException e) {
-                        throw new RepositoryException(e);
-                    }
-                } else {
-                    throw new ItemExistsException("Unable to restore version. Versionable node already exists.");
-                }
-            } catch (ItemNotFoundException e) {
-                // not found, create new one
-                node = addNode(relPath, ((VersionImpl) version).getInternalFrozenNode());
-            }
-
-            // recreate node from frozen state
-            node.internalRestore(version, new DateVersionSelector(version.getCreated()), removeExisting);
-            // session.save/revert is done in internal restore
-        }
+        String path = getPath() + "/" + relPath;
+        session.getWorkspace().getVersionManager().restore(path, version, removeExisting);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void restoreByLabel(String versionLabel, boolean removeExisting)
             throws VersionException, ItemExistsException,
             UnsupportedRepositoryOperationException, LockException,
@@ -3597,338 +3446,32 @@
 
         // do checks
         sanityCheck();
-        int options = ItemValidator.CHECK_PENDING_CHANGES | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.NONE);
-
-        Version v = getVersionHistory().getVersionByLabel(versionLabel);
-        if (v == null) {
-            throw new VersionException("No version for label " + versionLabel + " found.");
-        }
-        internalRestore(v, new LabelVersionSelector(versionLabel), removeExisting);
-        // session.save/revert is done in internal restore
+        session.getWorkspace().getVersionManager().restoreByLabel(getPath(), versionLabel, removeExisting);
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public VersionHistory getVersionHistory()
             throws UnsupportedRepositoryOperationException, RepositoryException {
-        // check state of this instance
         sanityCheck();
-
-        boolean isFull = checkVersionable();
-
-        InternalVersionHistory vh;
-        if (isFull) {
-            NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_VERSIONHISTORY).getString());
-            vh = session.getVersionManager().getVersionHistory(id);
-        } else {
-            vh = session.getVersionManager().getVersionHistoryOfNode((NodeId) id);
-        }
-        return (VersionHistory) session.getNodeById(vh.getId());
+        return session.getWorkspace().getVersionManager().getVersionHistory(getPath());
     }
 
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public Version getBaseVersion()
             throws UnsupportedRepositoryOperationException, RepositoryException {
         // check state of this instance
         sanityCheck();
-
-        boolean isFull = checkVersionable();
-
-        InternalVersion v;
-        if (isFull) {
-            NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_BASEVERSION).getString());
-            v = session.getVersionManager().getVersion(id);
-        } else {
-            // note, that the method currently only works for linear version
-            // graphs (i.e. simple versioning)
-            v = session.getVersionManager().getHeadVersionOfNode(((NodeId) id));
-        }
-
-        return (Version) session.getNodeById(v.getId());
+        return session.getWorkspace().getVersionManager().getBaseVersion(getPath());
     }
 
     //-----------------------------------< versioning support: implementation >
     /**
-     * Checks if this node is versionable, i.e. has 'mix:versionable' or a
-     * 'mix:simpleVersionable'.
-     * @return <code>true</code> if this node is full versionable, i.e. is
-     *         of nodetype mix:versionable
-     * @throws UnsupportedRepositoryOperationException
-     *          if this node is not versionable at all
-     */
-    private boolean checkVersionable()
-            throws UnsupportedRepositoryOperationException, RepositoryException {
-        if (isNodeType(NameConstants.MIX_VERSIONABLE)) {
-            return true;
-        } else if (isNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
-            return false;
-        } else {
-            String msg = "Unable to perform a versioning operation on a " +
-                         "non versionable node: " + this;
-            log.debug(msg);
-            throw new UnsupportedRepositoryOperationException(msg);
-        }
-    }
-
-    /**
-     * Returns the corresponding node in the workspace of the given session.
-     * <p/>
-     * Given a node N1 in workspace W1, its corresponding node N2 in workspace
-     * W2 is defined as follows:
-     * <ul>
-     * <li>If N1 is the root node of W1 then N2 is the root node of W2.
-     * <li>If N1 is referenceable (has a UUID) then N2 is the node in W2 with
-     * the same UUID.
-     * <li>If N1 is not referenceable (does not have a UUID) then there is some
-     * node M1 which is either the nearest ancestor of N1 that is
-     * referenceable, or is the root node of W1. If the corresponding node
-     * of M1 is M2 in W2, then N2 is the node with the same relative path
-     * from M2 as N1 has from M1.
-     * </ul>
-     *
-     * @param srcSession
-     * @return the corresponding node or <code>null</code> if no corresponding
-     *         node exists.
-     * @throws RepositoryException If another error occurs.
-     */
-    private NodeImpl getCorrespondingNode(SessionImpl srcSession) throws RepositoryException {
-
-        // search nearest ancestor that is referenceable
-        NodeImpl m1 = this;
-        while (!m1.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
-            if (m1.getDepth() == 0) {
-                // root node
-                try {
-                    return (NodeImpl) srcSession.getItem(getPath());
-                } catch (PathNotFoundException e) {
-                    return null;
-                }
-            }
-            m1 = (NodeImpl) m1.getParent();
-        }
-
-        try {
-            // get corresponding ancestor (might throw ItemNotFoundException)
-            NodeImpl m2 = (NodeImpl) srcSession.getNodeByUUID(m1.getUUID());
-
-            // return m2, if m1 == n1
-            if (m1 == this) {
-                return m2;
-            }
-
-            String relPath;
-            try {
-                Path p = m1.getPrimaryPath().computeRelativePath(getPrimaryPath());
-                // use prefix mappings of srcSession
-                relPath = session.getJCRPath(p);
-            } catch (NameException be) {
-                // should never get here...
-                String msg = "internal error: failed to determine relative path";
-                log.error(msg, be);
-                throw new RepositoryException(msg, be);
-            }
-            if (!m2.hasNode(relPath)) {
-                return null;
-            } else {
-                return (NodeImpl) m2.getNode(relPath);
-            }
-        } catch (ItemNotFoundException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Performs the merge test. If the result is 'update', then the corresponding
-     * source node is returned. if the result is 'leave' or 'besteffort-fail'
-     * then <code>null</code> is returned. If the result of the merge test is
-     * 'fail' with bestEffort set to <code>false</code> a MergeException is
-     * thrown.
-     * <p/>
-     * jsr170 - 8.2.10 Merge:
-     * [...]
-     * <ul>
-     * <li>If N is currently checked-in then:</li>
-     * <ul>
-     * <li>If V' is a successor (to any degree) of V, then the merge result
-     *     for N is update.
-     * </li>
-     * <li>If V' is a predecessor (to any degree) of V or if V and
-     *     V' are identical (i.e., are actually the same version),
-     *     then the merge result for N is leave.
-     * </li>
-     * <li>If V is neither a successor of, predecessor of, nor
-     *     identical with V', then the merge result for N is failed.
-     *     This is the case where N and N' represent divergent
-     *     branches of the version graph, thus determining the
-     *     result of a merge is non-trivial.
-     * </li>
-     * </ul>
-     * <li>If N is currently checked-out then:</li>
-     * <ul>
-     * <li>If V' is a predecessor (to any degree) of V or if V and
-     *     V' are identical (i.e., are actually the same version),
-     *     then the merge result for N is leave.
-     * </li>
-     * <li>If any other relationship holds between V and V',
-     *     then the merge result for N is fail.
-     * </li>
-     * </ul>
-     * </ul>
-     *
-     * @param srcSession the source session
-     * @param failedIds the list to store the failed node ids.
-     * @param bestEffort the best effort flag
-     * @return the corresponding source node or <code>null</code>
-     * @throws RepositoryException if an error occurs.
-     * @throws AccessDeniedException if access is denied
-     */
-    private NodeImpl doMergeTest(SessionImpl srcSession, List<ItemId> failedIds, boolean bestEffort)
-            throws RepositoryException, AccessDeniedException {
-
-        // If N does not have a corresponding node then the merge result for N is leave.
-        NodeImpl srcNode = getCorrespondingNode(srcSession);
-        if (srcNode == null) {
-            return null;
-        }
-
-        // if not versionable, update
-        if (!isNodeType(NameConstants.MIX_VERSIONABLE) || failedIds == null) {
-            return srcNode;
-        }
-        // if source node is not versionable, leave
-        if (!srcNode.isNodeType(NameConstants.MIX_VERSIONABLE)) {
-            return null;
-        }
-        // test versions
-        VersionImpl v = (VersionImpl) getBaseVersion();
-        VersionImpl vp = (VersionImpl) srcNode.getBaseVersion();
-        if (vp.isMoreRecent(v) && !isCheckedOut()) {
-            // I f V' is a successor (to any degree) of V, then the merge result for
-            // N is update. This case can be thought of as the case where N' is
-            // "newer" than N and therefore N should be updated to reflect N'.
-            return srcNode;
-        } else if (v.isSame(vp) || v.isMoreRecent(vp)) {
-            // If V' is a predecessor (to any degree) of V or if V and V' are
-            // identical (i.e., are actually the same version), then the merge
-            // result for N is leave. This case can be thought of as the case where
-            // N' is "older" or the "same age" as N and therefore N should be left alone.
-            return null;
-        } else {
-            // If V is neither a successor of, predecessor of, nor identical
-            // with V', then the merge result for N is failed. This is the case
-            // where N and N' represent divergent branches of the version graph,
-            // thus determining the result of a merge is non-trivial.
-            if (bestEffort) {
-                // add 'offending' version to jcr:mergeFailed property
-                Set<String> set = internalGetMergeFailed();
-                set.add(srcNode.getBaseVersion().getUUID());
-                internalSetMergeFailed(set);
-                failedIds.add(id);
-                return null;
-            } else {
-                String msg =
-                    "Unable to merge nodes. Violating versions. " + this;
-                log.debug(msg);
-                throw new MergeException(msg);
-            }
-        }
-    }
-
-    /**
-     * Perform {@link Node#cancelMerge(Version)} or {@link Node#doneMerge(Version)}
-     * depending on the value of <code>cancel</code>.
-     */
-    private void internalFinishMerge(Version version, boolean cancel)
-            throws VersionException, InvalidItemStateException,
-            UnsupportedRepositoryOperationException, RepositoryException {
-        // check state of this instance
-        sanityCheck();
-
-        // check versionable
-        checkVersionable();
-
-        // check lock, permissions and checkout-status
-        int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_VERSIONING | ItemValidator.CHECK_PENDING_CHANGES_ON_NODE | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.VERSION_MNGMT);
-
-        // check if version is in mergeFailed list
-        Set<String> failed = internalGetMergeFailed();
-        if (!failed.remove(version.getUUID())) {
-            String msg =
-                "Unable to finish merge. Specified version is not in"
-                + " jcr:mergeFailed property: " + this;
-            log.error(msg);
-            throw new VersionException(msg);
-        }
-
-        boolean success = false;
-        try {
-            // remove version from mergeFailed list
-            internalSetMergeFailed(failed);
-
-            if (!cancel) {
-                // add version to jcr:predecessors list
-                Value[] vals = getProperty(NameConstants.JCR_PREDECESSORS).getValues();
-                InternalValue[] v = new InternalValue[vals.length + 1];
-                for (int i = 0; i < vals.length; i++) {
-                    v[i] = InternalValue.create(new NodeId(vals[i].getString()));
-                }
-                v[vals.length] = InternalValue.create(new NodeId(version.getUUID()));
-                internalSetProperty(NameConstants.JCR_PREDECESSORS, v);
-            }
-
-            save();
-            success = true;
-        } finally {
-            if (!success) {
-                try {
-                    refresh(false);
-                } catch (RepositoryException e) {
-                    log.error("Error while reverting changes upon failed Node.doneMerge or Node.cancelMerge, respectively.", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * @return
-     * @throws RepositoryException
-     */
-    private Set<String> internalGetMergeFailed() throws RepositoryException {
-        HashSet<String> set = new HashSet<String>();
-        if (hasProperty(NameConstants.JCR_MERGEFAILED)) {
-            Value[] vals = getProperty(NameConstants.JCR_MERGEFAILED).getValues();
-            for (int i = 0; i < vals.length; i++) {
-                set.add(vals[i].getString());
-            }
-        }
-        return set;
-    }
-
-    /**
-     * @param set
-     * @throws RepositoryException
-     */
-    private void internalSetMergeFailed(Set<String> set) throws RepositoryException {
-        if (set.isEmpty()) {
-            internalSetProperty(NameConstants.JCR_MERGEFAILED, (InternalValue[]) null);
-        } else {
-            InternalValue[] vals = new InternalValue[set.size()];
-            Iterator<String> iter = set.iterator();
-            int i = 0;
-            while (iter.hasNext()) {
-                String uuid = iter.next();
-                vals[i++] = InternalValue.create(new NodeId(uuid));
-            }
-            internalSetProperty(NameConstants.JCR_MERGEFAILED, vals);
-        }
-    }
-
-    /**
      * Determines the checked-out status of this node.
      * <p/>
      * A node is considered <i>checked-out</i> if it is versionable and
@@ -3938,6 +3481,7 @@
      *
      * @return a boolean
      * @see Node#isCheckedOut()
+     * @throws RepositoryException if an error occurs
      */
     protected boolean internalIsCheckedOut() throws RepositoryException {
         /**
@@ -3973,600 +3517,6 @@
         }
     }
 
-    /**
-     * Creates a new node at <code>relPath</code> of the node type, uuid and
-     * eventual mixin types stored in the frozen node. The same as
-     * <code>{@link #addNode(String relPath)}</code> except that the primary
-     * node type type, the uuid and evt. mixin type of the new node is
-     * explictly specified in the nt:frozen node.
-     * <p/>
-     *
-     * @param name   The name of the new <code>Node</code> that is to be created.
-     * @param frozen The frozen node that contains the creation information
-     * @return The node that was added.
-     * @throws ItemExistsException          If an item at the
-     *                                      specified path already exists(and same-name siblings are not allowed).
-     * @throws PathNotFoundException        If specified path implies intermediary
-     *                                      <code>Node</code>s that do not exist.
-     * @throws NoSuchNodeTypeException      If the specified <code>nodeTypeName</code>
-     *                                      is not recognized.
-     * @throws ConstraintViolationException If an attempt is made to add a node as the
-     *                                      child of a <code>Property</code>
-     * @throws RepositoryException          if another error occurs.
-     */
-    private NodeImpl addNode(Name name, InternalFrozenNode frozen)
-            throws ItemExistsException, PathNotFoundException,
-            ConstraintViolationException, NoSuchNodeTypeException,
-            RepositoryException {
-
-        // get frozen node type
-        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
-        NodeTypeImpl nt = ntMgr.getNodeType(frozen.getFrozenPrimaryType());
-
-        // get frozen id
-        NodeId id = frozen.getFrozenId();
-
-        NodeImpl node = internalAddChildNode(name, nt, id);
-
-        // get frozen mixin
-        // todo: also respect mixing types on creation?
-        Name[] mxNames = frozen.getFrozenMixinTypes();
-        for (Name mxName : mxNames) {
-            node.addMixin(mxName);
-        }
-        return node;
-    }
-
-    /**
-     * Creates a new node at <code>relPath</code> of the node type, uuid and
-     * eventual mixin types stored in the frozen node. The same as
-     * <code>{@link #addNode(String relPath)}</code> except that the primary
-     * node type type, the uuid and evt. mixin type of the new node is
-     * explicitly specified in the nt:frozen node.
-     * <p/>
-     *
-     * @param relPath The path of the new <code>Node</code> that is to be created.
-     * @param frozen  The frozen node that contains the creation information
-     * @return The node that was added.
-     * @throws ItemExistsException          If an item at the
-     *                                      specified path already exists(and same-name siblings are not allowed).
-     * @throws PathNotFoundException        If specified path implies intermediary
-     *                                      <code>Node</code>s that do not exist.
-     * @throws NoSuchNodeTypeException      If the specified <code>nodeTypeName</code>
-     *                                      is not recognized.
-     * @throws ConstraintViolationException If an attempt is made to add a node as the
-     *                                      child of a <code>Property</code>
-     * @throws RepositoryException          if another error occurs.
-     */
-    private NodeImpl addNode(String relPath, InternalFrozenNode frozen)
-            throws ItemExistsException, PathNotFoundException,
-            ConstraintViolationException, NoSuchNodeTypeException,
-            RepositoryException {
-
-        // get frozen node type
-        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
-        NodeTypeImpl nt = ntMgr.getNodeType(frozen.getFrozenPrimaryType());
-
-        // get frozen id
-        NodeId id = frozen.getFrozenId();
-
-        NodeImpl node = internalAddNode(relPath, nt, id);
-
-        // get frozen mixin
-        // todo: also respect mixing types on creation?
-        Name[] mxNames = frozen.getFrozenMixinTypes();
-        for (Name mxName : mxNames) {
-            node.addMixin(mxName);
-        }
-        return node;
-    }
-
-    /**
-     * Executes the Node#update or Node#merge call.
-     *
-     * @param srcWorkspaceName Name of the source workspace as passed to
-     * {@link Node#merge(String, boolean)} or {@link Node#update(String)}.
-     * @param failedIds List to place the failed ids or <code>null</code> if
-     * {@link Node#update(String)} should be executed.
-     * @param bestEffort Flag passed to {@link Node#merge(String, boolean)} or
-     * false if {@link Node#update(String)} should be executed.
-     * @throws NoSuchWorkspaceException
-     * @throws AccessDeniedException
-     * @throws LockException
-     * @throws InvalidItemStateException
-     * @throws RepositoryException
-     */
-    private void internalMerge(String srcWorkspaceName,
-                               List<ItemId> failedIds, boolean bestEffort,
-                               boolean shallow)
-            throws NoSuchWorkspaceException, AccessDeniedException,
-            LockException, InvalidItemStateException, RepositoryException {
-
-        // might be added in future releases
-        boolean removeExisting = true;
-        boolean replaceExisting = false;
-
-        // do checks
-        sanityCheck();
-        session.getValidator().checkModify(this, ItemValidator.CHECK_PENDING_CHANGES, Permission.VERSION_MNGMT);
-
-        // if same workspace, ignore
-        if (srcWorkspaceName.equals(session.getWorkspace().getName())) {
-            return;
-        }
-
-        SessionImpl srcSession = null;
-        boolean success = false;
-        try {
-            // create session on other workspace for current subject
-            // (may throw NoSuchWorkspaceException and AccessDeniedException)
-            srcSession = rep.createSession(session.getSubject(), srcWorkspaceName);
-            internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
-            session.save();
-            success = true;
-        } finally {
-            if (!success) {
-                try {
-                    session.refresh(false);
-                } catch (RepositoryException e) {
-                    log.error("Error while cleaning up after failed merge/update", e);
-                }
-            }
-            if (srcSession != null) {
-                // we don't need the other session anymore, logout
-                srcSession.logout();
-            }
-        }
-    }
-
-    /**
-     * Merges/Updates this node with its corresponding ones
-     *
-     * @param srcSession
-     * @param failedIds
-     * @param bestEffort
-     * @param removeExisting
-     * @param replaceExisting
-     * @throws LockException
-     * @throws RepositoryException
-     */
-    private void internalMerge(SessionImpl srcSession, List<ItemId> failedIds,
-                               boolean bestEffort, boolean removeExisting,
-                               boolean replaceExisting, boolean shallow)
-            throws LockException, RepositoryException {
-
-        if (shallow) {
-            throw new UnsupportedRepositoryOperationException("Shallow merge not supported yet");
-        }
-
-        NodeImpl srcNode = doMergeTest(srcSession, failedIds, bestEffort);
-        if (srcNode == null) {
-            // leave, iterate over children, but ignore non-versionable child
-            // nodes (see JCR-1046)
-            NodeIterator iter = getNodes();
-            while (iter.hasNext()) {
-                NodeImpl n = (NodeImpl) iter.nextNode();
-                if (n.isNodeType(NameConstants.MIX_VERSIONABLE)) {
-                    n.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
-                }
-            }
-            return;
-        }
-
-        // check lock and hold status
-        int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_HOLD;
-        session.getValidator().checkModify(this, options, Permission.NONE);
-
-        // update the properties
-        PropertyIterator iter = getProperties();
-        while (iter.hasNext()) {
-            PropertyImpl p = (PropertyImpl) iter.nextProperty();
-            if (!srcNode.hasProperty(p.getQName())) {
-                p.internalRemove(true);
-            }
-        }
-        iter = srcNode.getProperties();
-        while (iter.hasNext()) {
-            PropertyImpl p = (PropertyImpl) iter.nextProperty();
-            // ignore system types
-            if (p.getQName().equals(NameConstants.JCR_PRIMARYTYPE)
-                    || p.getQName().equals(NameConstants.JCR_MIXINTYPES)
-                    || p.getQName().equals(NameConstants.JCR_UUID)) {
-                continue;
-            }
-            if (p.getDefinition().isMultiple()) {
-                internalSetProperty(p.getQName(), p.internalGetValues());
-            } else {
-                internalSetProperty(p.getQName(), p.internalGetValue());
-            }
-        }
-        // todo: add/remove mixins ?
-
-        // update the nodes. remove non existing ones
-        NodeIterator niter = getNodes();
-        while (niter.hasNext()) {
-            NodeImpl n = (NodeImpl) niter.nextNode();
-            Path.Element name = n.getPrimaryPath().getNameElement();
-            int idx = name.getIndex();
-            if (idx == 0) {
-                idx = 1;
-            }
-            if (!srcNode.hasNode(name.getName(), idx)) {
-                n.internalRemove(true);
-            }
-        }
-
-        // add source ones
-        niter = srcNode.getNodes();
-        while (niter.hasNext()) {
-            NodeImpl child = (NodeImpl) niter.nextNode();
-            NodeImpl dstNode = null;
-            NodeId childId = child.getNodeId();
-            Path.Element name = child.getPrimaryPath().getNameElement();
-            int idx = name.getIndex();
-            if (idx == 0) {
-                idx = 1;
-            }
-
-            if (child.isNodeType(NameConstants.MIX_REFERENCEABLE)) {
-                // check if correspondance exist in
-                // this workspace
-                try {
-                    dstNode = session.getNodeById(childId);
-                    // check if same parent
-                    if (!isSame(dstNode.getParent())) {
-                        if (removeExisting) {
-                            dstNode.internalRemove(false);
-                            dstNode = null;
-                        } else if (replaceExisting) {
-                            // node exists outside of this update tree, so continue there
-                        } else {
-                            throw new ItemExistsException("Unable to update item: " + dstNode);
-                        }
-                    }
-
-                } catch (ItemNotFoundException e) {
-                    // does not exist
-                }
-            } else {
-                // if child is not referenceable, clear uuid
-                childId = null;
-            }
-            if (dstNode == null && hasNode(name.getName(), idx)) {
-                // the exact behaviour for SNS is not specified by the spec
-                // so we just try to find the corresponding one.
-                dstNode = getNode(name.getName(), idx);
-            }
-            if (dstNode == null) {
-                dstNode = internalAddChildNode(name.getName(), (NodeTypeImpl) child.getPrimaryNodeType(), childId);
-                // add mixins
-                NodeType[] mixins = child.getMixinNodeTypes();
-                for (int i = 0; i < mixins.length; i++) {
-                    dstNode.addMixin(mixins[i].getName());
-                }
-                dstNode.internalMerge(srcSession, null, bestEffort, removeExisting, replaceExisting, shallow);
-            } else {
-                dstNode.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
-            }
-        }
-    }
-
-    /**
-     * Internal method to restore a version.
-     *
-     * @param version version to restore
-     * @param vsel the version selector that will select the correct version for
-     * OPV=Version child nodes.
-     * @param removeExisting remove existing flag
-     * @throws RepositoryException if an error occurs
-     */
-    private void internalRestore(Version version, VersionSelector vsel, boolean removeExisting)
-            throws RepositoryException {
-
-        boolean success = false;
-        try {
-            internalRestore((VersionImpl) version, vsel, removeExisting);
-            session.save();
-            success = true;
-        } finally {
-            if (!success) {
-                // revert session
-                try {
-                    log.debug("reverting changes applied during restore...");
-                    session.refresh(false);
-                } catch (RepositoryException e) {
-                    log.error("Error while reverting changes applied during restore.", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Internal method to restore a version.
-     *
-     * @param version version to restore
-     * @param vsel the version selector that will select the correct version for
-     * OPV=Version child nodes.
-     * @param removeExisting remove existing flag
-     * @return array of restored versions
-     * @throws RepositoryException if an error occurs
-     */
-    public Version[] internalRestore(VersionImpl version, VersionSelector vsel,
-                                        boolean removeExisting)
-            throws RepositoryException {
-
-        // fail if root version
-        if (version.isRootVersion()) {
-            throw new VersionException("Restore of root version not allowed.");
-        }
-
-        boolean isFull = checkVersionable();
-
-        // check permission
-        session.getAccessManager().checkPermission(getPrimaryPath(), Permission.VERSION_MNGMT);
-
-        // set jcr:isCheckedOut property to true, in order to avoid any conflicts
-        internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(true));
-
-        // 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).
-        HashSet<Version> restored = new HashSet<Version>();
-        restoreFrozenState(version.getInternalFrozenNode(), vsel, restored, removeExisting);
-        restored.add(version);
-
-        if (isFull) {
-            // 2. N's jcr:baseVersion property will be changed to point to V.
-            internalSetProperty(
-                    NameConstants.JCR_BASEVERSION,
-                    InternalValue.create((NodeId) version.getId()));
-
-            // 4. N's jcr:predecessor property is set to null
-            internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
-
-            // also clear mergeFailed
-            internalSetProperty(NameConstants.JCR_MERGEFAILED, (InternalValue[]) null);
-
-        } else {
-            // with simple versioning, the node is checked in automatically,
-            // thus not allowing any branches
-            session.getVersionManager().checkin(this);
-        }
-        // 3. N's jcr:isCheckedOut property is set to false.
-        internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
-
-        return restored.toArray(new Version[restored.size()]);
-    }
-
-    /**
-     * Restores the properties and child nodes from the frozen state.
-     *
-     * @param freeze the frozen node
-     * @param vsel version selector
-     * @param restored set of restored versions
-     * @param removeExisting remove existing flag
-     * @throws RepositoryException if an error occurs
-     */
-    public void restoreFrozenState(InternalFrozenNode freeze, VersionSelector vsel,
-                            Set<Version> restored, boolean removeExisting)
-            throws RepositoryException {
-
-        // check uuid
-        if (isNodeType(NameConstants.MIX_REFERENCEABLE)) {
-            if (!getNodeId().equals(freeze.getFrozenId())) {
-                throw new ItemExistsException("Unable to restore version of " + this + ". UUID changed.");
-            }
-        }
-
-        // check primary type
-        if (!freeze.getFrozenPrimaryType().equals(data.getNodeState().getNodeTypeName())) {
-            // todo: check with spec what should happen here
-            throw new ItemExistsException("Unable to restore version of " + this + ". PrimaryType changed.");
-        }
-
-        // adjust mixins
-        Name[] mixinNames = freeze.getFrozenMixinTypes();
-        setMixinTypesProperty(new HashSet<Name>(Arrays.asList(mixinNames)));
-
-        // 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());
-            if (prop.isMultiValued()) {
-                internalSetProperty(
-                        prop.getName(), prop.getValues(), prop.getType());
-            } else {
-                internalSetProperty(prop.getName(), prop.getValues()[0]);
-            }
-        }
-        // remove properties that do not exist in the frozen representation
-        PropertyIterator piter = getProperties();
-        while (piter.hasNext()) {
-            PropertyImpl prop = (PropertyImpl) piter.nextProperty();
-            // ignore some props that are not well guarded by the OPV
-            if (prop.getQName().equals(NameConstants.JCR_VERSIONHISTORY)) {
-                continue;
-            } else if (prop.getQName().equals(NameConstants.JCR_PREDECESSORS)) {
-                continue;
-            }
-            if (prop.getDefinition().getOnParentVersion() == OnParentVersionAction.COPY
-                    || prop.getDefinition().getOnParentVersion() == OnParentVersionAction.VERSION) {
-                if (!propNames.contains(prop.getQName())) {
-                    removeChildProperty(prop.getQName());
-                }
-            }
-        }
-
-        // add 'auto-create' properties that do not exist yet
-        NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
-        for (Name mixinName : mixinNames) {
-            NodeTypeImpl mixin = ntMgr.getNodeType(mixinName);
-            PropertyDefinition[] pda = mixin.getAutoCreatedPropertyDefinitions();
-            for (PropertyDefinition aPda : pda) {
-                PropertyDefinitionImpl pd = (PropertyDefinitionImpl) aPda;
-                if (!hasProperty(pd.getQName())) {
-                    createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
-                }
-            }
-        }
-
-        // first delete some of the version histories
-        NodeIterator iter = getNodes();
-        while (iter.hasNext()) {
-            NodeImpl n = (NodeImpl) iter.nextNode();
-            if (n.getDefinition().getOnParentVersion() == OnParentVersionAction.COPY) {
-                // only remove OPV=Copy nodes
-                n.internalRemove(true);
-            } else if (n.getDefinition().getOnParentVersion() == OnParentVersionAction.VERSION) {
-                // only remove, if node to be restored does not contain child,
-                // or if restored child is not versionable
-                NodeId vhId = n.hasProperty(NameConstants.JCR_VERSIONHISTORY)
-                        ? new NodeId(n.getProperty(NameConstants.JCR_VERSIONHISTORY).getString())
-                        : null;
-                if (vhId == null || !freeze.hasFrozenHistory(vhId)) {
-                    n.internalRemove(true);
-                }
-            }
-        }
-
-        // restore the frozen nodes
-        InternalFreeze[] frozenNodes = freeze.getFrozenChildNodes();
-        for (InternalFreeze child : frozenNodes) {
-            NodeImpl restoredChild = null;
-            if (child instanceof InternalFrozenNode) {
-                InternalFrozenNode f = (InternalFrozenNode) child;
-                // check for existing
-                if (f.getFrozenId() != null) {
-                    try {
-                        NodeImpl existing = (NodeImpl) session.getNodeById(f.getFrozenId());
-                        // check if one of this restore trees node
-                        if (removeExisting) {
-                            existing.remove();
-                        } else if (existing.isShareable()) {
-                            // if existing node is shareable, then clone it
-                            restoredChild = clone(existing, f.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);
-                        }
-                    } catch (ItemNotFoundException e) {
-                        // ignore, item with uuid does not exist
-                    }
-                }
-                if (restoredChild == null) {
-                    restoredChild = addNode(f.getName(), f);
-                    restoredChild.restoreFrozenState(f, vsel, restored, removeExisting);
-                }
-
-            } else if (child instanceof InternalFrozenVersionHistory) {
-                InternalFrozenVersionHistory f = (InternalFrozenVersionHistory) child;
-                VersionHistory history = (VersionHistory) session.getNodeById(f.getVersionHistoryId());
-                NodeId nodeId = NodeId.valueOf(history.getVersionableUUID());
-                String oldVersion = "jcr:dummy";
-
-                // check if representing versionable already exists somewhere
-                if (itemMgr.itemExists(nodeId)) {
-                    NodeImpl n = session.getNodeById(nodeId);
-                    if (removeExisting) {
-                        String dstPath = getPath() + "/" + n.getName();
-                        if (!n.getPath().equals(dstPath)) {
-                            session.move(n.getPath(), dstPath);
-                        }
-                        oldVersion = n.getBaseVersion().getName();
-                    } else if (n.getParent().isSame(this)) {
-                        n.internalRemove(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: " + n);
-                    }
-                }
-                // get desired version from version selector
-                VersionImpl v = (VersionImpl) vsel.select(history);
-
-                // check existing version of item exists
-                if (!itemMgr.itemExists(nodeId)) {
-                    if (v == null) {
-                        // if version selector was unable to select version,
-                        // choose the initial one
-                        Version[] vs = history.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 = (VersionImpl) vs[0];
-                    }
-                    restoredChild = addNode(child.getName(), v.getInternalFrozenNode());
-                } else {
-                    restoredChild = session.getNodeById(nodeId);
-                    if (v == null || oldVersion == null || v.getName().equals(oldVersion)) {
-                        v = null;
-                    }
-                }
-                if (v != null) {
-                    try {
-                        restoredChild.internalRestore(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();
-                        VersionIterator vi = history.getAllVersions();
-                        while (vi.hasNext()) {
-                            avail.append(vi.nextVersion().getName());
-                            if (vi.hasNext()) {
-                                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
-                    && getPrimaryNodeType().hasOrderableChildNodes()) {
-                orderBefore(restoredChild.getPrimaryPath().getNameElement(), null);
-            }
-        }
-    }
-
-    /**
-     * Copies a property to this node
-     *
-     * @param prop property to copy from
-     * @throws RepositoryException if an error occurs
-     */
-    protected void internalCopyPropertyFrom(PropertyImpl prop) throws RepositoryException {
-        if (prop.getDefinition().isMultiple()) {
-            Value[] values = prop.getValues();
-            InternalValue[] ivalues = new InternalValue[values.length];
-            for (int i = 0; i < values.length; i++) {
-                ivalues[i] = InternalValue.create(values[i], session, rep.getDataStore());
-            }
-            internalSetProperty(prop.getQName(), ivalues);
-        } else {
-            InternalValue value = InternalValue.create(prop.getValue(), session, rep.getDataStore());
-            internalSetProperty(prop.getQName(), value);
-        }
-    }
-
     //------------------------------------------------------< locking support >
     /**
      * {@inheritDoc}

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Sun Jul 19 00:09:40 2009
@@ -989,8 +989,10 @@
      *                                  is not granted access to the specified
      *                                  workspace
      * @throws RepositoryException      if another error occurs
+     *
+     * FIX PUBLIC!!!!
      */
-    protected final SessionImpl createSession(Subject subject,
+    public final SessionImpl createSession(Subject subject,
                                               String workspaceName)
             throws NoSuchWorkspaceException, AccessDeniedException,
             RepositoryException {

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Sun Jul 19 00:09:40 2009
@@ -16,12 +16,9 @@
  */
 package org.apache.jackrabbit.core;
 
-import java.util.HashMap;
-
 import javax.jcr.AccessDeniedException;
 import javax.jcr.InvalidItemStateException;
 import javax.jcr.ItemExistsException;
-import javax.jcr.ItemNotFoundException;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.NoSuchWorkspaceException;
 import javax.jcr.PathNotFoundException;
@@ -35,7 +32,6 @@
 import javax.jcr.query.QueryManager;
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
 import javax.jcr.version.VersionManager;
 
 import org.apache.jackrabbit.api.JackrabbitWorkspace;
@@ -52,10 +48,7 @@
 import org.apache.jackrabbit.core.retention.RetentionRegistry;
 import org.apache.jackrabbit.core.state.LocalItemStateManager;
 import org.apache.jackrabbit.core.state.SharedItemStateManager;
-import org.apache.jackrabbit.core.version.DateVersionSelector;
 import org.apache.jackrabbit.core.version.JcrVersionManagerImpl;
-import org.apache.jackrabbit.core.version.VersionImpl;
-import org.apache.jackrabbit.core.version.VersionSelector;
 import org.apache.jackrabbit.core.xml.ImportHandler;
 import org.apache.jackrabbit.core.xml.Importer;
 import org.apache.jackrabbit.core.xml.WorkspaceImporter;
@@ -256,7 +249,7 @@
     public VersionManager getVersionManager()
             throws UnsupportedRepositoryOperationException, RepositoryException {
         if (versionMgr == null) {
-            versionMgr = new JcrVersionManagerImpl(session);
+            versionMgr = new JcrVersionManagerImpl(session, stateMgr, hierMgr);
         }
         return versionMgr;
     }
@@ -784,90 +777,14 @@
     /**
      * {@inheritDoc}
      */
+    @Deprecated
     public void restore(Version[] versions, boolean removeExisting)
             throws ItemExistsException, UnsupportedRepositoryOperationException,
             VersionException, LockException, InvalidItemStateException,
             RepositoryException {
-
-        // todo: perform restore operations direct on the node states
-
         // check state of this instance
         sanityCheck();
-
-        // add all versions to map of versions to restore
-        final HashMap<String, VersionImpl> toRestore = new HashMap<String, VersionImpl>();
-        for (Version v : versions) {
-            VersionHistory vh = v.getContainingHistory();
-            // check for collision
-            if (toRestore.containsKey(vh.getUUID())) {
-                throw new VersionException("Unable to restore. Two or more versions have same version history.");
-            }
-            toRestore.put(vh.getUUID(), (VersionImpl) v);
-        }
-
-        // create a version selector to the set of versions
-        VersionSelector vsel = new VersionSelector() {
-            public Version select(VersionHistory versionHistory) throws RepositoryException {
-                // try to select version as specified
-                Version v = toRestore.get(versionHistory.getUUID());
-                if (v == null) {
-                    // select latest one
-                    v = DateVersionSelector.selectByDate(versionHistory, null);
-                }
-                return v;
-            }
-        };
-
-        // check for pending changes
-        if (session.hasPendingChanges()) {
-            String msg = "Unable to restore version. Session has pending changes.";
-            log.debug(msg);
-            throw new InvalidItemStateException(msg);
-        }
-        // TODO: add checks for lock/hold...
-        boolean success = false;
-        try {
-            // now restore all versions that have a node in the ws
-            int numRestored = 0;
-            while (toRestore.size() > 0) {
-                Version[] restored = null;
-                for (VersionImpl v : toRestore.values()) {
-                    try {
-                        NodeImpl node = (NodeImpl) session.getNodeById(v.getInternalFrozenNode().getFrozenId());
-                        restored = node.internalRestore(v, vsel, removeExisting);
-                        // remove restored versions from set
-                        for (Version r : restored) {
-                            toRestore.remove(r.getContainingHistory().getUUID());
-                        }
-                        numRestored += restored.length;
-                        break;
-                    } catch (ItemNotFoundException e) {
-                        // ignore
-                    }
-                }
-                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.");
-                    }
-                }
-            }
-            session.save();
-            success = true;
-        } finally {
-            if (!success) {
-                // revert session
-                try {
-                    log.debug("reverting changes applied during restore...");
-                    session.refresh(false);
-                } catch (RepositoryException e) {
-                    log.error("Error while reverting changes applied during restore.", e);
-                }
-            }
-        }
+        getVersionManager().restore(versions, removeExisting);
     }
 
     /**

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java Sun Jul 19 00:09:40 2009
@@ -25,6 +25,7 @@
 
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.NodeImpl;
+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;
@@ -534,7 +535,7 @@
      * @see javax.jcr.Node#checkin()
      */
     protected InternalVersion internalCheckin(InternalVersionHistoryImpl history,
-                                      NodeImpl node, boolean simple)
+                                      NodeStateEx node, boolean simple)
             throws RepositoryException {
         WriteOperation operation = startWriteOperation();
         try {
@@ -543,11 +544,10 @@
 
             // check for jcr:activity
             if (node.hasProperty(NameConstants.JCR_ACTIVITY)) {
-                NodeId actId = node.getProperty(NameConstants.JCR_ACTIVITY).internalGetValue().getNodeId();
+                NodeId actId = node.getPropertyValue(NameConstants.JCR_ACTIVITY).getNodeId();
                 InternalActivityImpl act = (InternalActivityImpl) getItem(actId);
                 act.addVersion(v);
             }
-
             operation.save();
             return v;
         } catch (ItemStateException e) {
@@ -600,7 +600,7 @@
      * @throws RepositoryException if an error occurs.
      */
     protected String calculateCheckinVersionName(InternalVersionHistoryImpl history,
-                                                 NodeImpl node, boolean simple)
+                                                 NodeStateEx node, boolean simple)
             throws RepositoryException {
         InternalVersion best = null;
         if (simple) {
@@ -609,9 +609,9 @@
             best = history.getVersion(names[names.length - 1]);
         } else {
             // 1. search a predecessor, suitable for generating the new name
-            Value[] values = node.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
-            for (Value value: values) {
-                InternalVersion pred = history.getVersion(NodeId.valueOf(value.getString()));
+            InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);
+            for (InternalValue value: values) {
+                InternalVersion pred = history.getVersion(value.getNodeId());
                 if (best == null
                         || pred.getName().getLocalName().length() < best.getName().getLocalName().length()) {
                     best = pred;

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/DateVersionSelector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/DateVersionSelector.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/DateVersionSelector.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/DateVersionSelector.java Sun Jul 19 00:09:40 2009
@@ -16,12 +16,12 @@
  */
 package org.apache.jackrabbit.core.version;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
 import java.util.Calendar;
 
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.spi.Name;
+
 /**
  * This Class implements a version selector that selects a version by creation
  * date. The selected version is the latest that is older or equal than the
@@ -57,7 +57,7 @@
      * Creates a <code>DateVersionSelector</code> that will select the latest
      * version of all those that are older than the given date.
      *
-     * @param date
+     * @param date reference date
      */
     public DateVersionSelector(Calendar date) {
         this.date = date;
@@ -67,8 +67,8 @@
      * Creates a <code>DateVersionSelector</code> that will select the latest
      * version of all those that are older than the given date.
      *
-     * @param date
-     * @param returnLatest
+     * @param date reference date
+     * @param returnLatest if <code>true</code> latest is selected
      */
     public DateVersionSelector(Calendar date, boolean returnLatest) {
         this.date = date;
@@ -87,7 +87,7 @@
     /**
      * Sets the date hint
      *
-     * @param date
+     * @param date reference date
      */
     public void setDate(Calendar date) {
         this.date = date;
@@ -107,22 +107,20 @@
      * Sets the flag, if the latest version should be selected, if no
      * version can be found using the given hint.
      *
-     * @param returnLatest
+     * @param returnLatest the <ocde>returnLatest</code> flag
      */
     public void setReturnLatest(boolean returnLatest) {
         this.returnLatest = returnLatest;
     }
 
     /**
+     * {@inheritDoc}
+     *
      * Selects a version from the given version history using the previously
      * assigned hint in the following order: name, label, date, latest.
-     *
-     * @param versionHistory
-     * @return
-     * @throws RepositoryException
      */
-    public Version select(VersionHistory versionHistory) throws RepositoryException {
-        Version selected = null;
+    public InternalVersion select(InternalVersionHistory versionHistory) throws RepositoryException {
+        InternalVersion selected = null;
         if (date != null) {
             selected = DateVersionSelector.selectByDate(versionHistory, date);
         }
@@ -135,21 +133,20 @@
     /**
      * Selects a version by date.
      *
-     * @param history
-     * @param date
+     * @param history history to select from
+     * @param date reference date
      * @return the latest version that is older than the given date date or
      * <code>null</code>
-     * @throws RepositoryException
+     * @throws RepositoryException if an error occurs
      */
-    public static Version selectByDate(VersionHistory history, Calendar date)
+    public static InternalVersion selectByDate(InternalVersionHistory history, Calendar date)
             throws RepositoryException {
         long time = (date != null) ? date.getTimeInMillis() : Long.MAX_VALUE;
         long latestDate = Long.MIN_VALUE;
-        Version latestVersion = null;
-        VersionIterator iter = history.getAllVersions();
-        while (iter.hasNext()) {
-            Version v = iter.nextVersion();
-            if (v.getPredecessors().length == 0) {
+        InternalVersion latestVersion = null;
+        for (Name name: history.getVersionNames()) {
+            InternalVersion v = history.getVersion(name);
+            if (v.isRootVersion()) {
                 // ignore root version
                 continue;
             }

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java Sun Jul 19 00:09:40 2009
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import java.util.Set;
+
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.state.PropertyState;
 import org.apache.jackrabbit.spi.Name;
@@ -64,7 +66,7 @@
      *
      * @return the list of names of the frozen mixin types.
      */
-    Name[] getFrozenMixinTypes();
+    Set<Name> getFrozenMixinTypes();
 
     /**
      * Checks if this frozen node has the frozen version history

Modified: jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java?rev=795452&r1=795451&r2=795452&view=diff
==============================================================================
--- jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java (original)
+++ jackrabbit/sandbox/tripod-JCR-2209/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java Sun Jul 19 00:09:40 2009
@@ -16,27 +16,25 @@
  */
 package org.apache.jackrabbit.core.version;
 
-import org.apache.jackrabbit.core.NodeImpl;
-import org.apache.jackrabbit.core.PropertyImpl;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.OnParentVersionAction;
+import javax.jcr.version.VersionException;
+
 import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+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.ChildNodeEntry;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 
-import javax.jcr.NodeIterator;
-import javax.jcr.PropertyIterator;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.version.OnParentVersionAction;
-import javax.jcr.version.VersionException;
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Implements a <code>InternalFrozenNode</code>
  */
@@ -44,20 +42,24 @@
         implements InternalFrozenNode {
 
     /**
-     * checkin mode version.
-     */
-    private static final int MODE_VERSION = 0;
-
-    /**
-     * checkin mode copy. specifies, that the items are always copied.
+     * checkin modes
      */
-    private static final int MODE_COPY = 1;
-
-    /**
-     * mode flag specifies, that the mode should be recursed. otherwise i
-     * will be redetermined by the opv.
-     */
-    private static final int MODE_COPY_RECURSIVE = 3;
+    private static enum Mode {
+        /**
+         * checkin mode version.
+         */
+        VERSION,
+        /**
+         * checkin mode copy. specifies, that the items are always copied.
+         */
+        COPY,
+
+        /**
+         * mode flag specifies, that the mode should be recursed. otherwise i
+         * will be redetermined by the opv.
+         */
+        COPY_RECURSE
+    }
 
     /**
      * the list of frozen properties
@@ -82,13 +84,15 @@
     /**
      * the frozen list of mixin types of the original node
      */
-    private Name[] frozenMixinTypes = null;
+    private Set<Name> frozenMixinTypes = null;
 
     /**
      * Creates a new frozen node based on the given persistance node.
      *
-     * @param node
-     * @throws javax.jcr.RepositoryException
+     * @param vMgr version manager
+     * @param node underlying node
+     * @param parent parent item
+     * @throws RepositoryException if an error occurs
      */
     public InternalFrozenNodeImpl(AbstractVersionManager vMgr, NodeStateEx node,
                                   InternalVersionItem parent)
@@ -104,6 +108,7 @@
         }
         List<PropertyState> propList = new ArrayList<PropertyState>();
 
+        Set<Name> mixins = new HashSet<Name>();
         for (PropertyState prop : props) {
             if (prop.getName().equals(NameConstants.JCR_FROZENUUID)) {
                 // special property
@@ -124,12 +129,9 @@
             } else if (prop.getName().equals(NameConstants.JCR_FROZENMIXINTYPES)) {
                 // special property
                 InternalValue[] values = node.getPropertyValues(NameConstants.JCR_FROZENMIXINTYPES);
-                if (values == null) {
-                    frozenMixinTypes = new Name[0];
-                } else {
-                    frozenMixinTypes = new Name[values.length];
-                    for (int j = 0; j < values.length; j++) {
-                        frozenMixinTypes[j] = values[j].getName();
+                if (values != null) {
+                    for (InternalValue value : values) {
+                        mixins.add(value.getName());
                     }
                 }
             } else if (prop.getName().equals(NameConstants.JCR_PRIMARYTYPE)) {
@@ -140,12 +142,10 @@
                 propList.add(prop);
             }
         }
-        frozenProperties = (PropertyState[]) propList.toArray(new PropertyState[propList.size()]);
+        frozenProperties = propList.toArray(new PropertyState[propList.size()]);
+        frozenMixinTypes = Collections.unmodifiableSet(mixins);
 
         // do some checks
-        if (frozenMixinTypes == null) {
-            frozenMixinTypes = new Name[0];
-        }
         if (frozenPrimaryType == null) {
             throw new RepositoryException("Illegal frozen node. Must have 'frozenPrimaryType'");
         }
@@ -193,10 +193,10 @@
     public boolean hasFrozenHistory(NodeId id) {
         try {
             InternalFreeze[] frozen = getFrozenChildNodes();
-            for (int i = 0; i < frozen.length; i++) {
-                if (frozen[i] instanceof InternalFrozenVersionHistory
-                        && ((InternalFrozenVersionHistory) frozen[i])
-                            .getVersionHistoryId().equals(id)) {
+            for (InternalFreeze aFrozen : frozen) {
+                if (aFrozen instanceof InternalFrozenVersionHistory
+                        && ((InternalFrozenVersionHistory) aFrozen)
+                        .getVersionHistoryId().equals(id)) {
                     return true;
                 }
             }
@@ -230,7 +230,7 @@
     /**
      * {@inheritDoc}
      */
-    public Name[] getFrozenMixinTypes() {
+    public Set<Name> getFrozenMixinTypes() {
         return frozenMixinTypes;
     }
 
@@ -241,16 +241,20 @@
      * list of frozen properties. It creates frozen child nodes for each child
      * node of <code>src</code> according to its OPV value.
      *
-     * @param parent
-     * @param name
-     * @param src
-     * @return
-     * @throws RepositoryException
+     * @param parent destination parent
+     * @param name new node name
+     * @param src source node state
+     * @return the node node state
+     * @throws RepositoryException if an error occurs
      */
     protected static NodeStateEx checkin(NodeStateEx parent, Name name,
-                                         NodeImpl src)
+                                         NodeStateEx src)
             throws RepositoryException {
-        return checkin(parent, name, src, MODE_VERSION);
+        try {
+            return checkin(parent, name, src, Mode.VERSION);
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
     }
 
     /**
@@ -260,15 +264,17 @@
      * list of frozen properties. It creates frozen child nodes for each child
      * node of <code>src</code> according to its OPV value.
      *
-     * @param parent
-     * @param name
-     * @param src
-     * @return
-     * @throws RepositoryException
+     * @param parent destination parent
+     * @param name new node name
+     * @param src source node state
+     * @param mode checkin mode
+     * @return the nde node state
+     * @throws RepositoryException if an error occurs
+     * @throws ItemStateException if an error during reading the items occurs
      */
     private static NodeStateEx checkin(NodeStateEx parent, Name name,
-                                       NodeImpl src, int mode)
-            throws RepositoryException {
+                                       NodeStateEx src, Mode mode)
+            throws RepositoryException, ItemStateException {
 
         // create new node
         NodeStateEx node = parent.addNode(name, NameConstants.NT_FROZENNODE, null, true);
@@ -277,47 +283,40 @@
         node.setPropertyValue(NameConstants.JCR_FROZENUUID,
                 InternalValue.create(src.getNodeId().toString()));
         node.setPropertyValue(NameConstants.JCR_FROZENPRIMARYTYPE,
-                InternalValue.create(((NodeTypeImpl) src.getPrimaryNodeType()).getQName()));
+                InternalValue.create(src.getState().getNodeTypeName()));
         if (src.hasProperty(NameConstants.JCR_MIXINTYPES)) {
-            NodeType[] mixins = src.getMixinNodeTypes();
-            InternalValue[] ivalues = new InternalValue[mixins.length];
-            for (int i = 0; i < mixins.length; i++) {
-                ivalues[i] = InternalValue.create(((NodeTypeImpl) mixins[i]).getQName());
-            }
-            node.setPropertyValues(NameConstants.JCR_FROZENMIXINTYPES, PropertyType.NAME, ivalues);
+            node.setPropertyValues(NameConstants.JCR_FROZENMIXINTYPES,
+                    PropertyType.NAME, src.getPropertyValues(NameConstants.JCR_MIXINTYPES));
         }
 
         // add the properties
-        PropertyIterator piter = src.getProperties();
-        while (piter.hasNext()) {
-            PropertyImpl prop = (PropertyImpl) piter.nextProperty();
+        for (PropertyState prop: src.getProperties()) {
             int opv;
-            if ((mode & MODE_COPY) > 0) {
+            if (mode != Mode.VERSION) {
                 opv = OnParentVersionAction.COPY;
             } else {
-                opv = prop.getDefinition().getOnParentVersion();
+                opv = src.getDefinition(prop).getOnParentVersion();
             }
 
+            Name propName = prop.getName();
             if (opv == OnParentVersionAction.ABORT) {
                 parent.reload();
-                throw new VersionException("Checkin aborted due to OPV in " + prop);
+                throw new VersionException("Checkin aborted due to OPV in " + propName);
             } else if (opv == OnParentVersionAction.VERSION
                     || opv == OnParentVersionAction.COPY) {
                 // ignore frozen properties
-                if (!prop.getQName().equals(NameConstants.JCR_PRIMARYTYPE)
-                        && !prop.getQName().equals(NameConstants.JCR_MIXINTYPES)
-                        && !prop.getQName().equals(NameConstants.JCR_UUID)) {
+                if (!propName.equals(NameConstants.JCR_PRIMARYTYPE)
+                        && !propName.equals(NameConstants.JCR_MIXINTYPES)
+                        && !propName.equals(NameConstants.JCR_UUID)) {
                     node.copyFrom(prop);
                 }
             }
         }
 
         // add the frozen children and histories
-        NodeIterator niter = src.getNodes();
-        while (niter.hasNext()) {
-            NodeImpl child = (NodeImpl) niter.nextNode();
+        for (NodeStateEx child: src.getChildNodes()) {
             int opv;
-            if ((mode & MODE_COPY_RECURSIVE) > 0) {
+            if (mode == Mode.COPY_RECURSE) {
                 opv = OnParentVersionAction.COPY;
             } else {
                 opv = child.getDefinition().getOnParentVersion();
@@ -326,22 +325,19 @@
             if (opv == OnParentVersionAction.ABORT) {
                 throw new VersionException("Checkin aborted due to OPV in " + child);
             } else if (opv == OnParentVersionAction.VERSION) {
-                if (child.isNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
+                if (child.getEffectiveNodeType().includesNodeType(NameConstants.MIX_VERSIONABLE)) {
                     // create frozen versionable child
-                    NodeStateEx newChild = node.addNode(child.getQName(), NameConstants.NT_VERSIONEDCHILD, null, false);
+                    NodeId histId = child.getPropertyValue(NameConstants.JCR_VERSIONHISTORY).getNodeId();
+                    NodeStateEx newChild = node.addNode(child.getName(), NameConstants.NT_VERSIONEDCHILD, null, false);
                     newChild.setPropertyValue(
                             NameConstants.JCR_CHILDVERSIONHISTORY,
-                            InternalValue.create(new NodeId(child.getVersionHistory().getUUID())));
-                    /*
-                        newChild.setPropertyValue(JCR_BASEVERSION,
-                                InternalValue.create(child.getBaseVersion().getUUID()));
-                     */
+                            InternalValue.create(histId));
                 } else {
                     // else copy but do not recurse
-                    checkin(node, child.getQName(), child, MODE_COPY);
+                    checkin(node, child.getName(), child, Mode.COPY);
                 }
             } else if (opv == OnParentVersionAction.COPY) {
-                checkin(node, child.getQName(), child, MODE_COPY_RECURSIVE);
+                checkin(node, child.getName(), child, Mode.COPY_RECURSE);
             }
         }
         return node;



Mime
View raw message