jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tri...@apache.org
Subject svn commit: r191172 [1/2] - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: ./ nodetype/ version/ version/persistence/
Date Fri, 17 Jun 2005 16:18:15 GMT
Author: tripod
Date: Fri Jun 17 09:18:13 2005
New Revision: 191172

URL: http://svn.apache.org/viewcvs?rev=191172&view=rev
Log:
[JCR-127] Speedup Startup
          Removing one layer in versioning, thus mapping virtual items
          directly from the peristence layer.

Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java   (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java   (with props)
Removed:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/HistoryRootNodeState.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionLabels.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionHistoryNodeState.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionLabelsNodeState.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionNodeState.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/persistence/
Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManagerImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionSelector.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/package.html

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java?rev=191172&r1=191171&r2=191172&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/RepositoryImpl.java Fri Jun 17 09:18:13 2005
@@ -65,10 +65,8 @@
 import org.apache.jackrabbit.core.state.PersistenceManager;
 import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import org.apache.jackrabbit.core.util.uuid.UUID;
-import org.apache.jackrabbit.core.version.PersistentVersionManager;
 import org.apache.jackrabbit.core.version.VersionManager;
 import org.apache.jackrabbit.core.version.VersionManagerImpl;
-import org.apache.jackrabbit.core.version.persistence.NativePVM;
 import org.apache.log4j.Logger;
 
 /**
@@ -104,7 +102,6 @@
 
     private final NamespaceRegistryImpl nsReg;
     private final NodeTypeRegistry ntReg;
-    private final PersistentVersionManager pvMgr;
     private final VersionManager vMgr;
     private final VirtualNodeTypeStateManager virtNTMgr;
 
@@ -192,8 +189,7 @@
                 rootNodeUUID,
                 nsReg,
                 ntReg);
-        pvMgr = new NativePVM(pm, getNodeTypeRegistry());
-        vMgr = new VersionManagerImpl(pvMgr, ntReg, delegatingDispatcher,
+        vMgr = new VersionManagerImpl(pm, ntReg, delegatingDispatcher,
                 VERSION_STORAGE_NODE_UUID, SYSTEM_ROOT_NODE_UUID);
 
         // init virtual nodetype manager
@@ -663,11 +659,6 @@
          * todo further cleanup tasks, free resources, etc.
          */
         try {
-            pvMgr.close();
-        } catch (Exception e) {
-            log.error("Error while closing Persistent Version Manager.", e);
-        }
-        try {
             vMgr.close();
         } catch (Exception e) {
             log.error("Error while closing Version Manager.", e);
@@ -1108,7 +1099,7 @@
                             getPersistenceManager(config.getPersistenceManagerConfig()),
                             rootNodeUUID, ntReg);
                     try {
-                        itemStateMgr.addVirtualItemStateProvider(vMgr.getVirtualItemStateProvider(itemStateMgr));
+                        itemStateMgr.addVirtualItemStateProvider(vMgr.getVirtualItemStateProvider());
                         itemStateMgr.addVirtualItemStateProvider(virtNTMgr.getVirtualItemStateProvider());
                     } catch (Exception e) {
                         log.error("Unable to add vmgr: " + e.toString(), e);

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml?rev=191172&r1=191171&r2=191172&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml Fri Jun 17 09:18:13 2005
@@ -369,6 +369,11 @@
                 <requiredPrimaryType>nt:versionHistory</requiredPrimaryType>
             </requiredPrimaryTypes>
         </childNodeDefinition>
+        <childNodeDefinition name="*" defaultPrimaryType="rep:versionStorage" autoCreated="false" mandatory="false" onParentVersion="ABORT" protected="true" sameNameSiblings="true">
+            <requiredPrimaryTypes>
+                <requiredPrimaryType>rep:versionStorage</requiredPrimaryType>
+            </requiredPrimaryTypes>
+        </childNodeDefinition>
     </nodeType>
     <nodeType name="rep:nodeTypes" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
         <supertypes>
@@ -379,33 +384,6 @@
                 <requiredPrimaryType>nt:nodeType</requiredPrimaryType>
             </requiredPrimaryTypes>
         </childNodeDefinition>
-    </nodeType>
-
-    <!-- internal node types for persistent version manager -->
-    <nodeType name="rep:versionHistory" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
-        <supertypes>
-            <supertype>nt:unstructured</supertype>
-        </supertypes>
-    </nodeType>
-    <nodeType name="rep:versionLabels" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
-        <supertypes>
-            <supertype>nt:unstructured</supertype>
-        </supertypes>
-    </nodeType>
-    <nodeType name="rep:version" isMixin="false" hasOrderableChildNodes="false" primaryItemName="">
-        <supertypes>
-            <supertype>nt:unstructured</supertype>
-        </supertypes>
-    </nodeType>
-    <nodeType name="rep:frozen" isMixin="false" hasOrderableChildNodes="true" primaryItemName="">
-        <supertypes>
-            <supertype>nt:unstructured</supertype>
-        </supertypes>
-    </nodeType>
-    <nodeType name="rep:frozenVersionHistory" isMixin="false" hasOrderableChildNodes="true" primaryItemName="">
-        <supertypes>
-            <supertype>nt:unstructured</supertype>
-        </supertypes>
     </nodeType>
 
 </nodeTypes>

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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;
+
+/**
+ * Implements a <code>InternalFreeze</code>
+ */
+abstract class InternalFreezeImpl extends InternalVersionItemImpl
+        implements InternalFreeze {
+
+    /**
+     * The parent item
+     */
+    private final InternalVersionItem parent;
+
+    /**
+     * Creates a new <code>InternalFreezeImpl</code>
+     *
+     * @param vMgr
+     * @param parent
+     */
+    protected InternalFreezeImpl(VersionManagerImpl vMgr, InternalVersionItem parent) {
+        super(vMgr);
+        this.parent = parent;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionItem getParent() {
+        return parent;
+    }
+
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java
------------------------------------------------------------------------------
    svn = 

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

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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 org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.PropertyImpl;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.OnParentVersionAction;
+import javax.jcr.version.VersionException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Implements a <code>InternalFrozenNode</code>
+ */
+public class InternalFrozenNodeImpl extends InternalFreezeImpl
+        implements InternalFrozenNode, Constants {
+
+    /**
+     * checkin mode version.
+     */
+    private static final int MODE_VERSION = 0;
+
+    /**
+     * checkin mode copy. specifies, that the items are always copied.
+     */
+    private static final int MODE_COPY = 1;
+
+    /**
+     * mode flag specifies, that the mode should be recursed. otherwise i
+     * will be redetermined by the opv.
+     */
+    private static final int MODE_COPY_RECURSIVE = 3;
+
+    /**
+     * the underlying persistance node
+     */
+    private NodeStateEx node;
+
+    /**
+     * the list of frozen properties
+     */
+    private PropertyState[] frozenProperties;
+
+    /**
+     * the frozen uuid of the original node
+     */
+    private String frozenUUID = null;
+
+    /**
+     * the frozen primary type of the orginal node
+     */
+    private QName frozenPrimaryType = null;
+
+    /**
+     * the frozen list of mixin types of the original node
+     */
+    private QName[] frozenMixinTypes = null;
+
+    /**
+     * Creates a new frozen node based on the given persistance node.
+     *
+     * @param node
+     * @throws javax.jcr.RepositoryException
+     */
+    public InternalFrozenNodeImpl(VersionManagerImpl vMgr, NodeStateEx node,
+                                  InternalVersionItem parent)
+            throws RepositoryException {
+        super(vMgr, parent);
+        this.node = node;
+
+        // init the frozen properties
+        PropertyState[] props;
+        try {
+            props = node.getProperties();
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+        List propList = new ArrayList();
+
+        for (int i = 0; i < props.length; i++) {
+            PropertyState prop = props[i];
+            if (prop.getName().equals(JCR_FROZENUUID)) {
+                // special property
+                frozenUUID = node.getPropertyValue(JCR_FROZENUUID).internalValue().toString();
+            } else if (prop.getName().equals(JCR_FROZENPRIMARYTYPE)) {
+                // special property
+                frozenPrimaryType = (QName) node.getPropertyValue(JCR_FROZENPRIMARYTYPE).internalValue();
+            } else if (prop.getName().equals(JCR_FROZENMIXINTYPES)) {
+                // special property
+                InternalValue[] values = node.getPropertyValues(JCR_FROZENMIXINTYPES);
+                if (values == null) {
+                    frozenMixinTypes = new QName[0];
+                } else {
+                    frozenMixinTypes = new QName[values.length];
+                    for (int j = 0; j < values.length; j++) {
+                        frozenMixinTypes[j] = (QName) values[j].internalValue();
+                    }
+                }
+            } else if (prop.getName().equals(JCR_PRIMARYTYPE)) {
+                // ignore
+            } else if (prop.getName().equals(JCR_UUID)) {
+                // ignore
+            } else {
+                propList.add(prop);
+            }
+        }
+        frozenProperties = (PropertyState[]) propList.toArray(new PropertyState[propList.size()]);
+
+        // do some checks
+        if (frozenMixinTypes == null) {
+            frozenMixinTypes = new QName[0];
+        }
+        if (frozenPrimaryType == null) {
+            throw new RepositoryException("Illegal frozen node. Must have 'frozenPrimaryType'");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getName() {
+        return node.getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getId() {
+        return node.getUUID();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalFreeze[] getFrozenChildNodes() throws VersionException {
+        try {
+            // maybe add iterator?
+            List entries = node.getState().getChildNodeEntries();
+            InternalFreeze[] freezes = new InternalFreeze[entries.size()];
+            Iterator iter = entries.iterator();
+            int i = 0;
+            while (iter.hasNext()) {
+                NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
+                freezes[i++] = (InternalFreeze) getVersionManager().getItem(entry.getUUID());
+            }
+            return freezes;
+        } catch (RepositoryException e) {
+            throw new VersionException("Unable to retrieve frozen child nodes", e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasFrozenHistory(String uuid) {
+        try {
+            List entries = node.getState().getChildNodeEntries(uuid);
+            if (entries.size() > 0) {
+                return getVersionManager().getItem(uuid) instanceof InternalFrozenVersionHistory;
+            }
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PropertyState[] getFrozenProperties() {
+        return frozenProperties;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getFrozenUUID() {
+        return frozenUUID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getFrozenPrimaryType() {
+        return frozenPrimaryType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName[] getFrozenMixinTypes() {
+        return frozenMixinTypes;
+    }
+
+    /**
+     * Checks-in a <code>src</code> node. It creates a new child node of
+     * <code>parent</code> with the given <code>name</code> and adds the
+     * source nodes properties according to their OPV value to the
+     * list of frozen properties. It creates frozen child nodes for each child
+     * node of <code>src</code> according to its OPV value.
+     *
+     * @param parent
+     * @param name
+     * @param src
+     * @return
+     * @throws RepositoryException
+     */
+    protected static NodeStateEx checkin(NodeStateEx parent, QName name,
+                                            NodeImpl src)
+            throws RepositoryException {
+        return checkin(parent, name, src, MODE_VERSION);
+    }
+
+    /**
+     * Checks-in a <code>src</code> node. It creates a new child node of
+     * <code>parent</code> with the given <code>name</code> and adds the
+     * source nodes properties according to their OPV value to the
+     * list of frozen properties. It creates frozen child nodes for each child
+     * node of <code>src</code> according to its OPV value.
+     *
+     * @param parent
+     * @param name
+     * @param src
+     * @return
+     * @throws RepositoryException
+     */
+    private static NodeStateEx checkin(NodeStateEx parent, QName name,
+                                            NodeImpl src, int mode)
+            throws RepositoryException {
+
+        // create new node
+        NodeStateEx node = parent.addNode(name, NT_FROZENNODE, null, true);
+
+        // initialize the internal properties
+        if (src.isNodeType(MIX_REFERENCEABLE)) {
+            node.setPropertyValue(JCR_FROZENUUID, InternalValue.create(src.getUUID()));
+        }
+        node.setPropertyValue(JCR_FROZENPRIMARYTYPE,
+                InternalValue.create(((NodeTypeImpl) src.getPrimaryNodeType()).getQName()));
+        if (src.hasProperty(NodeImpl.JCR_MIXINTYPES)) {
+            NodeType[] mixins = src.getMixinNodeTypes();
+            InternalValue[] ivalues = new InternalValue[mixins.length];
+            for (int i = 0; i < mixins.length; i++) {
+                ivalues[i] = InternalValue.create(((NodeTypeImpl) mixins[i]).getQName());
+            }
+            node.setPropertyValues(JCR_FROZENMIXINTYPES, PropertyType.NAME, ivalues);
+        }
+
+        // add the properties
+        PropertyIterator piter = src.getProperties();
+        while (piter.hasNext()) {
+            PropertyImpl prop = (PropertyImpl) piter.nextProperty();
+            int opv;
+            if ((mode & MODE_COPY) > 0) {
+                opv = OnParentVersionAction.COPY;
+            } else {
+                opv = prop.getDefinition().getOnParentVersion();
+            }
+            switch (opv) {
+                case OnParentVersionAction.ABORT:
+                    parent.reload();
+                    throw new VersionException("Checkin aborted due to OPV in " + prop.safeGetJCRPath());
+                case OnParentVersionAction.COMPUTE:
+                case OnParentVersionAction.IGNORE:
+                case OnParentVersionAction.INITIALIZE:
+                    break;
+                case OnParentVersionAction.VERSION:
+                case OnParentVersionAction.COPY:
+                    node.copyFrom(prop);
+                    break;
+            }
+        }
+
+        // add the frozen children and vistories
+        NodeIterator niter = src.getNodes();
+        while (niter.hasNext()) {
+            NodeImpl child = (NodeImpl) niter.nextNode();
+            int opv;
+            if ((mode & MODE_COPY_RECURSIVE) > 0) {
+                opv = OnParentVersionAction.COPY;
+            } else {
+                opv = child.getDefinition().getOnParentVersion();
+            }
+            switch (opv) {
+                case OnParentVersionAction.ABORT:
+                    throw new VersionException("Checkin aborted due to OPV in " + child.safeGetJCRPath());
+                case OnParentVersionAction.COMPUTE:
+                case OnParentVersionAction.IGNORE:
+                case OnParentVersionAction.INITIALIZE:
+                    break;
+                case OnParentVersionAction.VERSION:
+                    if (child.isNodeType(MIX_VERSIONABLE)) {
+                        // create frozen versionable child
+                        NodeStateEx newChild = node.addNode(child.getQName(), NT_VERSIONEDCHILD, null, false);
+                        newChild.setPropertyValue(JCR_VERSIONHISTORY,
+                                InternalValue.create(child.getVersionHistory().getUUID()));
+                        newChild.setPropertyValue(JCR_BASEVERSION,
+                                InternalValue.create(child.getBaseVersion().getUUID()));
+                        break;
+                    }
+                    // else copy but do not recurse
+                    checkin(node, child.getQName(), child, MODE_COPY);
+                    break;
+                case OnParentVersionAction.COPY:
+                    checkin(node, child.getQName(), child, MODE_COPY_RECURSIVE);
+                    break;
+            }
+        }
+        return node;
+    }
+
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
------------------------------------------------------------------------------
    svn = 

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

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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 org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.QName;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.version.VersionException;
+
+/**
+ * Implements a <code>InternalFrozenVersionHistory</code>
+ */
+public class InternalFrozenVHImpl extends InternalFreezeImpl
+        implements InternalFrozenVersionHistory {
+
+    /**
+     * the underlying persistence node
+     */
+    private NodeStateEx node;
+
+    /**
+     * Creates a new frozen version history.
+     *
+     * @param node
+     */
+    public InternalFrozenVHImpl(VersionManagerImpl vMgr, NodeStateEx node,
+                                InternalVersionItem parent) {
+        super(vMgr, parent);
+        this.node = node;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getName() {
+        return node.getName();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getId() {
+        return node.getUUID();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getVersionHistoryId() {
+        return (String) node.getPropertyValue(Constants.JCR_VERSIONHISTORY).internalValue();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionHistory getVersionHistory()
+            throws VersionException {
+        try {
+            return getVersionManager().getVersionHistory(getVersionHistoryId());
+        } catch (RepositoryException e) {
+            throw new VersionException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBaseVersionId() {
+        return (String) node.getPropertyValue(Constants.JCR_BASEVERSION).internalValue();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getBaseVesion()
+            throws VersionException {
+        try {
+            InternalVersionHistory history = getVersionManager().getVersionHistory(getVersionHistoryId());
+            return history.getVersion(getBaseVersionId());
+        } catch (RepositoryException e) {
+            throw new VersionException(e);
+        }
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java
------------------------------------------------------------------------------
    svn = 

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

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java?rev=191172&r1=191171&r2=191172&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java Fri Jun 17 09:18:13 2005
@@ -18,6 +18,7 @@
 
 import org.apache.jackrabbit.core.QName;
 
+import javax.jcr.version.Version;
 import java.util.Calendar;
 
 /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java?rev=191172&r1=191171&r2=191172&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java Fri Jun 17 09:18:13 2005
@@ -19,7 +19,6 @@
 import org.apache.jackrabbit.core.QName;
 
 import javax.jcr.version.VersionException;
-import javax.jcr.RepositoryException;
 import java.util.Iterator;
 
 /**
@@ -75,37 +74,6 @@
      * @see javax.jcr.version.VersionHistory#getVersionByLabel(java.lang.String)
      */
     InternalVersion getVersionByLabel(QName label);
-
-    /**
-     * 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.
-     *
-     * @param versionName the name of the version to be removed
-     * @throws RepositoryException if an error occurrs.
-     */
-    void removeVersion(QName versionName) throws RepositoryException;
-
-    /**
-     * 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 version 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
-     */
-    InternalVersion setVersionLabel(QName version, QName label, boolean move)
-            throws VersionException;
 
     /**
      * Returns an iterator over all versions (not ordered yet), including the

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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 org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.util.uuid.UUID;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.log4j.Logger;
+
+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.List;
+import java.util.Set;
+
+/**
+ * Implements a <code>InternalVersionHistory</code>
+ */
+public class InternalVersionHistoryImpl extends InternalVersionItemImpl
+        implements InternalVersionHistory, Constants {
+
+    /**
+     * default logger
+     */
+    private static Logger log = Logger.getLogger(InternalVersionHistory.class);
+
+    /**
+     * the cache of the version labels
+     * key = version label (String)
+     * value = version
+     */
+    private HashMap labelCache = new HashMap();
+
+    /**
+     * the root version of this history
+     */
+    private InternalVersion rootVersion;
+
+    /**
+     * the hashmap of all versions
+     * key = versionId (String)
+     * value = version
+     */
+    private HashMap versionCache = new HashMap();
+
+    /**
+     * The nodes state of this version history
+     */
+    private NodeStateEx node;
+
+    /**
+     * the node that holds the label nodes
+     */
+    private NodeStateEx labelNode;
+
+    /**
+     * the id of this history
+     */
+    private String historyId;
+
+    /**
+     * the if of the versionable node
+     */
+    private String versionableId;
+
+    /**
+     * Creates a new VersionHistory object for the given node state.
+     */
+    public InternalVersionHistoryImpl(VersionManagerImpl vMgr, NodeStateEx node)
+            throws RepositoryException {
+        super(vMgr);
+        this.node = node;
+        init();
+    }
+
+    /**
+     * Initialies the history and loads all internal caches
+     *
+     * @throws RepositoryException
+     */
+    private void init() throws RepositoryException {
+        versionCache.clear();
+        labelCache.clear();
+
+        // get id
+        historyId = node.getUUID();
+
+        // get versionable id
+        versionableId = (String) node.getPropertyValue(JCR_VERSIONABLEUUID).internalValue();
+
+        // get entries
+        NodeStateEx[] children = node.getChildNodes();
+        for (int i = 0; i < children.length; i++) {
+            NodeStateEx child = children[i];
+            if (child.getName().equals(JCR_VERSIONLABELS)) {
+                labelNode = child;
+                continue;
+            }
+            InternalVersionImpl v = new InternalVersionImpl(this, child, child.getName());
+            versionCache.put(v.getId(), v);
+            if (v.isRootVersion()) {
+                rootVersion = v;
+            }
+        }
+
+        // resolve successors and predecessors
+        Iterator iter = versionCache.values().iterator();
+        while (iter.hasNext()) {
+            InternalVersionImpl v = (InternalVersionImpl) iter.next();
+            v.resolvePredecessors();
+        }
+
+        try {
+            // init label cache
+            PropertyState[] labels = labelNode.getProperties();
+            for (int i = 0; i < labels.length; i++) {
+                PropertyState pState = labels[i];
+                if (pState.getType() == PropertyType.REFERENCE) {
+                    QName name = pState.getName();
+                    UUID ref = (UUID) pState.getValues()[0].internalValue();
+                    InternalVersionImpl v = (InternalVersionImpl) getVersion(ref.toString());
+                    labelCache.put(name, v);
+                    v.internalAddLabel(name);
+                }
+            }
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getId() {
+        return historyId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionItem getParent() {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getRootVersion() {
+        return rootVersion;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getVersion(QName versionName) throws VersionException {
+        // maybe add cache by name?
+        Iterator iter = versionCache.values().iterator();
+        while (iter.hasNext()) {
+            InternalVersion v = (InternalVersion) iter.next();
+            if (v.getName().equals(versionName)) {
+                return v;
+            }
+        }
+        throw new VersionException("Version " + versionName + " does not exist.");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasVersion(QName versionName) {
+        // maybe add cache?
+        Iterator iter = versionCache.values().iterator();
+        while (iter.hasNext()) {
+            InternalVersion v = (InternalVersion) iter.next();
+            if (v.getName().equals(versionName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasVersion(String uuid) {
+        return versionCache.containsKey(uuid);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getVersion(String uuid) {
+        return (InternalVersion) versionCache.get(uuid);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getVersionByLabel(QName label) {
+        return (InternalVersion) labelCache.get(label);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Iterator getVersions() {
+        return versionCache.values().iterator();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int getNumVersions() {
+        return versionCache.size();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getVersionableUUID() {
+        return versionableId;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName[] getVersionLabels() {
+        return (QName[]) labelCache.keySet().toArray(new QName[labelCache.size()]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getVersionLabelsUUID() {
+        return labelNode.getUUID();
+    }
+
+    /**
+     * 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.
+     *
+     * @param versionName
+     * @throws VersionException
+     */
+    void removeVersion(QName 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
+        List refs = getVersionManager().getItemReferences(v);
+        if (!refs.isEmpty()) {
+            throw new ReferentialIntegrityException("Unable to remove version. At least once referenced.");
+        }
+
+        // remove from persistance state
+        node.removeNode(v.getName());
+
+        // unregister from labels
+        QName[] labels = v.internalGetLabels();
+        for (int i = 0; i < labels.length; i++) {
+            v.internalRemoveLabel(labels[i]);
+            labelNode.removeProperty(labels[i]);
+        }
+        // detach from the version graph
+        v.internalDetach();
+
+        // and remove from history
+        versionCache.remove(v.getId());
+
+        // store changes
+        node.store();
+    }
+
+    /**
+     * 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
+     */
+    InternalVersion setVersionLabel(QName versionName, QName 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.");
+        }
+        InternalVersionImpl prev = (InternalVersionImpl) labelCache.get(label);
+        if (prev == null) {
+            if (version == null) {
+                return null;
+            }
+        } else {
+            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(new UUID(version.getId())));
+            }
+            labelNode.store();
+        } catch (RepositoryException e) {
+            throw new VersionException(e);
+        }
+
+        // update internal structures
+        if (prev != null) {
+            prev.internalRemoveLabel(label);
+            labelCache.remove(label);
+        }
+        if (version != null) {
+            labelCache.put(label, version);
+            ((InternalVersionImpl) version).internalAddLabel(label);
+        }
+        return prev;
+    }
+
+    /**
+     * 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
+     */
+    InternalVersionImpl checkin(QName name, NodeImpl src)
+            throws RepositoryException {
+
+        // copy predecessors from src node
+        Value[] preds = src.getProperty(JCR_PREDECESSORS).getValues();
+        InternalValue[] predecessors = new InternalValue[preds.length];
+        for (int i = 0; i < preds.length; i++) {
+            String predId = preds[i].getString();
+            // check if version exist
+            if (!versionCache.containsKey(predId)) {
+                throw new RepositoryException("invalid predecessor in source node");
+            }
+            predecessors[i] = InternalValue.create(new UUID(predId));
+        }
+
+        String versionId = UUID.randomUUID().toString();
+        NodeStateEx vNode = node.addNode(name, NT_VERSION, versionId, true);
+
+        // initialize 'created' and 'predecessors'
+        vNode.setPropertyValue(JCR_CREATED, InternalValue.create(Calendar.getInstance()));
+        vNode.setPropertyValues(JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);
+
+        // initialize 'empty' successors; their values are dynamically resolved
+        vNode.setPropertyValues(JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
+
+        // checkin source node
+        InternalFrozenNodeImpl.checkin(vNode, JCR_FROZENNODE, src);
+
+        // update version graph
+        InternalVersionImpl version = new InternalVersionImpl(this, vNode, name);
+        version.resolvePredecessors();
+
+        // and store
+        node.store();
+
+        // update cache
+        versionCache.put(version.getId(), version);
+
+        return version;
+    }
+
+    /**
+     * Creates a new <code>InternalVersionHistory</code> below the given parent
+     * node and with the given name.
+     *
+     * @param parent
+     * @param name
+     * @return
+     * @throws RepositoryException
+     */
+    static InternalVersionHistoryImpl create(VersionManagerImpl vMgr,
+                                             NodeStateEx parent,
+                                             String historyId, QName name,
+                                             NodeState nodeState)
+            throws RepositoryException {
+
+        // create history node
+        NodeStateEx pNode = parent.addNode(name, NT_VERSIONHISTORY, historyId, true);
+
+        // set the versionable uuid
+        pNode.setPropertyValue(JCR_VERSIONABLEUUID, InternalValue.create(nodeState.getUUID()));
+
+        // create label node
+        pNode.addNode(JCR_VERSIONLABELS, NT_VERSIONLABELS, null, false);
+
+        // create root version
+        String versionId = UUID.randomUUID().toString();
+
+        NodeStateEx vNode = pNode.addNode(JCR_ROOTVERSION, NT_VERSION, versionId, true);
+
+        // initialize 'created' and 'predecessors'
+        vNode.setPropertyValue(JCR_CREATED, InternalValue.create(Calendar.getInstance()));
+        vNode.setPropertyValues(JCR_PREDECESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
+        vNode.setPropertyValues(JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
+
+        // add also an empty frozen node to the root version
+        NodeStateEx node = vNode.addNode(JCR_FROZENNODE, NT_FROZENNODE, null, true);
+
+        // initialize the internal properties
+        node.setPropertyValue(JCR_FROZENUUID, InternalValue.create(nodeState.getUUID()));
+        node.setPropertyValue(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((QName) iter.next());
+            }
+            node.setPropertyValues(JCR_FROZENMIXINTYPES, PropertyType.NAME, ivalues);
+        }
+
+        parent.store();
+        return new InternalVersionHistoryImpl(vMgr, pNode);
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
------------------------------------------------------------------------------
    svn = 

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

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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 org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.util.uuid.UUID;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.HashSet;
+
+/**
+ * Implements a <code>InternalVersion</code>
+ */
+public class InternalVersionImpl extends InternalVersionItemImpl
+        implements InternalVersion, Constants {
+
+    /**
+     * the list/cache of predecessors (values == InternalVersion)
+     */
+    private ArrayList predecessors = new ArrayList();
+
+    /**
+     * the list of successors (values == InternalVersion)
+     */
+    private ArrayList successors = new ArrayList();
+
+    /**
+     * the underlying persistance node of this version
+     */
+    private NodeStateEx node;
+
+    /**
+     * the date when this version was created
+     */
+    private Calendar created;
+
+    /**
+     * the set of version labes of this history (values == String)
+     */
+    private HashSet labelCache = null;
+
+    /**
+     * specifies if this is the root version
+     */
+    private final boolean isRoot;
+
+    /**
+     * the version name
+     */
+    private final QName name;
+
+    /**
+     * the version history
+     */
+    private final InternalVersionHistory versionHistory;
+
+    /**
+     * Creates a new internal version with the given version history and
+     * persistance node. please note, that versions must be created by the
+     * version history.
+     *
+     * @param node
+     */
+    public InternalVersionImpl(InternalVersionHistoryImpl vh, NodeStateEx node, QName name) {
+        super(vh.getVersionManager());
+        this.versionHistory = vh;
+        this.node = node;
+        this.name = name;
+
+        // init internal values
+        InternalValue[] values = node.getPropertyValues(JCR_CREATED);
+        if (values != null) {
+            created = (Calendar) values[0].internalValue();
+        }
+        isRoot = name.equals(JCR_ROOTVERSION);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getId() {
+        return node.getUUID();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionItem getParent() {
+        return versionHistory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getName() {
+        return name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalFrozenNode getFrozenNode() {
+        // get frozen node
+        try {
+            NodeState.ChildNodeEntry entry = node.getState().getChildNodeEntry(JCR_FROZENNODE, 1);
+            if (entry == null) {
+                throw new InternalError("version has no frozen node: " + getId());
+            }
+            return (InternalFrozenNode) getVersionManager().getItem(entry.getUUID());
+        } catch (RepositoryException e) {
+            throw new IllegalStateException("unable to retrieve frozen node: " + e);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Calendar getCreated() {
+        return created;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion[] getSuccessors() {
+        return (InternalVersionImpl[]) successors.toArray(new InternalVersionImpl[successors.size()]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion[] getPredecessors() {
+        return (InternalVersionImpl[]) predecessors.toArray(new InternalVersionImpl[predecessors.size()]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isMoreRecent(InternalVersion v) {
+        for (int i = 0; i < predecessors.size(); i++) {
+            InternalVersion pred = (InternalVersion) predecessors.get(i);
+            if (pred.equals(v) || pred.isMoreRecent(v)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionHistory getVersionHistory() {
+        return versionHistory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasLabel(QName label) {
+        return internalHasLabel(label);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName[] getLabels() {
+        return internalGetLabels();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isRootVersion() {
+        return isRoot;
+    }
+
+    /**
+     * resolves the predecessors property and indirectly adds it self to their
+     * successor list.
+     */
+    void resolvePredecessors() {
+        InternalValue[] values = node.getPropertyValues(JCR_PREDECESSORS);
+        if (values != null) {
+            for (int i = 0; i < values.length; i++) {
+                InternalVersionImpl v = (InternalVersionImpl) versionHistory.getVersion(values[i].internalValue().toString());
+                predecessors.add(v);
+                v.addSuccessor(this);
+            }
+        }
+    }
+
+    /**
+     * adds a successor version to the internal cache
+     *
+     * @param successor
+     */
+    private void addSuccessor(InternalVersion successor) {
+        successors.add(successor);
+    }
+
+    /**
+     * stores the internal predecessor cache to the persistance node
+     *
+     * @throws RepositoryException
+     */
+    private void storePredecessors() throws RepositoryException {
+        InternalValue[] values = new InternalValue[predecessors.size()];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = InternalValue.create(new UUID(((InternalVersion) predecessors.get(i)).getId()));
+        }
+        node.setPropertyValues(JCR_PREDECESSORS, PropertyType.STRING, values);
+    }
+
+    /**
+     * Detaches itself from the version graph.
+     *
+     * @throws RepositoryException
+     */
+    void internalDetach() throws RepositoryException {
+        // detach this from all successors
+        InternalVersionImpl[] succ = (InternalVersionImpl[]) getSuccessors();
+        for (int i = 0; i < succ.length; i++) {
+            succ[i].internalDetachPredecessor(this);
+        }
+
+        // detach cached successors from preds
+        InternalVersionImpl[] preds = (InternalVersionImpl[]) getPredecessors();
+        for (int i = 0; i < preds.length; i++) {
+            preds[i].internalDetachSuccessor(this);
+        }
+
+        // clear properties
+        successors.clear();
+        predecessors.clear();
+        labelCache = null;
+    }
+
+    /**
+     * Removes the predecessor V of this predecessors list and adds all of Vs
+     * predecessors to it.
+     * <p/>
+     * please note, that this operation might corrupt the version graph
+     *
+     * @param v the successor to detach
+     */
+    private void internalDetachPredecessor(InternalVersionImpl v) throws RepositoryException {
+        // remove 'v' from predecessor list
+        for (int i = 0; i < predecessors.size(); i++) {
+            if (predecessors.get(i).equals(v)) {
+                predecessors.remove(i);
+                break;
+            }
+        }
+        // attach v's predecessors
+        predecessors.addAll(Arrays.asList(v.getPredecessors()));
+        storePredecessors();
+        node.store();
+    }
+
+    /**
+     * Removes the successor V of this successors list and adds all of Vs
+     * successors to it.
+     * <p/>
+     * please note, that this operation might corrupt the version graph
+     *
+     * @param v the successor to detach
+     */
+    private void internalDetachSuccessor(InternalVersionImpl v) {
+        // remove 'v' from successors list
+        for (int i = 0; i < successors.size(); i++) {
+            if (successors.get(i).equals(v)) {
+                successors.remove(i);
+                break;
+            }
+        }
+        // attach v's successors
+        successors.addAll(Arrays.asList(v.getSuccessors()));
+    }
+
+    /**
+     * adds a label to the label cache. does not affect storage
+     *
+     * @param label
+     * @return
+     */
+    boolean internalAddLabel(QName label) {
+        if (labelCache == null) {
+            labelCache = new HashSet();
+        }
+        return labelCache.add(label);
+    }
+
+    /**
+     * removes a label from the label cache. does not affect storage
+     *
+     * @param label
+     * @return
+     */
+    boolean internalRemoveLabel(QName label) {
+        if (labelCache == null) {
+            return false;
+        } else {
+            return labelCache.remove(label);
+        }
+    }
+
+    /**
+     * checks, if a label is in the label cache
+     *
+     * @param label
+     * @return
+     */
+    boolean internalHasLabel(QName label) {
+        if (labelCache == null) {
+            return false;
+        } else {
+            return labelCache.contains(label);
+        }
+    }
+
+    /**
+     * returns the array of the cached labels
+     *
+     * @return
+     */
+    QName[] internalGetLabels() {
+        if (labelCache == null) {
+            return new QName[0];
+        } else {
+            return (QName[]) labelCache.toArray(new QName[labelCache.size()]);
+        }
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
------------------------------------------------------------------------------
    svn = 

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

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed 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;
+
+/**
+ * Implements a <code>InternalVersionItem</code>.
+ */
+abstract class InternalVersionItemImpl implements InternalVersionItem {
+
+    /**
+     * the version manager
+     */
+    private final VersionManagerImpl vMgr;
+
+    /**
+     * Creates a new Internal version item impl
+     *
+     * @param vMgr
+     */
+    protected InternalVersionItemImpl(VersionManagerImpl vMgr) {
+        this.vMgr = vMgr;
+    }
+
+    /**
+     * Returns the persistent version manager for this item
+     *
+     * @return
+     */
+    protected VersionManagerImpl getVersionManager() {
+        return vMgr;
+    }
+
+    /**
+     * Returns the external id of this item
+     *
+     * @return
+     */
+    public abstract String getId();
+
+    /**
+     * returns the parent version item or null
+     *
+     * @return
+     */
+    public abstract InternalVersionItem getParent();
+
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java
------------------------------------------------------------------------------
    svn = 

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

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=191172&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java (added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java Fri Jun 17 09:18:13 2005
@@ -0,0 +1,573 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.PropertyImpl;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.Constants;
+import org.apache.jackrabbit.core.nodetype.PropDef;
+import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.core.nodetype.NodeDef;
+import org.apache.jackrabbit.core.state.ItemState;
+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.UpdatableItemStateManager;
+import org.apache.jackrabbit.core.util.uuid.UUID;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import java.util.List;
+import java.util.HashSet;
+
+/**
+ * This Class provides some basic node operations directly on the node state.
+ */
+class NodeStateEx implements Constants {
+
+    /**
+     * the underlying persistent state
+     */
+    private NodeState nodeState;
+
+    /**
+     * the state manager
+     */
+    private final UpdatableItemStateManager stateMgr;
+
+    /**
+     * the node type registry for resolving item defs
+     */
+    private final NodeTypeRegistry ntReg;
+
+    /**
+     * the cached name
+     */
+    private QName name;
+
+    /**
+     * Creates a new persistent node
+     *
+     * @param stateMgr
+     * @param nodeState
+     */
+    public NodeStateEx(UpdatableItemStateManager stateMgr,
+                       NodeTypeRegistry ntReg,
+                       NodeState nodeState, QName name) {
+        this.nodeState = nodeState;
+        this.ntReg = ntReg;
+        this.stateMgr = stateMgr;
+        this.name = name;
+    }
+
+
+    /**
+     * returns the name of this node
+     *
+     * @return
+     */
+    public QName getName() {
+        if (name == null) {
+            try {
+                String parentId = nodeState.getParentUUID();
+                NodeState parent = (NodeState) stateMgr.getItemState(new NodeId(parentId));
+                name = ((NodeState.ChildNodeEntry)
+                        parent.getChildNodeEntries(nodeState.getUUID()).get(0)).getName();
+            } catch (ItemStateException e) {
+                // should never occurr
+                throw new IllegalStateException(e.toString());
+            }
+        }
+        return name;
+    }
+
+    /**
+     * Returns the uuid of this node
+     *
+     * @return
+     */
+    public String getUUID() {
+        return nodeState.getUUID();
+    }
+
+    /**
+     * Returns the parent uuid of this node
+     *
+     * @return
+     */
+    public String getParentUUID() {
+        return nodeState.getParentUUID();
+    }
+
+    /**
+     * Returns the node state wrpaee
+     * @return
+     */
+    public NodeState getState() {
+        return nodeState;
+    }
+
+    /**
+     * Returns the properties of this node
+     *
+     * @return
+     */
+    public PropertyState[] getProperties() throws ItemStateException {
+        List list = nodeState.getPropertyEntries();
+        PropertyState[] props = new PropertyState[list.size()];
+        for (int i = 0; i < list.size(); i++) {
+            NodeState.PropertyEntry entry = (NodeState.PropertyEntry) list.get(i);
+            PropertyId propId = new PropertyId(nodeState.getUUID(), entry.getName());
+            props[i] = (PropertyState) stateMgr.getItemState(propId);
+        }
+        return props;
+    }
+
+    /**
+     * Checks if the given property exists
+     *
+     * @param name
+     * @return
+     */
+    public boolean hasProperty(QName name) {
+        PropertyId propId = new PropertyId(nodeState.getUUID(), name);
+        return stateMgr.hasItemState(propId);
+    }
+
+    /**
+     * Returns the values of the given property of <code>null</code>
+     *
+     * @param name
+     * @return
+     */
+    public InternalValue[] getPropertyValues(QName name) {
+        PropertyId propId = new PropertyId(nodeState.getUUID(), name);
+        try {
+            PropertyState ps = (PropertyState) stateMgr.getItemState(propId);
+            return ps.getValues();
+        } catch (ItemStateException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value of the given property or <code>null</code>
+     *
+     * @param name
+     * @return
+     */
+    public InternalValue getPropertyValue(QName name) {
+        PropertyId propId = new PropertyId(nodeState.getUUID(), name);
+        try {
+            PropertyState ps = (PropertyState) stateMgr.getItemState(propId);
+            return ps.getValues()[0];
+        } catch (ItemStateException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the property value
+     *
+     * @param name
+     * @param value
+     * @throws RepositoryException
+     */
+    public void setPropertyValue(QName name, InternalValue value)
+            throws RepositoryException {
+        setPropertyValues(name, value.getType(), new InternalValue[]{value}, false);
+    }
+
+    /**
+     * Sets the property values
+     *
+     * @param name
+     * @param type
+     * @param values
+     * @throws RepositoryException
+     */
+    public void setPropertyValues(QName name, int type, InternalValue[] values)
+            throws RepositoryException {
+        setPropertyValues(name, type, values, true);
+    }
+
+    /**
+     * Sets the property values
+     *
+     * @param name
+     * @param type
+     * @param values
+     * @throws RepositoryException
+     */
+    public void setPropertyValues(QName name, int type, InternalValue[] values, boolean multiple)
+            throws RepositoryException {
+
+        PropertyState prop = getOrCreatePropertyState(name, type, multiple);
+        prop.setValues(values);
+    }
+
+
+    /**
+     * Retrieves or creates a new property state as child property of this node
+     *
+     * @param name
+     * @param type
+     * @param multiValued
+     * @return
+     * @throws RepositoryException
+     */
+    private PropertyState getOrCreatePropertyState(QName name, int type, boolean multiValued)
+            throws RepositoryException {
+
+        PropertyId propId = new PropertyId(nodeState.getUUID(), name);
+        if (stateMgr.hasItemState(propId)) {
+            try {
+                PropertyState propState = (PropertyState) stateMgr.getItemState(propId);
+                // someone calling this method will always alter the property state, so set status to modified
+                if (propState.getStatus() == ItemState.STATUS_EXISTING) {
+                    propState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                }
+                // although this is not quite correct, we mark node as modified aswell
+                if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+                    nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                }
+                return propState;
+            } catch (ItemStateException e) {
+                throw new RepositoryException("Unable to create property: " + e.toString());
+            }
+        } else {
+            PropertyState propState = stateMgr.createNew(name, nodeState.getUUID());
+            propState.setType(type);
+            propState.setMultiValued(multiValued);
+
+            PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(name, type, multiValued);
+            propState.setDefinitionId(pd.getId());
+
+            // need to store nodestate
+            nodeState.addPropertyEntry(name);
+            if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+                nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+            }
+            return propState;
+        }
+    }
+
+    /**
+     * Returns the effective (i.e. merged and resolved) node type representation
+     * of this node's primary and mixin node types.
+     *
+     * @return the effective node type
+     * @throws RepositoryException
+     */
+    public EffectiveNodeType getEffectiveNodeType() throws RepositoryException {
+
+        // build effective node type of mixins & primary type
+        // existing mixin's
+        HashSet set = new HashSet((nodeState).getMixinTypeNames());
+        // primary type
+        set.add(nodeState.getNodeTypeName());
+        try {
+            return ntReg.getEffectiveNodeType((QName[]) set.toArray(new QName[set.size()]));
+        } catch (NodeTypeConflictException ntce) {
+            String msg = "internal error: failed to build effective node type for node " + nodeState.getUUID();
+            throw new RepositoryException(msg, ntce);
+        }
+    }
+
+
+
+    /**
+     * checks if the given child node exists.
+     *
+     * @param name
+     * @return
+     */
+    public boolean hasNode(QName name) {
+        return nodeState.hasChildNodeEntry(name);
+    }
+
+    /**
+     * removes the (first) child node with the given name.
+     *
+     * @param name
+     * @return
+     * @throws RepositoryException
+     */
+    public boolean removeNode(QName name) throws RepositoryException {
+        return removeNode(name, 1);
+    }
+
+    /**
+     * removes the child node with the given name and 1-based index
+     *
+     * @param name
+     * @param index
+     * @return
+     * @throws RepositoryException
+     */
+    public boolean removeNode(QName name, int index) throws RepositoryException {
+        try {
+            NodeState.ChildNodeEntry entry = nodeState.getChildNodeEntry(name, index);
+            if (entry == null) {
+                return false;
+            } else {
+                ItemState state = stateMgr.getItemState(new NodeId(entry.getUUID()));
+                stateMgr.destroy(state);
+                nodeState.removeChildNodeEntry(name, index);
+                nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                return true;
+            }
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * removes the property with the given name and 1-based index
+     *
+     * @param name
+     * @return
+     * @throws RepositoryException
+     */
+    public boolean removeProperty(QName name) throws RepositoryException {
+        try {
+            NodeState.PropertyEntry entry = nodeState.getPropertyEntry(name);
+            if (entry == null) {
+                return false;
+            } else {
+                PropertyId propId = new PropertyId(nodeState.getUUID(), name);
+                ItemState state = stateMgr.getItemState(propId);
+                stateMgr.destroy(state);
+                nodeState.removePropertyEntry(name);
+                nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                return true;
+            }
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * retrieves the child node with the given name and 1-base index or
+     * <code>null</code> if the node does not exist.
+     *
+     * @param name
+     * @param index
+     * @return
+     * @throws RepositoryException
+     */
+    public NodeStateEx getNode(QName name, int index) throws RepositoryException {
+        NodeState.ChildNodeEntry entry = nodeState.getChildNodeEntry(name, index);
+        if (entry == null) {
+            return null;
+        }
+        try {
+            NodeState state = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID()));
+            return new NodeStateEx(stateMgr, ntReg, state, name);
+        } catch (ItemStateException e) {
+            throw new RepositoryException("Unable to getNode: " + e.toString());
+        }
+    }
+
+    /**
+     * Adds a new child node with the given name
+     *
+     * @param nodeName
+     * @param nodeTypeName
+     * @return
+     * @throws NoSuchNodeTypeException
+     * @throws ConstraintViolationException
+     * @throws RepositoryException
+     */
+    public NodeStateEx addNode(QName nodeName, QName nodeTypeName,
+                                  String uuid, boolean referenceable)
+            throws NoSuchNodeTypeException, ConstraintViolationException, RepositoryException {
+
+        NodeStateEx node = createChildNode(nodeName, nodeTypeName, uuid);
+        if (referenceable) {
+            node.setPropertyValue(JCR_UUID, InternalValue.create(node.getUUID()));
+        }
+        return node;
+    }
+
+    /**
+     * creates a new child node
+     *
+     * @param name
+     * @param uuid
+     * @return
+     */
+    private NodeStateEx createChildNode(QName name, QName nodeTypeName, String uuid)
+            throws RepositoryException {
+        String parentUUID = nodeState.getUUID();
+        // create a new node state
+        if (uuid == null) {
+            uuid = UUID.randomUUID().toString();    // version 4 uuid
+        }
+        NodeState state = stateMgr.createNew(uuid, nodeTypeName, parentUUID);
+
+        NodeDef cnd = getEffectiveNodeType().getApplicableChildNodeDef(name, nodeTypeName);
+        state.setDefinitionId(cnd.getId());
+
+        // create Node instance wrapping new node state
+        NodeStateEx node = new NodeStateEx(stateMgr, ntReg, state, name);
+        node.setPropertyValue(JCR_PRIMARYTYPE, InternalValue.create(nodeTypeName));
+
+        // add new child node entryn
+        nodeState.addChildNodeEntry(name, state.getUUID());
+        if (nodeState.getStatus() == ItemState.STATUS_EXISTING) {
+            nodeState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+        }
+        return node;
+    }
+
+    /**
+     * returns all child nodes
+     *
+     * @return
+     * @throws RepositoryException
+     */
+    public NodeStateEx[] getChildNodes() throws RepositoryException {
+        try {
+            List entries = nodeState.getChildNodeEntries();
+            NodeStateEx[] children = new NodeStateEx[entries.size()];
+            for (int i = 0; i < entries.size(); i++) {
+                NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) entries.get(i);
+                NodeState state = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID()));
+                children[i] = new NodeStateEx(stateMgr, ntReg, state, entry.getName());
+            }
+            return children;
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * stores the persistent state recursively
+     *
+     * @throws RepositoryException
+     */
+    public void store() throws RepositoryException {
+        try {
+            store(nodeState);
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * stores the given persistent state recursively
+     *
+     * @param state
+     * @throws ItemStateException
+     */
+    private void store(NodeState state)
+            throws ItemStateException {
+
+        if (state.getStatus() != ItemState.STATUS_EXISTING) {
+            // first store all transient properties
+            List props = state.getPropertyEntries();
+            for (int i = 0; i < props.size(); i++) {
+                NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i);
+                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
+                if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
+                    stateMgr.store(pstate);
+                }
+            }
+            // now store all child node entries
+            List nodes = state.getChildNodeEntries();
+            for (int i = 0; i < nodes.size(); i++) {
+                NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) nodes.get(i);
+                NodeState nstate = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID()));
+                store(nstate);
+            }
+            // and store itself
+            stateMgr.store(state);
+        }
+    }
+
+    /**
+     * reloads the persistent state recursively
+     *
+     * @throws RepositoryException
+     */
+    public void reload() throws RepositoryException {
+        try {
+            reload(nodeState);
+            // refetch nodestate if discarded
+            nodeState = (NodeState) stateMgr.getItemState(nodeState.getId());
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * reloads the given persistent state recursively
+     *
+     * @param state
+     * @throws ItemStateException
+     */
+    private void reload(NodeState state) throws ItemStateException {
+        if (state.getStatus() != ItemState.STATUS_EXISTING) {
+            // first discard all all transient properties
+            List props = state.getPropertyEntries();
+            for (int i = 0; i < props.size(); i++) {
+                NodeState.PropertyEntry entry = (NodeState.PropertyEntry) props.get(i);
+                PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getUUID(), entry.getName()));
+                if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
+                    pstate.discard();
+                }
+            }
+            // now reload all child node entries
+            List nodes = state.getChildNodeEntries();
+            for (int i = 0; i < nodes.size(); i++) {
+                NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) nodes.get(i);
+                NodeState nstate = (NodeState) stateMgr.getItemState(new NodeId(entry.getUUID()));
+                reload(nstate);
+            }
+            // and reload itself
+            state.discard();
+        }
+    }
+
+    /**
+     * copies a property
+     *
+     * @param prop
+     * @throws RepositoryException
+     */
+    public void copyFrom(PropertyImpl prop) throws RepositoryException {
+        if (prop.getDefinition().isMultiple()) {
+            InternalValue[] values = prop.internalGetValues();
+            int type;
+            if (values.length > 0) {
+                type = values[0].getType();
+            } else {
+                type = prop.getDefinition().getRequiredType();
+            }
+            setPropertyValues(prop.getQName(), type, values);
+        } else {
+            setPropertyValue(prop.getQName(), prop.internalGetValue());
+        }
+    }
+
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/NodeStateEx.java
------------------------------------------------------------------------------
    svn = 

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

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java?rev=191172&r1=191171&r2=191172&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java Fri Jun 17 09:18:13 2005
@@ -18,7 +18,6 @@
 
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
 
@@ -26,22 +25,20 @@
 import javax.jcr.Session;
 import javax.jcr.version.Version;
 import javax.jcr.version.VersionHistory;
-import java.util.Iterator;
-import java.util.List;
 
 /**
  * This interface defines the version manager. It gives access to the underlying
  * persistence layer of the versioning.
  */
 public interface VersionManager {
+
     /**
      * returns the virtual item state provider that exposes the internal versions
      * as items.
      *
-     * @param base
      * @return
      */
-    VirtualItemStateProvider getVirtualItemStateProvider(ItemStateManager base);
+    VirtualItemStateProvider getVirtualItemStateProvider();
 
     /**
      * Creates a new version history. This action is needed either when creating
@@ -52,7 +49,8 @@
      * @return
      * @throws RepositoryException
      */
-    VersionHistory createVersionHistory(Session session, NodeState node) throws RepositoryException;
+    VersionHistory createVersionHistory(Session session, NodeState node)
+            throws RepositoryException;
 
     /**
      * invokes the checkin() on the persistent version manager and remaps the
@@ -88,11 +86,10 @@
      * @return
      * @throws RepositoryException
      */
-    Version setVersionLabel(VersionHistory history, QName version, QName label, boolean move)
+    Version setVersionLabel(VersionHistory history, QName version, QName label,
+                            boolean move)
             throws RepositoryException;
 
-    //-----------------------------------------------------< internal stuff >---
-
     /**
      * Checks if the version history with the given id exists
      *
@@ -108,23 +105,8 @@
      * @return
      * @throws RepositoryException
      */
-    InternalVersionHistory getVersionHistory(String id) throws RepositoryException;
-
-    /**
-     * Returns the number of version histories
-     *
-     * @return
-     * @throws RepositoryException
-     */
-    int getNumVersionHistories() throws RepositoryException;
-
-    /**
-     * Returns an iterator over all ids of {@link InternalVersionHistory}s.
-     *
-     * @return
-     * @throws RepositoryException
-     */
-    Iterator getVersionHistoryIds() throws RepositoryException;
+    InternalVersionHistory getVersionHistory(String id)
+            throws RepositoryException;
 
     /**
      * Checks if the version with the given id exists
@@ -142,44 +124,6 @@
      * @throws RepositoryException
      */
     InternalVersion getVersion(String id) throws RepositoryException;
-
-    /**
-     * checks, if the node with the given id exists
-     * todo: move probably to VersionManagerImpl
-     *
-     * @param id
-     * @return
-     */
-    boolean hasItem(String id);
-
-    /**
-     * Returns the version item with the given id
-     * todo: move probably to VersionManagerImpl
-     *
-     * @param id
-     * @return
-     * @throws RepositoryException
-     */
-    InternalVersionItem getItem(String id) throws RepositoryException;
-
-    /**
-     * Returns the references that exist to this version item
-     * todo: move probably to VersionManagerImpl
-     *
-     * @param item
-     * @return a collection of property ids
-     */
-    List getItemReferences(InternalVersionItem item);
-
-    /**
-     * Informs this version manager that the references to one of its
-     * items has changed.
-     * todo: move probably to VersionManagerImpl
-     *
-     * @param item the version item that is referenced
-     * @param references the collection of PropertyIds that references the item
-     */
-    void setItemReferences(InternalVersionItem item, List references);
 
     /**
      * Close this version manager. After having closed a persistence



Mime
View raw message