You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2009/04/16 12:07:33 UTC

svn commit: r765556 [1/2] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/ jackrab...

Author: tripod
Date: Thu Apr 16 10:07:31 2009
New Revision: 765556

URL: http://svn.apache.org/viewvc?rev=765556&view=rev
Log:
JCR-1593 JSR 283: Simple versioning
JCR-2058 JSR 283: VersionManager and new versioning methods

Added:
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java   (with props)
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/AbstractVersionTest.java   (contents, props changed)
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/version/AbstractVersionTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/BasicTest.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/CheckinTest.java   (contents, props changed)
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/version/CheckinTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/CheckoutTest.java   (contents, props changed)
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/version/CheckoutTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/CopyTest.java   (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/FrozenNodeTest.java   (contents, props changed)
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/version/FrozenNodeTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/RestoreTest.java
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/version/RestoreTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/version/simple/TestAll.java
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/api/jsr283/TestAll.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/mix-shareable.txt   (with props)
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/mix-simpleVersionable.txt
      - copied, changed from r763147, jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/mix-versionable.txt
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/nt-activity.txt   (with props)
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/nt-configuration.txt   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.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/InternalFrozenNodeImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistory.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/VersionHistoryImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionIteratorImpl.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/VersionSelector.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
    jackrabbit/trunk/jackrabbit-core/src/main/resources-filtered/org/apache/jackrabbit/core/repository.properties
    jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/JackrabbitRepositoryStub.properties
    jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/version/VersionIteratorImplTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/AbstractJCRTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/nodetype/PredefinedNodeTypeTest.java
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/mix-versionable.txt
    jackrabbit/trunk/jackrabbit-jcr-tests/src/main/resources/org/apache/jackrabbit/test/api/nodetype/spec/nt-version.txt
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameConstants.java

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java?rev=765556&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java Thu Apr 16 10:07:31 2009
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.api.jsr283.version;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * A <code>Version</code> object wraps an <code>nt:version</code> node. It
+ * provides convenient access to version information.
+ */
+public interface Version extends javax.jcr.version.Version {
+
+    /**
+     * Assuming that this <code>Version</code> object was acquired through a <code>Workspace</code>
+     * <code>W</code> and is within the <code>VersionHistory</code> <code>H</code>,
+     * this method returns the successor of this version along the same line of descent
+     * as is returned by <code>H.getAllLinearVersions()</code> where <code>H</code>
+     * was also acquired through <code>W</code>.
+     * <p>
+     * Note that under simple versioing the behavior of this method is equivalent to
+     * getting the unique successor (if any) of this version.
+     *
+     * @see VersionHistory#getAllLinearVersions
+     * @return a <code>Version</code> or <code>null</code> if no linear successor exists.
+     * @throws RepositoryException if an error occurs.
+     */
+    public Version getLinearSuccessor() throws RepositoryException;
+
+    /**
+     * Assuming that this <code>Version</code> object was acquired through a <code>Workspace</code>
+     * <code>W</code> and is within the <code>VersionHistory</code> <code>H</code>,
+     * this method returns the predecessor of this version along the same line of descent
+     * as is returned by <code>H.getAllLinearVersions()</code> where <code>H</code>
+     * was also acquired through <code>W</code>.
+     * <p>
+     * Note that under simple versioning the behavior of this method is equivalent to
+     * getting the unique predecessor (if any) of this version.
+     *
+     * @see VersionHistory#getAllLinearVersions
+     * @return a <code>Version</code> or <code>null</code> if no linear predecessor exists.
+     * @throws RepositoryException if an error occurs.
+     */
+    public javax.jcr.version.Version getLinearPredecessor() throws RepositoryException;
+
+    /**
+     * Returns the frozen node of this version.
+     *
+     * @return a <code>Node</code> object
+     * @throws RepositoryException if an error occurs.
+     * @since JCR 2.0
+     */
+    public Node getFrozenNode() throws RepositoryException;
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/Version.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java?rev=765556&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java (added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java Thu Apr 16 10:07:31 2009
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.api.jsr283.version;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.VersionIterator;
+
+/**
+ * A <code>VersionHistory</code> object wraps an <code>nt:versionHistory</code>
+ * node. It provides convenient access to version history information.
+ */
+public interface VersionHistory extends javax.jcr.version.VersionHistory {
+
+    /**
+     * Returns the identifier of the versionable node for which this is the version history.
+     *
+     * @return the identifier of the versionable node for which this is the version history.
+     * @throws RepositoryException if an error occurs.
+     * @since JCR 2.0
+     */
+    public String getVersionableIdentifier() throws RepositoryException;
+
+    /**
+     * This method returns an iterator over all the versions in the <i>line of descent</i>
+     * from the root version to that base version within this history <i>that is bound to the
+     * workspace through which this <code>VersionHistory</code> was accessed</i>.
+     * <p>
+     * Within a version history <code>H</code>, <code>B</code> is the base version bound
+     * to workspace <code>W</code> if and only if there exists a versionable node <code>N</code>
+     * in <code>W</code> whose version history is <code>H</code> and <code>B</code> is the base
+     * version of <code>N</code>.
+     * <p>
+     * The <i>line of descent</i> from version <code>V1</code> to <code>V2</code>,
+     * where <code>V2</code> is a successor of <code>V1</code>, is the ordered list
+     * of versions starting with <code>V1</code> and proceeding through each direct successor to
+     * <code>V2</code>.
+     * <p>
+     * The versions are returned in order of creation date, from oldest to newest.
+     * <p>
+     * Note that in a simple versioning repository the behavior of this method is
+     * equivalent to returning all versions in the version history in order from
+     * oldest to newest.
+     *
+     * @return a <code>VersionIterator</code> object.
+     * @throws RepositoryException if an error occurs.
+     */
+    public VersionIterator getAllLinearVersions() throws RepositoryException;
+
+    /**
+     * This method returns all the frozen nodes of all the versions in this verison history
+     * in the same order as {@link #getAllLinearVersions}.
+     *
+     * @return a <code>NodeIterator</code> object.
+     * @throws RepositoryException if an error occurs.
+     * @since JCR 2.0
+     */
+    public NodeIterator getAllLinearFrozenNodes() throws RepositoryException;
+
+    /**
+     * Returns an iterator over all the frozen nodes of all the versions of
+     * this version history. Under simple versioning the order of the returned
+     * nodes will be the order of their creation. Under full versioning the
+     * order is implementation-dependent.
+     *
+     * @return a <code>NodeIterator</code> object.
+     * @throws RepositoryException if an error occurs.
+     * @since JCR 2.0
+     */
+    public NodeIterator getAllFrozenNodes() throws RepositoryException;
+
+
+}

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionHistory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionManager.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionManager.java (original)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/version/VersionManager.java Thu Apr 16 10:07:31 2009
@@ -26,9 +26,7 @@
 import javax.jcr.AccessDeniedException;
 import javax.jcr.NodeIterator;
 import javax.jcr.Node;
-import javax.jcr.version.Version;
 import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.lock.LockException;
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java Thu Apr 16 10:07:31 2009
@@ -1683,7 +1683,8 @@
             NodeId id;
             EffectiveNodeType ent = getEffectiveNodeType(srcState);
             boolean referenceable = ent.includesNodeType(NameConstants.MIX_REFERENCEABLE);
-            boolean versionable = ent.includesNodeType(NameConstants.MIX_VERSIONABLE);
+            boolean versionable = ent.includesNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE);
+            boolean fullVersionable = ent.includesNodeType(NameConstants.MIX_VERSIONABLE);
             boolean shareable = ent.includesNodeType(NameConstants.MIX_SHAREABLE);
             switch (flag) {
                 case COPY:
@@ -1844,24 +1845,34 @@
                      * adjusted accordingly.
                      */
                     VersionManager manager = session.getVersionManager();
-                    if (propName.equals(NameConstants.JCR_VERSIONHISTORY)) {
-                        // jcr:versionHistory
-                        VersionHistoryInfo history =
-                            manager.getVersionHistory(session, newState);
-                        InternalValue value = InternalValue.create(
-                                history.getVersionHistoryId().getUUID());
-                        newChildState.setValues(new InternalValue[] { value });
-                    } else if (propName.equals(NameConstants.JCR_BASEVERSION)
-                            || propName.equals(NameConstants.JCR_PREDECESSORS)) {
-                        // jcr:baseVersion or jcr:predecessors
-                        VersionHistoryInfo history =
+                    if (fullVersionable) {
+                        if (propName.equals(NameConstants.JCR_VERSIONHISTORY)) {
+                            // jcr:versionHistory
+                            VersionHistoryInfo history =
+                                manager.getVersionHistory(session, newState);
+                            InternalValue value = InternalValue.create(
+                                    history.getVersionHistoryId().getUUID());
+                            newChildState.setValues(new InternalValue[] { value });
+                        } else if (propName.equals(NameConstants.JCR_BASEVERSION)
+                                || propName.equals(NameConstants.JCR_PREDECESSORS)) {
+                            // jcr:baseVersion or jcr:predecessors
+                            VersionHistoryInfo history =
+                                manager.getVersionHistory(session, newState);
+                            InternalValue value = InternalValue.create(
+                                    history.getRootVersionId().getUUID());
+                            newChildState.setValues(new InternalValue[] { value });
+                        } else if (propName.equals(NameConstants.JCR_ISCHECKEDOUT)) {
+                            // jcr:isCheckedOut
+                            newChildState.setValues(new InternalValue[]{InternalValue.create(true)});
+                        }
+                    } else {
+                        // for simple versionable, we just initialize the
+                        // version history when we see the jcr:isCheckedOut
+                        if (propName.equals(NameConstants.JCR_ISCHECKEDOUT)) {
+                            // jcr:isCheckedOut
+                            newChildState.setValues(new InternalValue[]{InternalValue.create(true)});
                             manager.getVersionHistory(session, newState);
-                        InternalValue value = InternalValue.create(
-                                history.getRootVersionId().getUUID());
-                        newChildState.setValues(new InternalValue[] { value });
-                    } else if (propName.equals(NameConstants.JCR_ISCHECKEDOUT)) {
-                        // jcr:isCheckedOut
-                        newChildState.setValues(new InternalValue[]{InternalValue.create(true)});
+                        }
                     }
                 }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ItemImpl.java Thu Apr 16 10:07:31 2009
@@ -445,7 +445,8 @@
                 PropDef[] pda = ent.getMandatoryPropDefs();
                 for (int i = 0; i < pda.length; i++) {
                     PropDef pd = pda[i];
-                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)) {
+                    if (pd.getDeclaringNodeType().equals(NameConstants.MIX_VERSIONABLE)
+                            || pd.getDeclaringNodeType().equals(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                         /**
                          * todo FIXME workaround for mix:versionable:
                          * the mandatory properties are initialized at a
@@ -752,6 +753,21 @@
                                 new InternalValue[] { versionId });
                         createdTransientState = true;
                     }
+                } else if (nt.includesNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
+                    // we need to check the version manager for an existing
+                    // version history, since simple versioning does not
+                    // expose it's reference in a property
+                    VersionManager vMgr = session.getVersionManager();
+                    vMgr.getVersionHistory(session, nodeState);
+
+                    // create isCheckedOutProperty if not already exists
+                    NodeImpl node = (NodeImpl) itemMgr.getItem(itemState.getId());
+                    if (!nodeState.hasPropertyName(NameConstants.JCR_ISCHECKEDOUT)) {
+                        node.internalSetProperty(
+                                NameConstants.JCR_ISCHECKEDOUT,
+                                InternalValue.create(true));
+                        createdTransientState = true;
+                    }
                 }
             }
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Thu Apr 16 10:07:31 2009
@@ -44,6 +44,8 @@
 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.InternalVersionHistory;
+import org.apache.jackrabbit.core.version.InternalVersion;
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
@@ -56,6 +58,7 @@
 import org.apache.jackrabbit.uuid.UUID;
 import org.apache.jackrabbit.value.ValueHelper;
 import org.apache.jackrabbit.api.jsr283.InvalidLifecycleTransitionException;
+import org.apache.jackrabbit.api.jsr283.version.VersionManager;
 import org.apache.jackrabbit.api.jsr283.lock.LockManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1001,10 +1004,11 @@
         int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_VERSIONING |
                 ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
         int permissions = Permission.NODE_TYPE_MNGMT;
-        // special handling of mix:versionable. since adding the mixin alters
+        // special handling of mix:(simple)versionable. since adding the mixin alters
         // the version storage jcr:versionManagement privilege is required
         // in addition.
-        if (NameConstants.MIX_VERSIONABLE.equals(mixinName)) {
+        if (NameConstants.MIX_VERSIONABLE.equals(mixinName)
+                || NameConstants.MIX_SIMPLE_VERSIONABLE.equals(mixinName)) {
             permissions |= Permission.VERSION_MNGMT;
         }
         session.getValidator().checkModify(this, options, permissions);
@@ -2779,10 +2783,11 @@
         int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_VERSIONING |
                 ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
         int permissions = Permission.NODE_TYPE_MNGMT;
-        // special handling of mix:versionable. since adding the mixin alters
+        // special handling of mix:(simple)versionable. since adding the mixin alters
         // the version storage jcr:versionManagement privilege is required
         // in addition.
-        if (NameConstants.MIX_VERSIONABLE.equals(ntName)) {
+        if (NameConstants.MIX_VERSIONABLE.equals(ntName)
+                || NameConstants.MIX_SIMPLE_VERSIONABLE.equals(mixinName)) {
             permissions |= Permission.VERSION_MNGMT;
         }
         if (!session.getValidator().canModify(this, options, permissions)) {
@@ -3222,7 +3227,7 @@
         sanityCheck();
 
         // check if versionable
-        checkVersionable();
+        boolean isFull = checkVersionable();
 
         // check if checked out
         if (!internalIsCheckedOut()) {
@@ -3239,8 +3244,10 @@
         boolean success = false;
         try {
             internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
-            internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(new UUID(v.getUUID())));
-            internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
+            if (isFull) {
+                internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(new UUID(v.getUUID())));
+                internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
+            }
             save();
             success = true;
         } finally {
@@ -3267,7 +3274,7 @@
         sanityCheck();
 
         // check if versionable
-        checkVersionable();
+        boolean isFull = checkVersionable();
 
         // check checked-out status
         if (internalIsCheckedOut()) {
@@ -3284,13 +3291,17 @@
         boolean success = false;
         try {
             props[0] = internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(true));
-            props[1] = internalSetProperty(NameConstants.JCR_PREDECESSORS,
-                    new InternalValue[]{
-                            InternalValue.create(new UUID(getBaseVersion().getUUID()))
-                    });
+            if (isFull) {
+                props[1] = internalSetProperty(NameConstants.JCR_PREDECESSORS,
+                        new InternalValue[]{
+                                InternalValue.create(new UUID(getBaseVersion().getUUID()))
+                        });
+            }
             if (hasPendingChanges) {
                 for (int i = 0; i < props.length; i++) {
-                    props[i].save();
+                    if (props[i] != null) {
+                        props[i].save();
+                    }
                 }
             } else {
                 save();
@@ -3317,7 +3328,7 @@
     public void update(String srcWorkspaceName)
             throws NoSuchWorkspaceException, AccessDeniedException,
             LockException, InvalidItemStateException, RepositoryException {
-        internalMerge(srcWorkspaceName, null, false);
+        internalMerge(srcWorkspaceName, null, false, false);
     }
 
     /**
@@ -3327,9 +3338,19 @@
             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 failedIds = new ArrayList();
-        internalMerge(srcWorkspace, failedIds, bestEffort);
+        internalMerge(srcWorkspace, failedIds, bestEffort, isShallow);
 
         return new LazyItemIterator(itemMgr, failedIds);
     }
@@ -3421,7 +3442,7 @@
             NodeImpl node;
             try {
                 // check if versionable node exists
-                InternalFrozenNode fn = ((VersionImpl) version).getFrozenNode();
+                InternalFrozenNode fn = ((VersionImpl) version).getInternalFrozenNode();
                 node = (NodeImpl) session.getNodeByUUID(fn.getFrozenUUID());
                 if (removeExisting) {
                     try {
@@ -3441,7 +3462,7 @@
                 }
             } catch (ItemNotFoundException e) {
                 // not found, create new one
-                node = addNode(relPath, ((VersionImpl) version).getFrozenNode());
+                node = addNode(relPath, ((VersionImpl) version).getInternalFrozenNode());
             }
 
             // recreate node from frozen state
@@ -3479,13 +3500,16 @@
         // check state of this instance
         sanityCheck();
 
-        checkVersionable();
-
-        // transactions workaround.
-        NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_VERSIONHISTORY).getString());
-        session.getVersionManager().getVersionHistory(id);
+        boolean isFull = checkVersionable();
 
-        return (VersionHistory) getProperty(NameConstants.JCR_VERSIONHISTORY).getNode();
+        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());
     }
 
     /**
@@ -3496,28 +3520,39 @@
         // check state of this instance
         sanityCheck();
 
-        checkVersionable();
+        boolean isFull = checkVersionable();
 
-        // transactions workaround.
-        NodeId id = NodeId.valueOf(getProperty(NameConstants.JCR_BASEVERSION).getString());
-        session.getVersionManager().getVersion(id);
+        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) getProperty(NameConstants.JCR_BASEVERSION).getNode();
+        return (Version) session.getNodeById(v.getId());
     }
 
     //-----------------------------------< versioning support: implementation >
     /**
-     * Checks if this node is versionable, i.e. has 'mix:versionable'.
-     *
+     * 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
+     *          if this node is not versionable at all
      */
-    private void checkVersionable()
+    private boolean checkVersionable()
             throws UnsupportedRepositoryOperationException, RepositoryException {
-        if (!isNodeType(NameConstants.MIX_VERSIONABLE)) {
-            String msg =
-                "Unable to perform a versioning operation on"
-                + " a non versionable node: " + this;
+        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);
         }
@@ -3927,7 +3962,8 @@
      * @throws RepositoryException
      */
     private void internalMerge(String srcWorkspaceName,
-                               List failedIds, boolean bestEffort)
+                               List failedIds, boolean bestEffort,
+                               boolean shallow)
             throws NoSuchWorkspaceException, AccessDeniedException,
             LockException, InvalidItemStateException, RepositoryException {
 
@@ -3950,7 +3986,7 @@
             // 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);
+            internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
             session.save();
             success = true;
         } finally {
@@ -3980,9 +4016,14 @@
      * @throws RepositoryException
      */
     private void internalMerge(SessionImpl srcSession, List failedIds,
-                               boolean bestEffort, boolean removeExisting, boolean replaceExisting)
+                               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
@@ -3991,7 +4032,7 @@
             while (iter.hasNext()) {
                 NodeImpl n = (NodeImpl) iter.nextNode();
                 if (n.isNodeType(NameConstants.MIX_VERSIONABLE)) {
-                    n.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting);
+                    n.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
                 }
             }
             return;
@@ -4088,9 +4129,9 @@
                 for (int i = 0; i < mixins.length; i++) {
                     dstNode.addMixin(mixins[i].getName());
                 }
-                dstNode.internalMerge(srcSession, null, bestEffort, removeExisting, replaceExisting);
+                dstNode.internalMerge(srcSession, null, bestEffort, removeExisting, replaceExisting, shallow);
             } else {
-                dstNode.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting);
+                dstNode.internalMerge(srcSession, failedIds, bestEffort, removeExisting, replaceExisting, shallow);
             }
         }
     }
@@ -4144,6 +4185,8 @@
             throw new VersionException("Restore of root version not allowed.");
         }
 
+        boolean isFull = checkVersionable();
+
         // check permission
         session.getAccessManager().checkPermission(getPrimaryPath(), Permission.VERSION_MNGMT);
 
@@ -4154,19 +4197,25 @@
         //    added to, depending on their corresponding copies in V and their
         //    own OnParentVersion attributes (see 7.2.8, below, for details).
         HashSet restored = new HashSet();
-        restoreFrozenState(version.getFrozenNode(), vsel, restored, removeExisting);
+        restoreFrozenState(version.getInternalFrozenNode(), vsel, restored, removeExisting);
         restored.add(version);
 
-        // 2. N's jcr:baseVersion property will be changed to point to V.
-        UUID uuid = ((NodeId) version.getId()).getUUID();
-        internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(uuid));
+        if (isFull) {
+            // 2. N's jcr:baseVersion property will be changed to point to V.
+            UUID uuid = ((NodeId) version.getId()).getUUID();
+            internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(uuid));
 
-        // 4. N's jcr:predecessor property is set to null
-        internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
+            // 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);
+            // 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));
 
@@ -4341,7 +4390,7 @@
                         }
                         v = (VersionImpl) vs[0];
                     }
-                    restoredChild = addNode(child.getName(), v.getFrozenNode());
+                    restoredChild = addNode(child.getName(), v.getInternalFrozenNode());
                 } else {
                     restoredChild = session.getNodeById(nodeId);
                     if (v == null || oldVersion == null || v.getName().equals(oldVersion)) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java Thu Apr 16 10:07:31 2009
@@ -33,6 +33,7 @@
 import org.apache.jackrabbit.core.version.DateVersionSelector;
 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.core.xml.ImportHandler;
 import org.apache.jackrabbit.core.xml.Importer;
 import org.apache.jackrabbit.core.xml.WorkspaceImporter;
@@ -129,6 +130,11 @@
     private org.apache.jackrabbit.api.jsr283.lock.LockManager jcr283LockManager;
 
     /**
+     * The API Version manager for this workspace
+     */
+    protected JcrVersionManagerImpl versionMgr;
+
+    /**
      * The internal manager used to evaluate effective retention policies and
      * holds.
      */
@@ -294,8 +300,12 @@
     /**
      * @see org.apache.jackrabbit.api.jsr283.Workspace#getVersionManager()
      */
-    public VersionManager getVersionManager() throws UnsupportedRepositoryOperationException, RepositoryException {
-        throw new UnsupportedRepositoryOperationException("not yet implemented");
+    public VersionManager getVersionManager()
+            throws UnsupportedRepositoryOperationException, RepositoryException {
+        if (versionMgr == null) {
+            versionMgr = new JcrVersionManagerImpl(session);
+        }
+        return versionMgr;
     }
 
     //-------------------------------< JackrabbitWorkspace/new JSR 283 method >
@@ -908,7 +918,7 @@
                 while (iter.hasNext()) {
                     VersionImpl v = (VersionImpl) iter.next();
                     try {
-                        NodeImpl node = (NodeImpl) session.getNodeByUUID(v.getFrozenNode().getFrozenUUID());
+                        NodeImpl node = (NodeImpl) session.getNodeByUUID(v.getInternalFrozenNode().getFrozenUUID());
                         restored = node.internalRestore(v, vsel, removeExisting);
                         // remove restored versions from set
                         for (int i = 0; i < restored.length; i++) {

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=765556&r1=765555&r2=765556&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 Thu Apr 16 10:07:31 2009
@@ -34,6 +34,7 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.Value;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.version.VersionException;
 
 /**
@@ -96,6 +97,42 @@
         return (InternalVersionHistory) getItem(id);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionHistory getVersionHistoryOfNode(NodeId id)
+            throws RepositoryException {
+        ReadLock lock = acquireReadLock();
+        try {
+            String uuid = id.getUUID().toString();
+            Name name = getName(uuid);
+
+            NodeStateEx parent = getParentNode(uuid, false);
+            if (parent != null && parent.hasNode(name)) {
+                NodeStateEx history = parent.getNode(name, 1);
+                return getVersionHistory(history.getNodeId());
+            } else {
+                throw new ItemNotFoundException("Version history of node " + id + " not found.");
+            }
+        } finally {
+            lock.release();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Assumes that all versions are stored chronologically below the version
+     * history and just returns the last one. i.e. currently only works for
+     * simple versioning.
+     */
+    public InternalVersion getHeadVersionOfNode(NodeId id) throws RepositoryException {
+        InternalVersionHistory vh = getVersionHistoryOfNode(id);
+        Name[] names = vh.getVersionNames();
+        InternalVersion last = vh.getVersion(names[names.length - 1]);
+        return getVersion(last.getId());
+    }
+
     //-------------------------------------------------------< implementation >
 
     /**
@@ -237,7 +274,6 @@
         return info;
     }
 
-
     /**
      * Creates a new version history. This action is needed either when creating
      * a new 'mix:versionable' node or when adding the 'mix:versionable' mixin
@@ -374,15 +410,17 @@
      *
      * @param history the version history
      * @param node node to checkin
+     * @param simple flag indicates simple versioning
      * @return internal version
      * @throws javax.jcr.RepositoryException if an error occurs
      * @see javax.jcr.Node#checkin()
      */
-    protected InternalVersion checkin(InternalVersionHistoryImpl history, NodeImpl node)
+    protected InternalVersion checkin(InternalVersionHistoryImpl history,
+                                      NodeImpl node, boolean simple)
             throws RepositoryException {
         WriteOperation operation = startWriteOperation();
         try {
-            String versionName = calculateCheckinVersionName(history, node);
+            String versionName = calculateCheckinVersionName(history, node, simple);
             InternalVersionImpl v = history.checkin(NameFactoryImpl.getInstance().create("", versionName), node);
             operation.save();
             return v;
@@ -431,20 +469,27 @@
      *
      * @param history the version history
      * @param node the node to checkin
+     * @param simple if <code>true</code> indicates simple versioning
      * @return the new version name
      * @throws RepositoryException if an error occurs.
      */
     protected String calculateCheckinVersionName(InternalVersionHistoryImpl history,
-                                                 NodeImpl node)
+                                                 NodeImpl node, boolean simple)
             throws RepositoryException {
-        // 1. search a predecessor, suitable for generating the new name
-        Value[] values = node.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
         InternalVersion best = null;
-        for (int i = 0; i < values.length; i++) {
-            InternalVersion pred = history.getVersion(NodeId.valueOf(values[i].getString()));
-            if (best == null
-                    || pred.getName().getLocalName().length() < best.getName().getLocalName().length()) {
-                best = pred;
+        if (simple) {
+            // 1. in simple versioning just take the 'head' version
+            Name[] names = history.getVersionNames();
+            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 (int i = 0; i < values.length; i++) {
+                InternalVersion pred = history.getVersion(NodeId.valueOf(values[i].getString()));
+                if (best == null
+                        || pred.getName().getLocalName().length() < best.getName().getLocalName().length()) {
+                    best = pred;
+                }
             }
         }
         // 2. generate version name (assume no namespaces in version names)

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java?rev=765556&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java Thu Apr 16 10:07:31 2009
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.version;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.version.VersionIterator;
+
+import org.apache.jackrabbit.api.jsr283.version.Version;
+import org.apache.jackrabbit.commons.iterator.RangeIteratorAdapter;
+
+/**
+ * Implements a node iterator that takes a version iterator and returns the
+ * frozen nodes of the underlying versions.
+ */
+public class FrozenNodeIteratorAdapter extends RangeIteratorAdapter implements NodeIterator {
+
+    public FrozenNodeIteratorAdapter(VersionIterator iterator) {
+        super(iterator);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return the next frozen node.
+     */
+    public Node nextNode() {
+        try {
+            return ((Version) next()).getFrozenNode();
+        } catch (RepositoryException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/FrozenNodeIteratorAdapter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java Thu Apr 16 10:07:31 2009
@@ -332,7 +332,7 @@
             if (opv == OnParentVersionAction.ABORT) {
                 throw new VersionException("Checkin aborted due to OPV in " + child);
             } else if (opv == OnParentVersionAction.VERSION) {
-                if (child.isNodeType(NameConstants.MIX_VERSIONABLE)) {
+                if (child.isNodeType(NameConstants.MIX_SIMPLE_VERSIONABLE)) {
                     // create frozen versionable child
                     NodeStateEx newChild = node.addNode(child.getQName(), NameConstants.NT_VERSIONEDCHILD, null, false);
                     newChild.setPropertyValue(NameConstants.JCR_CHILDVERSIONHISTORY,

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java Thu Apr 16 10:07:31 2009
@@ -18,6 +18,7 @@
 
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.api.jsr283.version.Version;
 
 import java.util.Calendar;
 
@@ -52,6 +53,7 @@
      * Equivalent to {@link javax.jcr.version.Version#getCreated()}
      *
      * @see javax.jcr.version.Version#getCreated()
+     * @return the created date
      */
     Calendar getCreated();
 
@@ -59,17 +61,37 @@
      * Equivalent to {@link javax.jcr.version.Version#getSuccessors()}}
      *
      * @see javax.jcr.version.Version#getSuccessors()
+     * @return the successors as internal versions
      */
     InternalVersion[] getSuccessors();
 
     /**
+     * Equivalent to {@link Version#getLinearSuccessor()}.
+     *
+     * @param baseVersion base version to determine single line of descent
+     * @return the successor as internal version
+     *
+     * @see Version#getLinearSuccessor()
+     */
+    InternalVersion getLinearSuccessor(InternalVersion baseVersion);
+
+    /**
      * Equivalent to {@link javax.jcr.version.Version#getPredecessors()}}
      *
      * @see javax.jcr.version.Version#getPredecessors()
+     * @return the predecessors as internal versions
      */
     InternalVersion[] getPredecessors();
 
     /**
+     * Equivalent to {@link Version#getLinearPredecessor()}
+     *
+     * @see Version#getLinearPredecessor()
+     * @return the predecessor as internal version
+     */
+    InternalVersion getLinearPredecessor();
+
+    /**
      * Checks if this version is more recent than the given version <code>v</code>.
      * A version is more recent if and only if it is a successor (or a successor
      * of a successor, etc., to any degree of separation) of the compared one.

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java Thu Apr 16 10:07:31 2009
@@ -30,13 +30,17 @@
     /**
      * Equivalalent to {@link javax.jcr.version.VersionHistory#getRootVersion()}.
      *
+     * @return the root version
      * @see javax.jcr.version.VersionHistory#getRootVersion()
      */
     InternalVersion getRootVersion();
 
     /**
-     * Equivalalent to {@link javax.jcr.version.VersionHistory#getVersion(java.lang.String)}.
+     * Equivalent to {@link javax.jcr.version.VersionHistory#getVersion(java.lang.String)}.
      *
+     * @param versionName the name of the version
+     * @return the version
+     * @throws VersionException if the version does not exist
      * @see javax.jcr.version.VersionHistory#getVersion(java.lang.String)
      */
     InternalVersion getVersion(Name versionName) throws VersionException;
@@ -63,7 +67,9 @@
      * Equivalalent to {@link javax.jcr.version.VersionHistory#getVersionByLabel(java.lang.String)}
      * but returns <code>null</code> if the version does not exists.
      *
+     * @param label the lable
      * @see javax.jcr.version.VersionHistory#getVersionByLabel(java.lang.String)
+     * @return the version or <code>null</code> if not exists
      */
     InternalVersion getVersionByLabel(Name label);
 
@@ -82,7 +88,7 @@
     UUID getVersionableUUID();
 
     /**
-     * Returns a string  iterator over all version labels that exist in this
+     * Returns a name array of all version labels that exist in this
      * version history
      *
      * @return the labels
@@ -90,6 +96,12 @@
     Name[] getVersionLabels();
 
     /**
+     * Returns a name array of all version names that exist in this version history.
+     * @return the names
+     */
+    Name[] getVersionNames();
+
+    /**
      * Returns the Id of the version labels node.
      *
      * @return the id of the version labels node.

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=765556&r1=765555&r2=765556&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 Thu Apr 16 10:07:31 2009
@@ -38,6 +38,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Set;
+import java.util.LinkedHashMap;
 
 /**
  * Implements a <code>InternalVersionHistory</code>
@@ -72,19 +73,19 @@
      * key = version name
      * value = version id (NodeId)
      */
-    private HashMap nameCache = new HashMap();
+    private LinkedHashMap/*<Name, NodeId>*/ nameCache = new LinkedHashMap/*<Name, NodeId>*/();
 
     /**
      * the hashmap of all versions
      * key = version id (NodeId)
      * value = version
      */
-    private HashMap versionCache = new HashMap();
+    private HashMap/*<NodeId, InternalVersion>*/ versionCache = new HashMap/*<NodeId, InternalVersion>*/();
 
     /**
      * Temporary version cache, used on a refresh.
      */
-    private HashMap tempVersionCache = new HashMap();
+    private HashMap/*<NodeId, InternalVersion>*/ tempVersionCache = new HashMap/*<NodeId, InternalVersion>*/();
 
     /**
      * the node that holds the label nodes
@@ -103,6 +104,9 @@
 
     /**
      * Creates a new VersionHistory object for the given node state.
+     * @param vMgr version manager
+     * @param node version history node state
+     * @throws RepositoryException if an error occurs
      */
     public InternalVersionHistoryImpl(AbstractVersionManager vMgr, NodeStateEx node)
             throws RepositoryException {
@@ -113,7 +117,7 @@
     /**
      * Initialies the history and loads all internal caches
      *
-     * @throws RepositoryException
+     * @throws RepositoryException if an error occurs
      */
     private void init() throws RepositoryException {
         nameCache.clear();
@@ -176,6 +180,7 @@
 
     /**
      * Reload this object and all its dependent version objects.
+     * @throws RepositoryException if an error occurs
      */
     void reload() throws RepositoryException {
         tempVersionCache.putAll(versionCache);
@@ -193,6 +198,9 @@
 
     /**
      * Create a version instance.
+     * @param name name of the version
+     * @return the new internal version
+     * @throws IllegalArgumentException if the version does not exist
      */
     InternalVersionImpl createVersionInstance(Name name) {
         try {
@@ -219,6 +227,8 @@
     /**
      * Create a version instance. May resurrect versions temporarily swapped
      * out when refreshing this history.
+     * @param child child node state
+     * @return new version instance
      */
     InternalVersionImpl createVersionInstance(NodeStateEx child) {
         InternalVersionImpl v = (InternalVersionImpl) tempVersionCache.remove(child.getNodeId());
@@ -312,6 +322,13 @@
     /**
      * {@inheritDoc}
      */
+    public Name[] getVersionNames() {
+        return (Name[]) nameCache.keySet().toArray(new Name[nameCache.size()]);
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
     public int getNumVersions() {
         return nameCache.size();
     }
@@ -346,8 +363,8 @@
      * predecessors of the removed version and vice versa. then, the entire
      * version node and all its subnodes are removed.
      *
-     * @param versionName
-     * @throws VersionException
+     * @param versionName name of the version to remove
+     * @throws VersionException if removal is not possible
      */
     void removeVersion(Name versionName) throws RepositoryException {
 
@@ -371,7 +388,7 @@
         // detach from the version graph
         v.internalDetach();
 
-        // remove from persistance state
+        // remove from persistence state
         node.removeNode(v.getName());
 
         // and remove from history
@@ -400,7 +417,7 @@
      * @param label the label to assgign
      * @param move  flag what to do by collisions
      * @return the version that was previously assigned by this label or <code>null</code>.
-     * @throws VersionException
+     * @throws VersionException if the version does not exist or if the label is already defined.
      */
     InternalVersion setVersionLabel(Name versionName, Name label, boolean move)
             throws VersionException {
@@ -453,24 +470,40 @@
      * Checks in a node. It creates a new version with the given name and freezes
      * the state of the given node.
      *
-     * @param name
-     * @param src
-     * @return
-     * @throws RepositoryException
+     * @param name new version name
+     * @param src source node to version
+     * @return the newly created version
+     * @throws RepositoryException if an error occurs
      */
     InternalVersionImpl checkin(Name name, NodeImpl src)
             throws RepositoryException {
 
         // copy predecessors from src node
-        Value[] preds = src.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
-        InternalValue[] predecessors = new InternalValue[preds.length];
-        for (int i = 0; i < preds.length; i++) {
-            UUID predId = UUID.fromString(preds[i].getString());
-            // check if version exist
-            if (!nameCache.containsValue(new NodeId(predId))) {
-                throw new RepositoryException("invalid predecessor in source node");
+        InternalValue[] predecessors;
+        if (src.hasProperty(NameConstants.JCR_PREDECESSORS)) {
+            Value[] preds = src.getProperty(NameConstants.JCR_PREDECESSORS).getValues();
+            predecessors = new InternalValue[preds.length];
+            for (int i = 0; i < preds.length; i++) {
+                UUID predId = UUID.fromString(preds[i].getString());
+                // check if version exist
+                if (!nameCache.containsValue(new NodeId(predId))) {
+                    throw new RepositoryException("invalid predecessor in source node");
+                }
+                predecessors[i] = InternalValue.create(predId);
+            }
+        } else {
+            // with simple versioning, the node does not contain a predecessors
+            // property and we just use the 'head' version as predecessor
+            Iterator iter = nameCache.values().iterator();
+            NodeId last = null;
+            while (iter.hasNext()) {
+                last = (NodeId) iter.next();
+            }
+            if (last == null) {
+                // should never happen
+                last = rootVersion.getId();
             }
-            predecessors[i] = InternalValue.create(predId);
+            predecessors = new InternalValue[]{InternalValue.create(last.getUUID())};
         }
 
         NodeId versionId = new NodeId(UUID.randomUUID());
@@ -504,10 +537,12 @@
      * Creates a new version history below the given parent node and with
      * the given name.
      *
-     * @param parent
-     * @param name
-     * @return
-     * @throws RepositoryException
+     * @param vMgr version manager
+     * @param parent parent node
+     * @param name history name
+     * @param nodeState node state
+     * @return new node state
+     * @throws RepositoryException if an error occurs
      */
     static NodeStateEx create(
             AbstractVersionManager vMgr, NodeStateEx parent, Name name,

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=765556&r1=765555&r2=765556&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 Thu Apr 16 10:07:31 2009
@@ -67,7 +67,9 @@
      * persistance node. please note, that versions must be created by the
      * version history.
      *
-     * @param node
+     * @param vh containing version history
+     * @param node node state of this version
+     * @param name name of this version
      */
     public InternalVersionImpl(InternalVersionHistoryImpl vh, NodeStateEx node, Name name) {
         super(vh.getVersionManager(), node);
@@ -158,6 +160,20 @@
     /**
      * {@inheritDoc}
      */
+    public InternalVersion getLinearSuccessor(InternalVersion baseVersion) {
+        // walk up all predecessors of the base version until 'this' version
+        // is found.
+        InternalVersion pred = baseVersion.getLinearPredecessor();
+        while (pred != null && !pred.getId().equals(getId())) {
+            baseVersion = pred;
+            pred = baseVersion.getLinearPredecessor();
+        }
+        return pred == null ? null : baseVersion;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public InternalVersion[] getPredecessors() {
         InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);
         if (values != null) {
@@ -174,6 +190,21 @@
 
     /**
      * {@inheritDoc}
+     *
+     * Always return the left most predecessor
+     */
+    public InternalVersion getLinearPredecessor() {
+        InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);
+        if (values != null && values.length > 0) {
+            NodeId vId = new NodeId(values[0].getUUID());
+            return versionHistory.getVersion(vId);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
      */
     public boolean isMoreRecent(InternalVersion v) {
         InternalVersion[] preds = getPredecessors();
@@ -224,9 +255,12 @@
     /**
      * stores the given successors or predecessors to the persistance node
      *
-     * @throws RepositoryException
+     * @param cessors list of versions to store
+     * @param propname property name to store
+     * @param store if <code>true</code> the node is stored
+     * @throws RepositoryException if a repository error occurs
      */
-    private void storeXCessors(List cessors, Name propname, boolean store)
+    private void storeXCessors(List/*<InternalVersion>*/ cessors, Name propname, boolean store)
             throws RepositoryException {
         InternalValue[] values = new InternalValue[cessors.size()];
         for (int i = 0; i < values.length; i++) {
@@ -242,7 +276,7 @@
     /**
      * Detaches itself from the version graph.
      *
-     * @throws RepositoryException
+     * @throws RepositoryException if a repository error occurs
      */
     void internalDetach() throws RepositoryException {
         // detach this from all successors
@@ -251,7 +285,7 @@
             ((InternalVersionImpl) succ[i]).internalDetachPredecessor(this, true);
         }
 
-        // detach cached successors from preds
+        // detach cached successors from predecessors
         InternalVersion[] preds = getPredecessors();
         for (int i = 0; i < preds.length; i++) {
             ((InternalVersionImpl) preds[i]).internalDetachSuccessor(this, true);
@@ -265,7 +299,7 @@
      * Attaches this version as successor to all predecessors. assuming that the
      * predecessors are already set.
      *
-     * @throws RepositoryException
+     * @throws RepositoryException if a repository error occurs
      */
     void internalAttach() throws RepositoryException {
         InternalVersion[] preds = getPredecessors();
@@ -277,9 +311,9 @@
     /**
      * Adds a version to the set of successors.
      *
-     * @param succ
-     * @param store
-     * @throws RepositoryException
+     * @param succ successor
+     * @param store <code>true</code> if node is stored
+     * @throws RepositoryException if a repository error occurs
      */
     private void internalAddSuccessor(InternalVersionImpl succ, boolean store)
             throws RepositoryException {
@@ -297,6 +331,8 @@
      * please note, that this operation might corrupt the version graph
      *
      * @param v the successor to detach
+     * @param store <code>true</code> if node is stored immediately
+     * @throws RepositoryException if a repository error occurs
      */
     private void internalDetachPredecessor(InternalVersionImpl v, boolean store)
             throws RepositoryException {
@@ -304,7 +340,7 @@
         List l = new ArrayList(Arrays.asList(getPredecessors()));
         l.remove(v);
 
-        // attach v's predecessors
+        // attach V's predecessors
         l.addAll(Arrays.asList(v.getPredecessors()));
         storeXCessors(l, NameConstants.JCR_PREDECESSORS, store);
     }
@@ -316,6 +352,8 @@
      * please note, that this operation might corrupt the version graph
      *
      * @param v the successor to detach
+     * @param store <code>true</code> if node is stored immediately
+     * @throws RepositoryException if a repository error occurs
      */
     private void internalDetachSuccessor(InternalVersionImpl v, boolean store)
             throws RepositoryException {
@@ -323,7 +361,7 @@
         List l = new ArrayList(Arrays.asList(getSuccessors()));
         l.remove(v);
 
-        // attach v's successors
+        // attach V's successors
         l.addAll(Arrays.asList(v.getSuccessors()));
         storeXCessors(l, NameConstants.JCR_SUCCESSORS, store);
     }
@@ -331,7 +369,7 @@
     /**
      * adds a label to the label cache. does not affect storage
      *
-     * @param label
+     * @param label label to add
      * @return <code>true</code> if the label was added
      */
     boolean internalAddLabel(Name label) {
@@ -344,29 +382,21 @@
     /**
      * removes a label from the label cache. does not affect storage
      *
-     * @param label
+     * @param label label to remove
      * @return <code>true</code> if the label was removed
      */
     boolean internalRemoveLabel(Name label) {
-        if (labelCache == null) {
-            return false;
-        } else {
-            return labelCache.remove(label);
-        }
+        return labelCache != null && labelCache.remove(label);
     }
 
     /**
      * checks, if a label is in the label cache
      *
-     * @param label
+     * @param label label to check
      * @return <code>true</code> if the label exists
      */
     boolean internalHasLabel(Name label) {
-        if (labelCache == null) {
-            return false;
-        } else {
-            return labelCache.contains(label);
-        }
+        return labelCache != null && labelCache.contains(label);
     }
 
     /**
@@ -392,7 +422,7 @@
     /**
      * Resolves jcr:successor properties that are missing.
      *
-     * @throws RepositoryException
+     * @throws RepositoryException if a repository error occurs
      */
     void legacyResolveSuccessors() throws RepositoryException {
         InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java?rev=765556&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java Thu Apr 16 10:07:31 2009
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.version;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.PropertyType;
+import javax.jcr.lock.LockException;
+import javax.jcr.version.VersionException;
+
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.ItemValidator;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.api.jsr283.version.Version;
+import org.apache.jackrabbit.api.jsr283.version.VersionHistory;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.uuid.UUID;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+/**
+ * Implementation of the {@link org.apache.jackrabbit.api.jsr283.version.VersionManager}.
+ * <p/>
+ * 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 implements org.apache.jackrabbit.api.jsr283.version.VersionManager {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(JcrVersionManagerImpl.class);
+
+    /**
+     * workspace session
+     */
+    private final SessionImpl session;
+
+    /**
+     * Creates a new version manager for the given session
+     * @param session workspace sesion
+     */
+    public JcrVersionManagerImpl(SessionImpl session) {
+        this.session = session;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Version checkin(String absPath) throws RepositoryException {
+        return (Version) session.getNode(absPath).checkin();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void checkout(String absPath) throws RepositoryException {
+        session.getNode(absPath).checkout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Version checkpoint(String absPath) throws RepositoryException {
+        // this is not quite correct, since the entire checkpoint operation
+        // should be atomic
+        Node node = session.getNode(absPath);
+        Version v = (Version) node.checkin();
+        node.checkout();
+        return v;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isCheckedOut(String absPath) throws RepositoryException {
+        return session.getNode(absPath).isCheckedOut();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public VersionHistory getVersionHistory(String absPath)
+            throws RepositoryException {
+        return (VersionHistory) session.getNode(absPath).getVersionHistory();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Version getBaseVersion(String absPath)
+            throws RepositoryException {
+        return (Version) session.getNode(absPath).getBaseVersion();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(Version[] versions, boolean removeExisting)
+            throws RepositoryException {
+        session.getWorkspace().restore(versions, removeExisting);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(String absPath, String versionName,
+                        boolean removeExisting)
+            throws RepositoryException {
+        session.getNode(absPath).restore(versionName, removeExisting);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(Version version, boolean removeExisting)
+            throws RepositoryException {
+        session.getWorkspace().restore(new Version[]{version}, removeExisting);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restore(String absPath, Version version, boolean removeExisting)
+            throws RepositoryException {
+        session.getNode(absPath).restore(version, removeExisting);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void restoreByLabel(String absPath, String versionLabel,
+                               boolean removeExisting)
+            throws RepositoryException {
+        session.getNode(absPath).restoreByLabel(versionLabel, removeExisting);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeIterator merge(String absPath, String srcWorkspace,
+                              boolean bestEffort)
+            throws RepositoryException {
+        return ((NodeImpl) session.getNode(absPath))
+                .merge(srcWorkspace, bestEffort, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeIterator merge(String absPath, String srcWorkspace,
+                              boolean bestEffort, boolean isShallow)
+            throws RepositoryException {
+        return ((NodeImpl) session.getNode(absPath))
+                .merge(srcWorkspace, bestEffort, isShallow);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void doneMerge(String absPath, Version version)
+            throws RepositoryException {
+        session.getNode(absPath).doneMerge(version);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void cancelMerge(String absPath, Version version)
+            throws RepositoryException {
+        session.getNode(absPath).cancelMerge(version);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node createConfiguration(String absPath, Version baseline)
+            throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node setActivity(Node activity) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node getActivity() throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node createActivity(String title) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Node removeActivity(String title) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public NodeIterator merge(Node activityNode) throws RepositoryException {
+        throw new UnsupportedRepositoryOperationException("comming soon...");
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java?rev=765556&r1=765555&r2=765556&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java Thu Apr 16 10:07:31 2009
@@ -24,6 +24,8 @@
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.conversion.NameException;
+import org.apache.jackrabbit.api.jsr283.version.VersionHistory;
+import org.apache.jackrabbit.api.jsr283.version.Version;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,10 +35,10 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.UnsupportedRepositoryOperationException;
 import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
+import javax.jcr.AccessDeniedException;
 import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.version.Version;
 import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
 import javax.jcr.version.VersionIterator;
 
 /**
@@ -53,7 +55,7 @@
      * Create a new instance of this class.
      * @param itemMgr item manager
      * @param session session
-     * @param data
+     * @param data node data
      */
     public VersionHistoryImpl(ItemManager itemMgr, SessionImpl session, AbstractNodeData data) {
         super(itemMgr, session, data);
@@ -78,7 +80,7 @@
     /**
      * @see javax.jcr.version.VersionHistory#getRootVersion()
      */
-    public Version getRootVersion() throws RepositoryException {
+    public javax.jcr.version.Version getRootVersion() throws RepositoryException {
         return (Version) session.getNodeById(
                 getInternalVersionHistory().getRootVersion().getId());
     }
@@ -92,9 +94,36 @@
     }
 
     /**
+     * @see VersionHistory#getAllFrozenNodes()
+     */
+    public NodeIterator getAllFrozenNodes() throws RepositoryException {
+        return new FrozenNodeIteratorAdapter(getAllVersions());
+    }
+
+    /**
+     * @see VersionHistory#getAllLinearVersions()
+     */
+    public VersionIterator getAllLinearVersions() throws RepositoryException {
+        // get base version. this can certainly be optimized
+        InternalVersionHistory vh = getInternalVersionHistory();
+        NodeId id = new NodeId(vh.getVersionableUUID());
+        Node vn = session.getNodeById(id);
+        InternalVersion base = ((VersionImpl) vn.getBaseVersion()).getInternalVersion();
+
+        return new VersionIteratorImpl(session, vh.getRootVersion(), base);
+    }
+
+    /**
+     * @see VersionHistory#getAllLinearFrozenNodes()
+     */
+    public NodeIterator getAllLinearFrozenNodes() throws RepositoryException {
+        return new FrozenNodeIteratorAdapter(getAllLinearVersions());
+    }
+
+    /**
      * @see javax.jcr.version.VersionHistory#getVersion(String)
      */
-    public Version getVersion(String versionName)
+    public javax.jcr.version.Version getVersion(String versionName)
             throws VersionException, RepositoryException {
         try {
             Name name = session.getQName(versionName);
@@ -111,7 +140,7 @@
     /**
      * @see javax.jcr.version.VersionHistory#getVersionByLabel(String)
      */
-    public Version getVersionByLabel(String label) throws RepositoryException {
+    public javax.jcr.version.Version getVersionByLabel(String label) throws RepositoryException {
         try {
             Name qLabel = session.getQName(label);
             InternalVersion v =
@@ -148,7 +177,7 @@
         try {
             // check permissions
             checkVersionManagementPermission();
-            Version existing = session.getVersionManager().setVersionLabel(this, null, session.getQName(label), true);
+            javax.jcr.version.Version existing = session.getVersionManager().setVersionLabel(this, null, session.getQName(label), true);
             if (existing == null) {
                 throw new VersionException("No version with label '" + label + "' exists in this version history.");
             }
@@ -173,9 +202,9 @@
     /**
      * @see javax.jcr.version.VersionHistory#getVersionLabels(javax.jcr.version.Version)
      */
-    public String[] getVersionLabels(Version version)
+    public String[] getVersionLabels(javax.jcr.version.Version version)
             throws VersionException, RepositoryException {
-        checkOwnVersion(version);
+        checkOwnVersion((Version) version);
         Name[] labels = ((VersionImpl) version).getInternalVersion().getLabels();
         String[] ret = new String[labels.length];
         for (int i = 0; i < labels.length; i++) {
@@ -199,9 +228,9 @@
     /**
      * @see javax.jcr.version.VersionHistory#hasVersionLabel(javax.jcr.version.Version, String)
      */
-    public boolean hasVersionLabel(Version version, String label)
+    public boolean hasVersionLabel(javax.jcr.version.Version version, String label)
             throws VersionException, RepositoryException {
-        checkOwnVersion(version);
+        checkOwnVersion((Version)version);
         try {
             Name qLabel = session.getQName(label);
             return ((VersionImpl) version).getInternalVersion().hasLabel(qLabel);
@@ -246,13 +275,21 @@
      * {@inheritDoc}
      */
     public String getVersionableUUID() throws RepositoryException {
+        return getVersionableIdentifier();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getVersionableIdentifier() throws RepositoryException {
         return getInternalVersionHistory().getVersionableUUID().toString();
     }
 
     /**
-     * 
-     * @return
-     * @throws RepositoryException
+     * Checks if the current session has version management permission
+     *
+     * @throws AccessDeniedException if version management is not allowed
+     * @throws RepositoryException if an error occurs
      */
     private void checkVersionManagementPermission() throws RepositoryException {
         try {
@@ -265,9 +302,10 @@
     /**
      * Checks if the given version belongs to this history
      *
-     * @param version
-     * @throws javax.jcr.version.VersionException
-     * @throws javax.jcr.RepositoryException
+     * @param version the version
+     * @throws javax.jcr.version.VersionException if the specified version is
+     *         not part of this version history
+     * @throws javax.jcr.RepositoryException if a repository error occurs
      */
     private void checkOwnVersion(Version version)
             throws VersionException, RepositoryException {