jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r784261 [1/2] - in /jackrabbit/trunk: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/ jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/ jackra...
Date Fri, 12 Jun 2009 20:32:47 GMT
Author: tripod
Date: Fri Jun 12 20:32:47 2009
New Revision: 784261

URL: http://svn.apache.org/viewvc?rev=784261&view=rev
Log:
JCR-1592 - JSR 283: Activities

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java
      - copied, changed from r783733, 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/InternalActivityImpl.java
      - copied, changed from r782966, jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/LazyItemIterator.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/RepositoryImpl.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/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/JcrVersionManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/resources/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.cnd
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractRepository.java
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/NameConstants.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/LazyItemIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/LazyItemIterator.java?rev=784261&r1=784260&r2=784261&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/LazyItemIterator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/LazyItemIterator.java Fri Jun 12 20:32:47 2009
@@ -45,7 +45,7 @@
  *
  * @see #getSize()
  */
-class LazyItemIterator implements NodeIterator, PropertyIterator {
+public class LazyItemIterator implements NodeIterator, PropertyIterator {
 
     /** Logger instance for this class */
     private static Logger log = LoggerFactory.getLogger(LazyItemIterator.class);
@@ -54,7 +54,7 @@
     private final ItemManager itemMgr;
 
     /** the list of item ids */
-    private final List idList;
+    private final List<ItemId> idList;
 
     /** parent node id (when returning children nodes) or <code>null</code> */
     private final NodeId parentId;
@@ -71,7 +71,7 @@
      * @param itemMgr item manager
      * @param idList  list of item id's
      */
-    public LazyItemIterator(ItemManager itemMgr, List idList) {
+    public LazyItemIterator(ItemManager itemMgr, List<ItemId> idList) {
         this(itemMgr, idList, null);
     }
 
@@ -84,9 +84,9 @@
      * @param idList  list of item id's
      * @param parentId parent id.
      */
-    public LazyItemIterator(ItemManager itemMgr, List idList, NodeId parentId) {
+    public LazyItemIterator(ItemManager itemMgr, List<ItemId> idList, NodeId parentId) {
         this.itemMgr = itemMgr;
-        this.idList = new ArrayList(idList);
+        this.idList = new ArrayList<ItemId>(idList);
         this.parentId = parentId;
         // prefetch first item
         pos = 0;
@@ -103,7 +103,7 @@
         // reset
         next = null;
         while (next == null && pos < idList.size()) {
-            ItemId id = (ItemId) idList.get(pos);
+            ItemId id = idList.get(pos);
             try {
                 if (parentId != null) {
                     next = itemMgr.getNode((NodeId) id, parentId);
@@ -190,7 +190,7 @@
                 // skipped past last item
                 throw new NoSuchElementException();
             }
-            ItemId id = (ItemId) idList.get(pos);
+            ItemId id = idList.get(pos);
             // eliminate invalid items from this iterator
             while (!itemMgr.itemExists(id)) {
                 log.debug("ignoring nonexistent item " + id);
@@ -200,9 +200,7 @@
                     // skipped past last item
                     throw new NoSuchElementException();
                 }
-                id = (ItemId) idList.get(pos);
-                // try next
-                continue;
+                id = idList.get(pos);
             }
         }
         // prefetch final item (the one to be returned on next())

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=784261&r1=784260&r2=784261&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 Fri Jun 12 20:32:47 2009
@@ -811,7 +811,7 @@
         return createChildNode(nodeName, def, nodeType, id);
     }
 
-    private void setMixinTypesProperty(Set mixinNames) throws RepositoryException {
+    private void setMixinTypesProperty(Set<Name> mixinNames) throws RepositoryException {
         NodeState thisState = data.getNodeState();
         // get or create jcr:mixinTypes property
         PropertyImpl prop;
@@ -3322,6 +3322,9 @@
             if (isFull) {
                 internalSetProperty(NameConstants.JCR_BASEVERSION, InternalValue.create(new UUID(v.getUUID())));
                 internalSetProperty(NameConstants.JCR_PREDECESSORS, InternalValue.EMPTY_ARRAY, PropertyType.REFERENCE);
+                if (hasProperty(NameConstants.JCR_ACTIVITY)) {
+                    removeChildProperty(NameConstants.JCR_ACTIVITY);
+                }
             }
             save();
             success = true;
@@ -3362,20 +3365,26 @@
         session.getValidator().checkModify(this, options, Permission.VERSION_MNGMT);
 
         boolean hasPendingChanges = hasPendingChanges();
-        Property[] props = new Property[2];
+        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 UUID(getBaseVersion().getUUID()))
+                                InternalValue.create(new UUID(baseVersion.getUUID()))
                         });
+                if (activity != null) {
+                    props[2] = internalSetProperty(NameConstants.JCR_ACTIVITY,
+                            InternalValue.create(activity.getNodeId().getUUID()));
+                }
             }
             if (hasPendingChanges) {
-                for (int i = 0; i < props.length; i++) {
-                    if (props[i] != null) {
-                        props[i].save();
+                for (Property prop : props) {
+                    if (prop != null) {
+                        prop.save();
                     }
                 }
             } else {
@@ -3384,10 +3393,10 @@
             success = true;
         } finally {
             if (!success) {
-                for (int i = 0; i < props.length; i++) {
-                    if (props[i] != null) {
+                for (Property prop : props) {
+                    if (prop != null) {
                         try {
-                            props[i].refresh(false);
+                            prop.refresh(false);
                         } catch (RepositoryException e) {
                             log.error("Error while cleaning up after failed Node.checkout", e);
                         }
@@ -3973,8 +3982,8 @@
         // get frozen mixin
         // todo: also respect mixing types on creation?
         Name[] mxNames = frozen.getFrozenMixinTypes();
-        for (int i = 0; i < mxNames.length; i++) {
-            node.addMixin(mxNames[i]);
+        for (Name mxName : mxNames) {
+            node.addMixin(mxName);
         }
         return node;
     }
@@ -4017,8 +4026,8 @@
         // get frozen mixin
         // todo: also respect mixing types on creation?
         Name[] mxNames = frozen.getFrozenMixinTypes();
-        for (int i = 0; i < mxNames.length; i++) {
-            node.addMixin(mxNames[i]);
+        for (Name mxName : mxNames) {
+            node.addMixin(mxName);
         }
         return node;
     }
@@ -4216,15 +4225,14 @@
     /**
      * Internal method to restore a version.
      *
-     * @param version
-     * @param vsel    the version selector that will select the correct version for
-     *                OPV=Version child nodes.
-     * @throws UnsupportedRepositoryOperationException
-     *
-     * @throws RepositoryException
+     * @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 UnsupportedRepositoryOperationException, RepositoryException {
+            throws RepositoryException {
 
         boolean success = false;
         try {
@@ -4247,13 +4255,14 @@
     /**
      * Internal method to restore a version.
      *
-     * @param version
-     * @param vsel           the version selector that will select the correct version for
-     *                       OPV=Version child nodes.
-     * @param removeExisting
-     * @throws RepositoryException
+     * @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
      */
-    protected Version[] internalRestore(VersionImpl version, VersionSelector vsel,
+    public Version[] internalRestore(VersionImpl version, VersionSelector vsel,
                                         boolean removeExisting)
             throws RepositoryException {
 
@@ -4273,7 +4282,7 @@
         // 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 restored = new HashSet();
+        HashSet<Version> restored = new HashSet<Version>();
         restoreFrozenState(version.getInternalFrozenNode(), vsel, restored, removeExisting);
         restored.add(version);
 
@@ -4296,18 +4305,20 @@
         // 3. N's jcr:isCheckedOut property is set to false.
         internalSetProperty(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(false));
 
-        return (Version[]) restored.toArray(new Version[restored.size()]);
+        return restored.toArray(new Version[restored.size()]);
     }
 
     /**
      * Restores the properties and child nodes from the frozen state.
      *
-     * @param freeze
-     * @param vsel
-     * @param removeExisting
-     * @throws RepositoryException
+     * @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
      */
-    void restoreFrozenState(InternalFrozenNode freeze, VersionSelector vsel, Set restored, boolean removeExisting)
+    public void restoreFrozenState(InternalFrozenNode freeze, VersionSelector vsel, 
+                            Set<Version> restored, boolean removeExisting)
             throws RepositoryException {
 
         // check uuid
@@ -4326,19 +4337,22 @@
 
         // adjust mixins
         Name[] mixinNames = freeze.getFrozenMixinTypes();
-        setMixinTypesProperty(new HashSet(Arrays.asList(mixinNames)));
+        setMixinTypesProperty(new HashSet<Name>(Arrays.asList(mixinNames)));
 
         // copy frozen properties
         PropertyState[] props = freeze.getFrozenProperties();
-        HashSet propNames = new HashSet();
-        for (int i = 0; i < props.length; i++) {
-            PropertyState prop = props[i];
+        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(
-                        props[i].getName(), prop.getValues(), prop.getType());
+                        prop.getName(), prop.getValues(), prop.getType());
             } else {
-                internalSetProperty(props[i].getName(), prop.getValues()[0]);
+                internalSetProperty(prop.getName(), prop.getValues()[0]);
             }
         }
         // remove properties that do not exist in the frozen representation
@@ -4361,11 +4375,11 @@
 
         // add 'auto-create' properties that do not exist yet
         NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
-        for (int j = 0; j < mixinNames.length; j++) {
-            NodeTypeImpl mixin = ntMgr.getNodeType(mixinNames[j]);
+        for (Name mixinName : mixinNames) {
+            NodeTypeImpl mixin = ntMgr.getNodeType(mixinName);
             PropertyDefinition[] pda = mixin.getAutoCreatedPropertyDefinitions();
-            for (int i = 0; i < pda.length; i++) {
-                PropertyDefinitionImpl pd = (PropertyDefinitionImpl) pda[i];
+            for (PropertyDefinition aPda : pda) {
+                PropertyDefinitionImpl pd = (PropertyDefinitionImpl) aPda;
                 if (!hasProperty(pd.getQName())) {
                     createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
                 }
@@ -4393,8 +4407,7 @@
 
         // restore the frozen nodes
         InternalFreeze[] frozenNodes = freeze.getFrozenChildNodes();
-        for (int i = 0; i < frozenNodes.length; i++) {
-            InternalFreeze child = frozenNodes[i];
+        for (InternalFreeze child : frozenNodes) {
             NodeImpl restoredChild = null;
             if (child instanceof InternalFrozenNode) {
                 InternalFrozenNode f = (InternalFrozenNode) child;
@@ -4402,7 +4415,7 @@
                 if (f.getFrozenUUID() != null) {
                     try {
                         NodeImpl existing = (NodeImpl) session.getNodeByUUID(f.getFrozenUUID());
-                        // check if one of this restoretrees node
+                        // check if one of this restore trees node
                         if (removeExisting) {
                             existing.remove();
                         } else if (existing.isShareable()) {
@@ -4413,8 +4426,8 @@
                             // found nodes must be outside of this tree
                             throw new ItemExistsException(
                                     "Unable to restore node, item already"
-                                    + " exists outside of restored tree: "
-                                    + existing);
+                                            + " exists outside of restored tree: "
+                                            + existing);
                         }
                     } catch (ItemNotFoundException e) {
                         // ignore, item with uuid does not exist
@@ -4447,7 +4460,7 @@
                         // found nodes must be outside of this tree
                         throw new ItemExistsException(
                                 "Unable to restore node, item already exists"
-                                + " outside of restored tree: " + n);
+                                        + " outside of restored tree: " + n);
                     }
                 }
                 // get desired version from version selector
@@ -4461,7 +4474,7 @@
                         Version[] vs = history.getRootVersion().getSuccessors();
                         if (vs.length == 0) {
                             String msg = "Unable to select appropariate version for "
-                                + child.getName() + " using " + vsel;
+                                    + child.getName() + " using " + vsel;
                             log.error(msg);
                             throw new VersionException(msg);
                         }
@@ -4497,7 +4510,7 @@
                     restored.add(v);
                 }
             }
-            // ensure proper odering (issue JCR-469)
+            // ensure proper ordering (issue JCR-469)
             if (restoredChild != null
                     && getPrimaryNodeType().hasOrderableChildNodes()) {
                 orderBefore(restoredChild.getPrimaryPath().getNameElement(), null);
@@ -4508,8 +4521,8 @@
     /**
      * Copies a property to this node
      *
-     * @param prop
-     * @throws RepositoryException
+     * @param prop property to copy from
+     * @throws RepositoryException if an error occurs
      */
     protected void internalCopyPropertyFrom(PropertyImpl prop) throws RepositoryException {
         if (prop.getDefinition().isMultiple()) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=784261&r1=784260&r2=784261&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java Fri Jun 12 20:32:47 2009
@@ -132,6 +132,11 @@
     public static final NodeId VERSION_STORAGE_NODE_ID = NodeId.valueOf("deadbeef-face-babe-cafe-babecafebabe");
 
     /**
+     * hardcoded id of the "/jcr:system/jcr:versionStorage/jcr:activities" node
+     */
+    public static final NodeId ACTIVITIES_NODE_ID = NodeId.valueOf("deadbeef-face-babe-ac71-babecafebabe");
+
+    /**
      * hardcoded id of the "/jcr:system/jcr:nodeTypes" node
      */
     public static final NodeId NODETYPES_NODE_ID = NodeId.valueOf("deadbeef-cafe-cafe-cafe-babecafebabe");
@@ -467,7 +472,10 @@
         ISMLocking ismLocking = vConfig.getISMLocking();
 
         return new VersionManagerImpl(pm, fs, ntReg, delegatingDispatcher,
-                VERSION_STORAGE_NODE_ID, SYSTEM_ROOT_NODE_ID, cacheFactory,
+                SYSTEM_ROOT_NODE_ID,
+                VERSION_STORAGE_NODE_ID,
+                ACTIVITIES_NODE_ID,
+                cacheFactory,
                 ismLocking);
     }
 

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=784261&r1=784260&r2=784261&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 Fri Jun 12 20:32:47 2009
@@ -16,27 +16,31 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.ReferentialIntegrityException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.version.VersionException;
+
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.state.DefaultISMLocking;
+import org.apache.jackrabbit.core.state.ISMLocking.ReadLock;
+import org.apache.jackrabbit.core.state.ISMLocking.WriteLock;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.LocalItemStateManager;
+import org.apache.jackrabbit.core.state.NodeReferences;
+import org.apache.jackrabbit.core.state.NodeReferencesId;
 import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.core.state.ISMLocking.ReadLock;
-import org.apache.jackrabbit.core.state.ISMLocking.WriteLock;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
+import org.apache.jackrabbit.uuid.UUID;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.Value;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.version.VersionException;
-
 /**
  * Base implementation of the {@link VersionManager} interface.
  * <p/>
@@ -66,6 +70,11 @@
     protected NodeStateEx historyRoot;
 
     /**
+     * Persistent root node of the activities.
+     */
+    protected NodeStateEx activitiesRoot;
+
+    /**
      * the lock on this version manager
      */
     private final DefaultISMLocking rwLock = new DefaultISMLocking();
@@ -91,6 +100,18 @@
     /**
      * {@inheritDoc}
      */
+    public InternalActivity getActivity(NodeId id) throws RepositoryException {
+        // lock handling via getItem()
+        InternalActivity v = (InternalActivity) getItem(id);
+        if (v == null) {
+            log.warn("Versioning item not found: " + id);
+        }
+        return v;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public InternalVersionHistory getVersionHistory(NodeId id)
             throws RepositoryException {
         // lock handling via getItem()
@@ -107,7 +128,7 @@
             String uuid = id.getUUID().toString();
             Name name = getName(uuid);
 
-            NodeStateEx parent = getParentNode(uuid, false);
+            NodeStateEx parent = getParentNode(historyRoot, uuid, null);
             if (parent != null && parent.hasNode(name)) {
                 NodeStateEx history = parent.getNode(name, 1);
                 return getVersionHistory(history.getNodeId());
@@ -258,7 +279,7 @@
             String uuid = node.getNodeId().getUUID().toString();
             Name name = getName(uuid);
 
-            NodeStateEx parent = getParentNode(uuid, false);
+            NodeStateEx parent = getParentNode(historyRoot, uuid, null);
             if (parent != null && parent.hasNode(name)) {
                 NodeStateEx history = parent.getNode(name, 1);
                 Name root = NameConstants.JCR_ROOTVERSION;
@@ -353,13 +374,13 @@
      * @return the identifiers of the newly created version history and root version
      * @throws RepositoryException if an error occurs
      */
-    NodeStateEx createVersionHistory(NodeState node, NodeId copiedFrom)
+    NodeStateEx internalCreateVersionHistory(NodeState node, NodeId copiedFrom)
             throws RepositoryException {
         WriteOperation operation = startWriteOperation();
         try {
             // create deep path
             String uuid = node.getNodeId().getUUID().toString();
-            NodeStateEx parent = getParentNode(uuid, true);
+            NodeStateEx parent = getParentNode(historyRoot, uuid, NameConstants.REP_VERSIONSTORAGE);
             Name name = getName(uuid);
             if (parent.hasNode(name)) {
                 // already exists
@@ -385,6 +406,84 @@
     }
 
     /**
+     * Creates a new activity.
+     *
+     * @param title title of the new activity
+     * @return the id of the newly created activity
+     * @throws RepositoryException if an error occurs
+     */
+    NodeStateEx internalCreateActivity(String title)
+            throws RepositoryException {
+        WriteOperation operation = startWriteOperation();
+        try {
+            // create deep path
+            NodeId activityId = new NodeId(UUID.randomUUID());
+            NodeStateEx parent = getParentNode(activitiesRoot, activityId.toString(), NameConstants.REP_ACTIVITIES);
+            Name name = getName(activityId.toString());
+
+            // create new activity node in the persistent state
+            NodeStateEx pNode = InternalActivityImpl.create(parent, name, activityId, title);
+
+            // end update
+            operation.save();
+
+            log.debug("Created new activity " + activityId
+                    + " with title " + title + ".");
+            return pNode;
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        } finally {
+            operation.close();
+        }
+    }
+
+    /**
+     * Removes the specified activity
+     *
+     * @param activity the acitvity to remove
+     * @throws javax.jcr.RepositoryException if any other error occurs.
+     */
+    protected void internalRemoveActivity(InternalActivityImpl activity)
+            throws RepositoryException {
+        WriteOperation operation = startWriteOperation();
+        try {
+            // check if the activity has any references in the workspaces
+            NodeId nodeId = activity.getId();
+            NodeReferencesId refId = new NodeReferencesId(nodeId);
+            if (stateMgr.hasNodeReferences(refId)) {
+                NodeReferences refs = stateMgr.getNodeReferences(refId);
+                if (refs.hasReferences()) {
+                    throw new ReferentialIntegrityException("Unable to delete activity. still referenced.");
+                }
+            }
+            // TODO:
+            // check if the activity is used in anywhere in the version storage
+            // and reject removal
+
+            // remove activity and possible empty parent directories
+            NodeStateEx act = getNodeStateEx(nodeId);
+            NodeId parentId = act.getParentId();
+            Name name = act.getName();
+            while (parentId != null) {
+                NodeStateEx parent = getNodeStateEx(parentId);
+                parent.removeNode(name);
+                parent.store();
+                if (parent.getChildNodes().length == 0 && !parentId.equals(activitiesRoot.getNodeId())) {
+                    name = parent.getName();
+                    parentId = parent.getParentId();
+                } else {
+                    parentId = null;
+                }
+            }
+            operation.save();
+        } catch (ItemStateException e) {
+            log.error("Error while storing: " + e.toString());
+        } finally {
+            operation.close();
+        }
+    }
+
+    /**
      * Utility method that returns the given string as a name in the default
      * namespace.
      *
@@ -398,24 +497,26 @@
     /**
      * Utility method that returns the parent node under which the version
      * history of the identified versionable node is or will be stored. If
-     * the create flag is set, then the returned parent node and any ancestor
-     * nodes are automatically created if they do not already exist. Otherwise
+     * the <code>interNT</code> is not <code>null</code> then the returned
+     * parent node and any ancestor nodes are automatically created if they do
+     * not already exist. Otherwise
      * <code>null</code> is returned if the parent node does not exist.
      *
+     * @param parent the parent node
      * @param uuid UUID of a versionable node
-     * @param create whether to create missing nodes
+     * @param interNT intermediate nodetype.
      * @return parent node of the version history, or <code>null</code>
      * @throws RepositoryException if an error occurs
      */
-    private NodeStateEx getParentNode(String uuid, boolean create)
+    private NodeStateEx getParentNode(NodeStateEx parent, String uuid, Name interNT)
             throws RepositoryException {
-        NodeStateEx n = historyRoot;
+        NodeStateEx n = parent;
         for (int i = 0; i < 3; i++) {
             Name name = getName(uuid.substring(i * 2, i * 2 + 2));
             if (n.hasNode(name)) {
                 n = n.getNode(name, 1);
-            } else if (create) {
-                n.addNode(name, NameConstants.REP_VERSIONSTORAGE, null, false);
+            } else if (interNT != null) {
+                n.addNode(name, interNT, null, false);
                 n.store();
                 n = n.getNode(name, 1);
             } else {
@@ -435,13 +536,21 @@
      * @throws javax.jcr.RepositoryException if an error occurs
      * @see javax.jcr.Node#checkin()
      */
-    protected InternalVersion checkin(InternalVersionHistoryImpl history,
+    protected InternalVersion internalCheckin(InternalVersionHistoryImpl history,
                                       NodeImpl node, boolean simple)
             throws RepositoryException {
         WriteOperation operation = startWriteOperation();
         try {
             String versionName = calculateCheckinVersionName(history, node, simple);
             InternalVersionImpl v = history.checkin(NameFactoryImpl.getInstance().create("", versionName), node);
+
+            // check for jcr:activity
+            if (node.hasProperty(NameConstants.JCR_ACTIVITY)) {
+                NodeId actId = new NodeId(node.getProperty(NameConstants.JCR_ACTIVITY).internalGetValue().getUUID());
+                InternalActivityImpl act = (InternalActivityImpl) getItem(actId);
+                act.addVersion(v);
+            }
+
             operation.save();
             return v;
         } catch (ItemStateException e) {
@@ -538,7 +647,7 @@
      *  not have a version with <code>name</code>.
      * @throws javax.jcr.RepositoryException if any other error occurs.
      */
-    protected void removeVersion(InternalVersionHistoryImpl history, Name name)
+    protected void internalRemoveVersion(InternalVersionHistoryImpl history, Name name)
             throws VersionException, RepositoryException {
         WriteOperation operation = startWriteOperation();
         try {
@@ -629,6 +738,8 @@
                     return ((InternalVersionHistory) parent).getVersion(id);
                 } else if (ntName.equals(NameConstants.NT_VERSIONHISTORY)) {
                     return new InternalVersionHistoryImpl(this, pNode);
+                } else if (ntName.equals(NameConstants.NT_ACTIVITY)) {
+                    return new InternalActivityImpl(this, pNode);
                 } else {
                     return null;
                 }

Copied: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java (from r783733, 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/InternalActivity.java?p2=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivity.java&p1=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersion.java&r1=783733&r2=784261&rev=784261&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/InternalActivity.java Fri Jun 12 20:32:47 2009
@@ -16,120 +16,35 @@
  */
 package org.apache.jackrabbit.core.version;
 
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.core.NodeId;
-import javax.jcr.version.Version;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.jcr.RepositoryException;
 
-import java.util.Calendar;
+import org.apache.jackrabbit.core.NodeId;
 
 /**
- * This interface defines the internal version.
+ * This interface defines the internal activity.
  */
-public interface InternalVersion extends InternalVersionItem {
-
-    /**
-     * Returns the name of this version.
-     *
-     * @return the name of this version.
-     */
-    Name getName();
-
-    /**
-     * Returns the frozen node of this version or <code>null</code> if this is
-     * the root version.
-     *
-     * @return the frozen node.
-     */
-    InternalFrozenNode getFrozenNode();
-
-    /**
-     * Returns the node id of the frozen node.
-     *
-     * @return the node id of the frozen node;
-     */
-    NodeId getFrozenNodeId();
-
-    /**
-     * Equivalent to {@link javax.jcr.version.Version#getCreated()}
-     *
-     * @see javax.jcr.version.Version#getCreated()
-     * @return the created date
-     */
-    Calendar getCreated();
-
-    /**
-     * Equivalent to {@link javax.jcr.version.Version#getSuccessors()}}
-     *
-     * @see javax.jcr.version.Version#getSuccessors()
-     * @return the successors as internal versions
-     */
-    InternalVersion[] getSuccessors();
+public interface InternalActivity extends InternalVersionItem {
 
     /**
-     * Equivalent to {@link Version#getLinearSuccessor()}.
-     *
-     * @param baseVersion base version to determine single line of descent
-     * @return the successor as internal version
-     *
-     * @see Version#getLinearSuccessor()
+     * Returns the latest version of the given history that is referenced in this activity.
+     * @param history the history
+     * @return the version
+     * @throws RepositoryException if an error occurs
      */
-    InternalVersion getLinearSuccessor(InternalVersion baseVersion);
+    public InternalVersion getLatestVersion(InternalVersionHistory history)
+            throws RepositoryException;
 
     /**
-     * Equivalent to {@link javax.jcr.version.Version#getPredecessors()}}
-     *
-     * @see javax.jcr.version.Version#getPredecessors()
-     * @return the predecessors as internal versions
+     * Returns the changeset of this activity.
+     * This is the set of versions that are the latest members of this activity
+     * in their respective version histories. the changeset is a map grouped by
+     * the nodeid of the respective histories.
+     * @return the changeset
+     * @throws RepositoryException if an error occurs
      */
-    InternalVersion[] getPredecessors();
+    public Map<NodeId, InternalVersion> getChangeSet() throws RepositoryException;
 
-    /**
-     * 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.
-     *
-     * @param v the version to check
-     * @return <code>true</code> if the version is more recent;
-     *         <code>false</code> otherwise.
-     */
-    boolean isMoreRecent(InternalVersion v);
-
-    /**
-     * returns the internal version history in wich this version lifes in.
-     *
-     * @return the version history for this version.
-     */
-    InternalVersionHistory getVersionHistory();
-
-    /**
-     * checks if this is the root version.
-     *
-     * @return <code>true</code> if this version is the root version;
-     *         <code>false</code> otherwise.
-     */
-    boolean isRootVersion();
-
-    /**
-     * Checks, if this version has the given label assosiated
-     *
-     * @param label the label to check.
-     * @return <code>true</code> if the label is assigned to this version;
-     *         <code>false</code> otherwise.
-     */
-    boolean hasLabel(Name label);
-
-    /**
-     * returns the labels that are assigned to this version
-     *
-     * @return a string array of labels.
-     */
-    Name[] getLabels();
-}
+}
\ No newline at end of file

Copied: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java (from r782966, 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/InternalActivityImpl.java?p2=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalActivityImpl.java&p1=jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java&r1=782966&r2=784261&rev=784261&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/InternalActivityImpl.java Fri Jun 12 20:32:47 2009
@@ -16,92 +16,27 @@
  */
 package org.apache.jackrabbit.core.version;
 
-import org.apache.jackrabbit.core.NodeImpl;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
 import org.apache.jackrabbit.core.NodeId;
-import org.apache.jackrabbit.core.state.ItemStateException;
-import org.apache.jackrabbit.core.state.NodeState;
-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.uuid.UUID;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jcr.PropertyType;
-import javax.jcr.ReferentialIntegrityException;
-import javax.jcr.RepositoryException;
-import javax.jcr.Value;
-import javax.jcr.version.VersionException;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import org.apache.jackrabbit.uuid.UUID;
 
 /**
- * Implements a <code>InternalVersionHistory</code>
+ * Implements a internal representation of an activity node.
+ * this is only for the {@link XAVersionManager}.
  */
-class InternalVersionHistoryImpl extends InternalVersionItemImpl
-        implements InternalVersionHistory {
-
-    /**
-     * default logger
-     */
-    private static Logger log = LoggerFactory.getLogger(InternalVersionHistory.class);
-
-    /**
-     * The last current time that was returned by {@link #getCurrentTime()}.
-     */
-    private static final Calendar CURRENT_TIME = Calendar.getInstance();
-
-    /**
-     * the cache of the version labels
-     * key = version label (String)
-     * value = version name
-     */
-    private Map<Name, Name> labelCache = new HashMap<Name, Name>();
-
-    /**
-     * the root version of this history
-     */
-    private InternalVersion rootVersion;
-
-    /**
-     * the hashmap of all versions names
-     * key = version name
-     * value = version id (NodeId)
-     */
-    private Map<Name, NodeId> nameCache = new LinkedHashMap<Name, NodeId>();
-
-    /**
-     * the hashmap of all versions
-     * key = version id (NodeId)
-     * value = version
-     */
-    private Map<NodeId, InternalVersion> versionCache = new HashMap<NodeId, InternalVersion>();
-
-    /**
-     * Temporary version cache, used on a refresh.
-     */
-    private Map<NodeId, InternalVersion> tempVersionCache = new HashMap<NodeId, InternalVersion>();
-
-    /**
-     * the node that holds the label nodes
-     */
-    private NodeStateEx labelNode;
-
-    /**
-     * the id of this history
-     */
-    private NodeId historyId;
-
-    /**
-     * the id of the versionable node
-     */
-    private NodeId versionableId;
+class InternalActivityImpl extends InternalVersionItemImpl implements InternalActivity {
 
     /**
      * Creates a new VersionHistory object for the given node state.
@@ -109,136 +44,16 @@
      * @param node version history node state
      * @throws RepositoryException if an error occurs
      */
-    public InternalVersionHistoryImpl(AbstractVersionManager vMgr, NodeStateEx node)
+    public InternalActivityImpl(AbstractVersionManager vMgr, NodeStateEx node)
             throws RepositoryException {
         super(vMgr, node);
-        init();
-    }
-
-    /**
-     * Initialies the history and loads all internal caches
-     *
-     * @throws RepositoryException if an error occurs
-     */
-    private void init() throws RepositoryException {
-        nameCache.clear();
-        versionCache.clear();
-        labelCache.clear();
-
-        // get id
-        historyId = node.getNodeId();
-
-        // get versionable id
-        versionableId = NodeId.valueOf(node.getPropertyValue(NameConstants.JCR_VERSIONABLEUUID).toString());
-
-        // get label node
-        labelNode = node.getNode(NameConstants.JCR_VERSIONLABELS, 1);
-
-        // init label cache
-        try {
-            PropertyState[] labels = labelNode.getProperties();
-            for (PropertyState pState : labels) {
-                if (pState.getType() == PropertyType.REFERENCE) {
-                    Name labelName = pState.getName();
-                    UUID ref = pState.getValues()[0].getUUID();
-                    NodeId id = new NodeId(ref);
-                    if (node.getState().hasChildNodeEntry(id)) {
-                        labelCache.put(labelName, node.getState().getChildNodeEntry(id).getName());
-                    } else {
-                        log.warn("Error while resolving label reference. Version missing: " + ref);
-                    }
-                }
-            }
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
-        }
-
-        // get root version
-        rootVersion = createVersionInstance(NameConstants.JCR_ROOTVERSION);
-
-        // get version entries
-        ChildNodeEntry[] children = (ChildNodeEntry[])
-            node.getState().getChildNodeEntries().toArray();
-        for (ChildNodeEntry child : children) {
-            if (child.getName().equals(NameConstants.JCR_VERSIONLABELS)) {
-                continue;
-            }
-            nameCache.put(child.getName(), child.getId());
-        }
-
-        // fix legacy
-        if (rootVersion.getSuccessors().length == 0) {
-            for (Name versionName : nameCache.keySet()) {
-                InternalVersionImpl v = createVersionInstance(versionName);
-                v.legacyResolveSuccessors();
-            }
-        }
-    }
-
-    /**
-     * Reload this object and all its dependent version objects.
-     * @throws RepositoryException if an error occurs
-     */
-    void reload() throws RepositoryException {
-        tempVersionCache.putAll(versionCache);
-
-        init();
-
-        // invalidate all versions that are not referenced any more
-        for (Object o : tempVersionCache.values()) {
-            InternalVersionImpl v = (InternalVersionImpl) o;
-            v.invalidate();
-        }
-        tempVersionCache.clear();
-    }
-
-    /**
-     * 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 {
-            NodeStateEx nodeStateEx = node.getNode(name, 1);
-            InternalVersionImpl v = createVersionInstance(nodeStateEx);
-            versionCache.put(v.getId(), v);
-            vMgr.versionCreated(v);
-
-            // add labels
-            for (Name labelName: labelCache.keySet()) {
-                Name versionName = labelCache.get(labelName);
-                if (v.getName().equals(versionName)) {
-                    v.internalAddLabel(labelName);
-                }
-            }
-            return v;
-        } catch (RepositoryException e) {
-            throw new IllegalArgumentException("Failed to create version " + name + ".");
-        }
-    }
-
-    /**
-     * 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());
-        if (v != null) {
-            v.clear();
-        } else {
-            v = new InternalVersionImpl(this, child, child.getName());
-        }
-        return v;
     }
 
     /**
      * {@inheritDoc}
      */
     public NodeId getId() {
-        return historyId;
+        return node.getNodeId();
     }
 
     /**
@@ -249,379 +64,111 @@
     }
 
     /**
-     * {@inheritDoc}
-     */
-    public InternalVersion getRootVersion() {
-        return rootVersion;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public InternalVersion getVersion(Name versionName) throws VersionException {
-        NodeId versionId = nameCache.get(versionName);
-        if (versionId == null) {
-            throw new VersionException("Version " + versionName + " does not exist.");
-        }
-
-        InternalVersion v = versionCache.get(versionId);
-        if (v == null) {
-            v = createVersionInstance(versionName);
-        }
-        return v;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean hasVersion(Name versionName) {
-        return nameCache.containsKey(versionName);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public InternalVersion getVersion(NodeId id) {
-        InternalVersion v = versionCache.get(id);
-        if (v == null) {
-            for (Name versionName : nameCache.keySet()) {
-                if (nameCache.get(versionName).equals(id)) {
-                    v = createVersionInstance(versionName);
-                    break;
-                }
-            }
-        }
-        return v;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public InternalVersion getVersionByLabel(Name label) {
-        Name versionName = labelCache.get(label);
-        if (versionName == null) {
-            return null;
-        }
-
-        NodeId id = nameCache.get(versionName);
-        InternalVersion v = versionCache.get(id);
-        if (v == null) {
-            v = createVersionInstance(versionName);
-        }
-        return v;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Name[] getVersionNames() {
-        return nameCache.keySet().toArray(new Name[nameCache.size()]);
-    }
-    
-    /**
-     * {@inheritDoc}
-     */
-    public int getNumVersions() {
-        return nameCache.size();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public UUID getVersionableUUID() {
-        return versionableId.getUUID();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Name[] getVersionLabels() {
-        return labelCache.keySet().toArray(new Name[labelCache.size()]);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public NodeId getVersionLabelsId() {
-        return labelNode.getNodeId();
-    }
-
-    /**
-     * Removes the indicated version from this VersionHistory. If the specified
-     * vesion does not exist, if it specifies the root version or if it is
-     * referenced by any node e.g. as base version, a VersionException is thrown.
-     * <p/>
-     * all successors of the removed version become successors of the
-     * predecessors of the removed version and vice versa. then, the entire
-     * version node and all its subnodes are removed.
+     * Creates a new activity history below the given parent node and with
+     * the given name.
      *
-     * @param versionName name of the version to remove
-     * @throws VersionException if removal is not possible
+     * @param parent parent node
+     * @param name activity name
+     * @param activityId node id for the new activity
+     * @param title title of the activity
+     * @return new node state
+     * @throws RepositoryException if an error occurs
      */
-    void removeVersion(Name versionName) throws RepositoryException {
-
-        InternalVersionImpl v = (InternalVersionImpl) getVersion(versionName);
-        if (v.equals(rootVersion)) {
-            String msg = "Removal of " + versionName + " not allowed.";
-            log.debug(msg);
-            throw new VersionException(msg);
-        }
-        // check if any references (from outside the version storage) exist on this version
-        if (vMgr.hasItemReferences(v.getId())) {
-            throw new ReferentialIntegrityException("Unable to remove version. At least once referenced.");
-        }
+    static NodeStateEx create(NodeStateEx parent, Name name, NodeId activityId,
+                              String title)
+            throws RepositoryException {
 
-        // unregister from labels
-        Name[] labels = v.internalGetLabels();
-        for (Name label : labels) {
-            v.internalRemoveLabel(label);
-            labelNode.removeProperty(label);
-        }
-        // detach from the version graph
-        v.internalDetach();
+        // create new activity node in the persistent state
+        NodeStateEx pNode = parent.addNode(name, NameConstants.NT_ACTIVITY, activityId, true);
+        Set<Name> mix = new HashSet<Name>();
+        mix.add(NameConstants.REP_VERSION_REFERENCE);
+        pNode.setMixins(mix);
 
-        // remove from persistence state
-        node.removeNode(v.getName());
+        // set the title
+        pNode.setPropertyValue(NameConstants.JCR_ACTIVITY_TITLE, InternalValue.create(title));
 
-        // and remove from history
-        versionCache.remove(v.getId());
-        nameCache.remove(versionName);
-        vMgr.versionDestroyed(v);
-
-        // Check if this was the last version in addition to the root version
-        if (!vMgr.hasItemReferences(node.getNodeId())) {
-            log.debug("Current version history has no references");
-            NodeStateEx[] childNodes = node.getChildNodes();
-
-            // Check if there is only root version and version labels nodes
-            if (childNodes.length == 2) {
-                log.debug("Removing orphan version history as it contains only two children");
-                NodeStateEx parentNode = vMgr.getNodeStateEx(node.getParentId());
-                // Remove version history node
-                parentNode.removeNode(node.getName());
-                // store changes for this node and his children
-                parentNode.store();
-            }
-        } else {
-            log.debug("Current version history has at least one reference");
-            // store changes
-            node.store();
-        }
+        parent.store();
 
-        // now also remove from labelCache
-        for (Name label : labels) {
-            labelCache.remove(label);
-        }
+        return pNode;
     }
 
     /**
-     * Sets the version <code>label</code> to the given <code>version</code>.
-     * If the label is already assigned to another version, a VersionException is
-     * thrown unless <code>move</code> is <code>true</code>. If <code>version</code>
-     * is <code>null</code>, the label is removed from the respective version.
-     * In either case, the version the label was previously assigned to is returned,
-     * or <code>null</code> of the label was not moved.
-     *
-     * @param versionName the name of the version
-     * @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 if the version does not exist or if the label is already defined.
+     * Adds a version reference
+     * @param v the version
+     * @throws RepositoryException if an error occurs
      */
-    InternalVersion setVersionLabel(Name versionName, Name label, boolean move)
-            throws VersionException {
-        InternalVersion version =
-            (versionName != null) ? getVersion(versionName) : null;
-        if (versionName != null && version == null) {
-            throw new VersionException("Version " + versionName + " does not exist in this version history.");
-        }
-        Name prevName = labelCache.get(label);
-        InternalVersionImpl prev = null;
-        if (prevName == null) {
-            if (version == null) {
-                return null;
-            }
+    public void addVersion(InternalVersionImpl v) throws RepositoryException {
+        InternalValue[] versions;
+        if (node.hasProperty(NameConstants.REP_VERSIONS)) {
+            InternalValue[] vs = node.getPropertyValues(NameConstants.REP_VERSIONS);
+            versions = new InternalValue[vs.length+1];
+            System.arraycopy(vs, 0, versions, 0, vs.length);
+            versions[vs.length] = InternalValue.create(v.getId().getUUID());
         } else {
-            prev = (InternalVersionImpl) getVersion(prevName);
-            if (prev.equals(version)) {
-                return version;
-            } else if (!move) {
-                // already defined elsewhere, throw
-                throw new VersionException("Version label " + label + " already defined for version " + prev.getName());
-            }
-        }
-
-        // update persistence
-        try {
-            if (version == null) {
-                labelNode.removeProperty(label);
-            } else {
-                labelNode.setPropertyValue(label, InternalValue.create(version.getId().getUUID()));
-            }
-            labelNode.store();
-        } catch (RepositoryException e) {
-            throw new VersionException(e);
+            versions = new InternalValue[]{InternalValue.create(v.getId().getUUID())};
         }
-
-        // update internal structures
-        if (prev != null) {
-            prev.internalRemoveLabel(label);
-            labelCache.remove(label);
-        }
-        if (version != null) {
-            labelCache.put(label, version.getName());
-            ((InternalVersionImpl) version).internalAddLabel(label);
-        }
-        return prev;
+        node.setPropertyValues(NameConstants.REP_VERSIONS, PropertyType.REFERENCE, versions);
+        node.store();
     }
 
     /**
-     * Checks in a node. It creates a new version with the given name and freezes
-     * the state of the given node.
-     *
-     * @param name new version name
-     * @param src source node to version
-     * @return the newly created version
+     * Removes the given version from the list of references
+     * @param v the version
      * @throws RepositoryException if an error occurs
      */
-    InternalVersionImpl checkin(Name name, NodeImpl src)
-            throws RepositoryException {
-
-        // copy predecessors from src 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");
+    public void removeVersion(InternalVersionImpl v) throws RepositoryException {
+        List<InternalValue> versions = new LinkedList<InternalValue>();
+        if (node.hasProperty(NameConstants.REP_VERSIONS)) {
+            UUID vUUID = v.getId().getUUID();
+            for (InternalValue ref: node.getPropertyValues(NameConstants.REP_VERSIONS)) {
+                if (!ref.getUUID().equals(vUUID)) {
+                    versions.add(ref);
                 }
-                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 = new InternalValue[]{InternalValue.create(last.getUUID())};
         }
-
-        NodeId versionId = new NodeId(UUID.randomUUID());
-        NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true);
-
-        // initialize 'created', 'predecessors' and 'successors'
-        vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime()));
-        vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);
-        vNode.setPropertyValues(NameConstants.JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
-
-        // checkin source node
-        InternalFrozenNodeImpl.checkin(vNode, NameConstants.JCR_FROZENNODE, src);
-
-        // update version graph
-        InternalVersionImpl version = new InternalVersionImpl(this, vNode, name);
-        version.internalAttach();
-
-        // and store
+        node.setPropertyValues(NameConstants.REP_VERSIONS, PropertyType.REFERENCE, versions.toArray(new InternalValue[versions.size()]));
         node.store();
 
-        vMgr.versionCreated(version);
-
-        // update cache
-        versionCache.put(version.getId(), version);
-        nameCache.put(version.getName(), version.getId());
-
-        return version;
     }
 
     /**
-     * Creates a new version history below the given parent node and with
-     * the given name.
-     *
-     * @param vMgr version manager
-     * @param parent parent node
-     * @param name history name
-     * @param nodeState node state
-     * @param copiedFrom the id of the base version
-     * @return new node state
+     * Returns the latest version of the given history that is referenced in this activity.
+     * @param history the history
+     * @return the version
      * @throws RepositoryException if an error occurs
      */
-    static NodeStateEx create(
-            AbstractVersionManager vMgr, NodeStateEx parent, Name name,
-            NodeState nodeState, NodeId copiedFrom) throws RepositoryException {
-
-        // create history node
-        NodeId historyId = new NodeId(UUID.randomUUID());
-        NodeStateEx pNode = parent.addNode(name, NameConstants.NT_VERSIONHISTORY, historyId, true);
-
-        // set the versionable uuid
-        String versionableUUID = nodeState.getNodeId().getUUID().toString();
-        pNode.setPropertyValue(NameConstants.JCR_VERSIONABLEUUID, InternalValue.create(versionableUUID));
-
-        // create label node
-        pNode.addNode(NameConstants.JCR_VERSIONLABELS, NameConstants.NT_VERSIONLABELS, null, false);
-
-        // initialize the 'jcr:copiedFrom' property
-        if (copiedFrom != null) {
-            pNode.setPropertyValue(NameConstants.JCR_COPIEDFROM, InternalValue.create(copiedFrom.getUUID(), true));
-        }
-        
-        // create root version
-        NodeId versionId = new NodeId(UUID.randomUUID());
-        NodeStateEx vNode = pNode.addNode(NameConstants.JCR_ROOTVERSION, NameConstants.NT_VERSION, versionId, true);
-
-        // initialize 'created' and 'predecessors'
-        vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime()));
-        vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
-        vNode.setPropertyValues(NameConstants.JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
-
-        // add also an empty frozen node to the root version
-        NodeStateEx node = vNode.addNode(NameConstants.JCR_FROZENNODE, NameConstants.NT_FROZENNODE, null, true);
-
-        // initialize the internal properties
-        node.setPropertyValue(NameConstants.JCR_FROZENUUID, InternalValue.create(versionableUUID));
-        node.setPropertyValue(NameConstants.JCR_FROZENPRIMARYTYPE,
-                InternalValue.create(nodeState.getNodeTypeName()));
-
-        Set mixins = nodeState.getMixinTypeNames();
-        if (mixins.size() > 0) {
-            InternalValue[] ivalues = new InternalValue[mixins.size()];
-            Iterator iter = mixins.iterator();
-            for (int i = 0; i < mixins.size(); i++) {
-                ivalues[i] = InternalValue.create((Name) iter.next());
+    public InternalVersion getLatestVersion(InternalVersionHistory history)
+            throws RepositoryException {
+        if (node.hasProperty(NameConstants.REP_VERSIONS)) {
+            InternalVersion best = null;
+            for (InternalValue ref: node.getPropertyValues(NameConstants.REP_VERSIONS)) {
+                NodeId versionId = new NodeId(ref.getUUID());
+                InternalVersion v = history.getVersion(versionId);
+                if (v != null) {
+                    // currently we assume that the last version is the best
+                    best = v;
+                }
             }
-            node.setPropertyValues(NameConstants.JCR_FROZENMIXINTYPES, PropertyType.NAME, ivalues);
+            return best;
+        } else {
+            return null;
         }
-
-        parent.store();
-        return pNode;
     }
 
     /**
-     * Returns the current time as a calendar instance and makes sure that no
-     * two Calendar instances represent the exact same time. If this method is
-     * called quickly in succession each Calendar instance returned is at least
-     * one millisecond later than the previous one.
-     *
-     * @return the current time.
+     * {@inheritDoc}
      */
-    static Calendar getCurrentTime() {
-        long time = System.currentTimeMillis();
-        synchronized (CURRENT_TIME) {
-            if (time > CURRENT_TIME.getTimeInMillis()) {
-                CURRENT_TIME.setTimeInMillis(time);
-            } else {
-                CURRENT_TIME.add(Calendar.MILLISECOND, 1);
+    public Map<NodeId, InternalVersion> getChangeSet() throws RepositoryException {
+        Map<NodeId, InternalVersion> changeset = new HashMap<NodeId, InternalVersion>();
+        if (node.hasProperty(NameConstants.REP_VERSIONS)) {
+            for (InternalValue ref: node.getPropertyValues(NameConstants.REP_VERSIONS)) {
+                // currently we rely on the fact that the latest version is
+                // also the last in the references
+                NodeId versionId = new NodeId(ref.getUUID());
+                InternalVersion v = vMgr.getVersion(versionId);
+                changeset.put(v.getVersionHistory().getId(), v);
             }
-            return (Calendar) CURRENT_TIME.clone();
         }
+        return changeset;
     }
-}
+}
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java?rev=784261&r1=784260&r2=784261&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 Fri Jun 12 20:32:47 2009
@@ -380,6 +380,12 @@
         // detach from the version graph
         v.internalDetach();
 
+        // check if referenced by an activity
+        InternalActivityImpl activity = v.getActivity();
+        if (activity != null) {
+            activity.removeVersion(v);
+        }
+
         // remove from persistence state
         node.removeNode(v.getName());
 
@@ -518,6 +524,12 @@
         NodeId versionId = new NodeId(UUID.randomUUID());
         NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true);
 
+        // check for jcr:activity
+        if (src.hasProperty(NameConstants.JCR_ACTIVITY)) {
+            InternalValue act = src.getProperty(NameConstants.JCR_ACTIVITY).internalGetValue();
+            vNode.setPropertyValue(NameConstants.JCR_ACTIVITY, act);
+        }
+
         // initialize 'created', 'predecessors' and 'successors'
         vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(getCurrentTime()));
         vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);

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=784261&r1=784260&r2=784261&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 Fri Jun 12 20:32:47 2009
@@ -25,11 +25,11 @@
 
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.HashSet;
 import java.util.List;
+import java.util.ArrayList;
 
 /**
  * Implements a <code>InternalVersion</code>
@@ -45,7 +45,7 @@
     /**
      * the set of version labes of this history (values == String)
      */
-    private HashSet labelCache = null;
+    private HashSet<Name> labelCache = null;
 
     /**
      * specifies if this is the root version
@@ -208,8 +208,7 @@
      */
     public boolean isMoreRecent(InternalVersion v) {
         InternalVersion[] preds = getPredecessors();
-        for (int i = 0; i < preds.length; i++) {
-            InternalVersion pred = preds[i];
+        for (InternalVersion pred : preds) {
             if (pred.equals(v) || pred.isMoreRecent(v)) {
                 return true;
             }
@@ -281,14 +280,14 @@
     void internalDetach() throws RepositoryException {
         // detach this from all successors
         InternalVersion[] succ = getSuccessors();
-        for (int i = 0; i < succ.length; i++) {
-            ((InternalVersionImpl) succ[i]).internalDetachPredecessor(this, true);
+        for (InternalVersion aSucc : succ) {
+            ((InternalVersionImpl) aSucc).internalDetachPredecessor(this, true);
         }
 
         // detach cached successors from predecessors
         InternalVersion[] preds = getPredecessors();
-        for (int i = 0; i < preds.length; i++) {
-            ((InternalVersionImpl) preds[i]).internalDetachSuccessor(this, true);
+        for (InternalVersion pred : preds) {
+            ((InternalVersionImpl) pred).internalDetachSuccessor(this, true);
         }
 
         // clear properties
@@ -303,8 +302,8 @@
      */
     void internalAttach() throws RepositoryException {
         InternalVersion[] preds = getPredecessors();
-        for (int i = 0; i < preds.length; i++) {
-            ((InternalVersionImpl) preds[i]).internalAddSuccessor(this, true);
+        for (InternalVersion pred : preds) {
+            ((InternalVersionImpl) pred).internalAddSuccessor(this, true);
         }
     }
 
@@ -317,7 +316,7 @@
      */
     private void internalAddSuccessor(InternalVersionImpl succ, boolean store)
             throws RepositoryException {
-        List l = new ArrayList(Arrays.asList(getSuccessors()));
+        List<InternalVersion> l = new ArrayList<InternalVersion>(Arrays.asList(getSuccessors()));
         if (!l.contains(succ)) {
             l.add(succ);
             storeXCessors(l, NameConstants.JCR_SUCCESSORS, store);
@@ -337,7 +336,7 @@
     private void internalDetachPredecessor(InternalVersionImpl v, boolean store)
             throws RepositoryException {
         // remove 'v' from predecessor list
-        List l = new ArrayList(Arrays.asList(getPredecessors()));
+        List<InternalVersion> l = new ArrayList<InternalVersion>(Arrays.asList(getPredecessors()));
         l.remove(v);
 
         // attach V's predecessors
@@ -358,7 +357,7 @@
     private void internalDetachSuccessor(InternalVersionImpl v, boolean store)
             throws RepositoryException {
         // remove 'v' from successors list
-        List l = new ArrayList(Arrays.asList(getSuccessors()));
+        List<InternalVersion> l = new ArrayList<InternalVersion>(Arrays.asList(getSuccessors()));
         l.remove(v);
 
         // attach V's successors
@@ -374,7 +373,7 @@
      */
     boolean internalAddLabel(Name label) {
         if (labelCache == null) {
-            labelCache = new HashSet();
+            labelCache = new HashSet<Name>();
         }
         return labelCache.add(label);
     }
@@ -408,7 +407,7 @@
         if (labelCache == null) {
             return new Name[0];
         } else {
-            return (Name[]) labelCache.toArray(new Name[labelCache.size()]);
+            return labelCache.toArray(new Name[labelCache.size()]);
         }
     }
 
@@ -427,8 +426,8 @@
     void legacyResolveSuccessors() throws RepositoryException {
         InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);
         if (values != null) {
-            for (int i = 0; i < values.length; i++) {
-                NodeId vId = new NodeId(values[i].getUUID());
+            for (InternalValue value : values) {
+                NodeId vId = new NodeId(value.getUUID());
                 InternalVersionImpl v = (InternalVersionImpl) versionHistory.getVersion(vId);
                 v.internalAddSuccessor(this, false);
             }
@@ -455,4 +454,18 @@
     public int hashCode() {
         return getId().hashCode();
     }
+
+    /**
+     * Returns the activity of this version or <code>null</code> if not defined
+     * @return the activity or <code>null</code>
+     * @throws RepositoryException if an error occurs
+     */
+    public InternalActivityImpl getActivity() throws RepositoryException {
+        if (node.hasProperty(NameConstants.JCR_ACTIVITY)) {
+            NodeId actId = new NodeId(node.getPropertyValue(NameConstants.JCR_ACTIVITY).getUUID());
+            return (InternalActivityImpl) vMgr.getItem(actId);
+        } else {
+            return null;
+        }
+    }
 }

Modified: 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=784261&r1=784260&r2=784261&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/JcrVersionManagerImpl.java Fri Jun 12 20:32:47 2009
@@ -16,6 +16,12 @@
  */
 package org.apache.jackrabbit.core.version;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
@@ -23,8 +29,14 @@
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionHistory;
 
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.LazyItemIterator;
+import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
 
 /**
  * Implementation of the {@link javax.jcr.version.VersionManager}.
@@ -35,11 +47,22 @@
 public class JcrVersionManagerImpl implements javax.jcr.version.VersionManager {
 
     /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(JcrVersionManagerImpl.class);
+
+    /**
      * workspace session
      */
     private final SessionImpl session;
 
     /**
+     * the node id of the current activity
+     */
+    private NodeId currentActivity;
+
+
+    /**
      * Creates a new version manager for the given session
      * @param session workspace sesion
      */
@@ -186,42 +209,142 @@
      * {@inheritDoc}
      */
     public Node setActivity(Node activity) throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException("comming soon...");
+        Node oldActivity = getActivity();
+        if (activity == null) {
+            currentActivity = null;
+        } else {
+            NodeImpl actNode = (NodeImpl) activity;
+            if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
+                throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
+            }
+            currentActivity = actNode.getNodeId();
+        }
+        return oldActivity;
     }
 
     /**
      * {@inheritDoc}
      */
     public Node getActivity() throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException("comming soon...");
+        if (currentActivity == null) {
+            return null;
+        } else {
+            return session.getNodeById(currentActivity);
+        }
     }
 
     /**
      * {@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...");
+        NodeId id = session.getVersionManager().createActivity(session, title);
+        return session.getNodeById(id);
     }
 
     /**
      * {@inheritDoc}
      */
     public void removeActivity(Node node) throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException("comming soon...");
+        NodeImpl actNode = (NodeImpl) node;
+        if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
+            throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
+        }
+        NodeId actId = actNode.getNodeId();
+        session.getVersionManager().removeActivity(session, actId);
+        if (currentActivity.equals(actId)) {
+            currentActivity = null;
+        }
     }
 
     /**
      * {@inheritDoc}
      */
     public NodeIterator merge(Node activityNode) throws RepositoryException {
-        throw new UnsupportedRepositoryOperationException("comming soon...");
+        NodeImpl actNode = (NodeImpl) activityNode;
+        if (!actNode.isNodeType(NameConstants.NT_ACTIVITY)) {
+            throw new UnsupportedRepositoryOperationException("Given node is not an activity.");
+        }
+        InternalActivity activity = session.getVersionManager().getActivity(actNode.getNodeId());
+        if (activity == null) {
+            throw new UnsupportedRepositoryOperationException("Given activity not found.");
+        }
+        boolean success = false;
+        try {
+            NodeIterator ret = internalMerge(activity);
+            session.save();
+            success = true;
+            return ret;
+        } finally {
+            if (!success) {
+                // revert session
+                try {
+                    log.debug("reverting changes applied during merge...");
+                    session.refresh(false);
+                } catch (RepositoryException e) {
+                    log.error("Error while reverting changes applied merge restore.", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Internally does the merge without saving the changes.
+     * @param activity internal activity
+     * @throws RepositoryException if an error occurs
+     * @return a node iterator of all failed nodes
+     */
+    private NodeIterator internalMerge(InternalActivity activity)
+            throws RepositoryException {
+        List<ItemId> failedIds = new ArrayList<ItemId>();
+        Map<NodeId, InternalVersion> changeSet = activity.getChangeSet();
+        ChangeSetVersionSelector vsel = new ChangeSetVersionSelector(changeSet);
+        Iterator<NodeId> iter = changeSet.keySet().iterator();
+        while (iter.hasNext()) {
+            InternalVersion v = changeSet.remove(iter.next());
+            NodeId nodeId = new NodeId(v.getVersionHistory().getVersionableUUID());
+            try {
+                NodeImpl node = session.getNodeById(nodeId);
+                InternalVersion base = ((VersionImpl) node.getBaseVersion()).getInternalVersion();
+                VersionImpl version = (VersionImpl) session.getNodeById(v.getId());
+                // if base version is newer than version, add to failed list
+                // but merge it anyways
+                if (base.isMoreRecent(version.getInternalVersion())) {
+                    failedIds.add(node.getNodeId());
+                    // should we add it to the jcr:mergeFailed property ?
+                } else {
+                    Version[] vs = node.internalRestore(version, vsel, true);
+                    for (Version restored: vs) {
+                        changeSet.remove(((VersionImpl) restored).getNodeId());
+                    }
+                }
+            } catch (ItemNotFoundException e) {
+                // ignore nodes not present in this workspace (not best practice)
+            }
+
+            // reset iterator
+            iter = changeSet.keySet().iterator();
+        }
+        return new LazyItemIterator(session.getItemManager(), failedIds);
+    }
+
+    /**
+     * Internal version selector that selects the version in the changeset.
+     */
+    private class ChangeSetVersionSelector implements VersionSelector {
+
+        private final Map<NodeId, InternalVersion> changeSet;
+
+        private ChangeSetVersionSelector(Map<NodeId, InternalVersion> changeSet) {
+            this.changeSet = changeSet;
+        }
+
+        public Version select(VersionHistory vh) throws RepositoryException {
+            InternalVersion v = changeSet.get(((VersionHistoryImpl) vh).getNodeId());
+            if (v != null) {
+                return (Version) session.getNodeById(v.getId());
+            } else {
+                return null;
+            }
+        }
     }
-
 }
\ No newline at end of file

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=784261&r1=784260&r2=784261&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java Fri Jun 12 20:32:47 2009
@@ -40,6 +40,7 @@
 import java.util.Set;
 
 import javax.jcr.RepositoryException;
+import javax.jcr.PropertyType;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
 
@@ -436,6 +437,19 @@
     }
 
     /**
+     * Sets the given mixin types
+     * @param mixinTypeNames the mixin type names
+     * @throws RepositoryException if an error occurs
+     */
+    public void setMixins(Set<Name> mixinTypeNames) throws RepositoryException {
+        nodeState.setMixinTypeNames(mixinTypeNames);
+        // update jcr:mixinTypes property
+        setPropertyValues(NameConstants.JCR_MIXINTYPES, PropertyType.NAME,
+                InternalValue.create(
+                        mixinTypeNames.toArray(new Name[mixinTypeNames.size()]))
+        );
+    }
+    /**
      * creates a new child node
      *
      * @param name

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java?rev=784261&r1=784260&r2=784261&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java Fri Jun 12 20:32:47 2009
@@ -69,6 +69,15 @@
     Version checkin(NodeImpl node) throws RepositoryException;
 
     /**
+     * invokes the checkout() on the persistent version manager.
+     *
+     * @param node node to checkout
+     * @return the base version
+     * @throws RepositoryException if an error occurs
+     */
+    Version checkout(NodeImpl node) throws RepositoryException;
+
+    /**
      * Removes the specified version from the given version history.
      * @param history version history to remove the version from
      * @param versionName name of the version
@@ -126,6 +135,15 @@
     InternalVersion getVersion(NodeId id) throws RepositoryException;
 
     /**
+     * Returns the activity with the given id
+     *
+     * @param id id of the activity to retrieve
+     * @return the activity.
+     * @throws RepositoryException if an error occurs
+     */
+    InternalActivity getActivity(NodeId id) throws RepositoryException;
+
+    /**
      * Returns the head version of the node with the given id. this is always
      * the last of all versions. this only works correctly for liner version
      * graphs (i.e. simple versioning)
@@ -137,6 +155,23 @@
     InternalVersion getHeadVersionOfNode(NodeId id) throws RepositoryException;
 
     /**
+     * Creates a new activity
+     * @param session the current session
+     * @param title title of the new activity
+     * @return the nodeid of the new activity
+     * @throws RepositoryException if an error occurs
+     */
+    NodeId createActivity(Session session, String title) throws RepositoryException;
+
+    /**
+     * Removes an activity and all 
+     * @param session the current session
+     * @param nodeId id of the activity to remove
+     * @throws RepositoryException if an error occurs
+     */
+    void removeActivity(Session session, NodeId nodeId) throws RepositoryException;
+
+    /**
      * Close this version manager. After having closed a persistence
      * manager, further operations on this object are treated as illegal
      * and throw



Mime
View raw message