You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2004/12/10 17:10:55 UTC

svn commit: r111518 - in incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core: . nodetype state version virtual

Author: tripod
Date: Fri Dec 10 08:10:53 2004
New Revision: 111518

URL: http://svn.apache.org/viewcvs?view=rev&rev=111518
Log:
- improved versioning / virtual node behaviour
  fixes jira issues: JCR-20, JCR-22 and JCR-23
Added:
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/HistoryRootNodeState.java   (contents, props changed)
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionHistoryNodeState.java   (contents, props changed)
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java   (contents, props changed)
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionNodeState.java   (contents, props changed)
Removed:
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/DefaultItemStateProvider.java
Modified:
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java
   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/PersistentNode.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java
   incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/InternalValue.java	Fri Dec 10 08:10:53 2004
@@ -239,6 +239,18 @@
     }
 
     /**
+     * @param values
+     * @return
+     */
+    public static InternalValue[] create(Calendar[] values) {
+        InternalValue[] ret = new InternalValue[values.length];
+        for (int i = 0; i < values.length; i++) {
+            ret[i] = new InternalValue(values[i]);
+        }
+        return ret;
+    }
+
+    /**
      * @param value
      * @return
      */

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java	Fri Dec 10 08:10:53 2004
@@ -375,6 +375,7 @@
         } catch (RepositoryException e) {
             throw e;
         } catch (Exception e) {
+            //return InternalValue.create(0).toJCRValue(session.getNamespaceResolver());
             throw new RepositoryException("Unable to get value of " + safeGetJCRPath() + ":" + 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?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/builtin_nodetypes.xml&r2=111518
==============================================================================
--- 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 Dec 10 08:10:53 2004
@@ -85,7 +85,7 @@
         <supertypes>
             <supertype>nt:base</supertype>
         </supertypes>
-        <propertyDef name="jcr:created" type="Date" autoCreate="true" mandatory="true" onParentVersion="INITIALIZE" protected="true" primaryItem="false" multiple="false"/>
+        <propertyDef name="jcr:created" type="Date" autoCreate="true" mandatory="true" onParentVersion="COPY" protected="true" primaryItem="false" multiple="false"/>
     </nodeType>
     <nodeType name="nt:file" mixin="false" orderableChildNodes="false">
         <supertypes>

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/state/NodeState.java	Fri Dec 10 08:10:53 2004
@@ -109,7 +109,7 @@
      * @return always true
      * @see ItemState#isNode
      */
-    public boolean isNode() {
+    public final boolean isNode() {
         return true;
     }
 
@@ -800,7 +800,7 @@
         private int index; // 1-based index for same-name siblings
         private String uuid;
 
-        private ChildNodeEntry(QName nodeName, String uuid, int index) {
+        public ChildNodeEntry(QName nodeName, String uuid, int index) {
             super(nodeName);
 
             if (uuid == null) {

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/HistoryRootNodeState.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/HistoryRootNodeState.java?view=auto&rev=111518
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/HistoryRootNodeState.java	Fri Dec 10 08:10:53 2004
@@ -0,0 +1,110 @@
+/*
+ * 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.virtual.VirtualNodeState;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NamespaceRegistryImpl;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+
+import javax.jcr.RepositoryException;
+import java.util.*;
+
+/**
+ * This Class implements...
+ *
+ * @author tripod
+ * @version $Revision:$, $Date:$
+ */
+public class HistoryRootNodeState extends VirtualNodeState {
+
+    private VersionManager vm;
+
+    public HistoryRootNodeState(VersionItemStateProvider vm, String uuid, String parentUUID) {
+        super(vm, uuid, NodeTypeRegistry.NT_UNSTRUCTURED, parentUUID);
+        this.vm = vm.getVersionManager();
+
+        setDefinitionId(vm.getNodeDefId(VersionManager.NODENAME_HISTORY_ROOT));
+    }
+
+    public synchronized boolean hasChildNodeEntry(QName name) {
+        return vm.hasVersionHistory(name);
+    }
+
+    public synchronized boolean hasChildNodeEntry(QName name, int index) {
+        return index<=1 ? vm.hasVersionHistory(name) : false;
+    }
+
+    public synchronized ChildNodeEntry getChildNodeEntry(QName nodeName, int index) {
+        try {
+            if (index<=1) {
+                InternalVersionHistory hist = vm.getVersionHistory(nodeName);
+                return new ChildNodeEntry(nodeName, hist.getId(), 1);
+            }
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return null;
+    }
+
+    public synchronized List getChildNodeEntries() {
+        try {
+            ArrayList list = new ArrayList(vm.getNumVersionHistories());
+            Iterator iter = vm.getVersionHistories();
+            while (iter.hasNext()) {
+                InternalVersionHistory vh = (InternalVersionHistory) iter.next();
+                QName name = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, vh.getId());
+                list.add(new ChildNodeEntry(name, vh.getId(), 1));
+            }
+            return list;
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    public synchronized List getChildNodeEntries(String uuid) {
+        // todo: do nicer
+        try {
+            ChildNodeEntry entry = getChildNodeEntry(new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid), 1);
+            if (entry!=null) {
+                ArrayList list = new ArrayList(1);
+                list.add(entry);
+                return list;
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    public synchronized List getChildNodeEntries(QName nodeName) {
+        // todo: do nicer
+        try {
+            ChildNodeEntry entry = getChildNodeEntry(nodeName, 1);
+            if (entry!=null) {
+                ArrayList list = new ArrayList(1);
+                list.add(entry);
+                return list;
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+
+}

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalFrozenNode.java	Fri Dec 10 08:10:53 2004
@@ -16,6 +16,7 @@
 package org.apache.jackrabbit.core.version;
 
 import org.apache.jackrabbit.core.*;
+import org.apache.jackrabbit.core.util.uuid.UUID;
 import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 
@@ -27,6 +28,8 @@
 import javax.jcr.version.OnParentVersionAction;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * The InternalFrozenNode class presents the frozen node that was generated
@@ -36,6 +39,8 @@
  */
 public class InternalFrozenNode extends InternalFreeze {
 
+    private static final boolean FREEZEMODE_CLONE = true;
+
     /**
      * the underlaying persistance node
      */
@@ -67,6 +72,11 @@
     private QName[] frozenMixinTypes = null;
 
     /**
+     * uuid of this node
+     */
+    private String uuid;
+
+    /**
      * Creates a new frozen node based on the given persistance node.
      *
      * @param node
@@ -79,31 +89,53 @@
         // init the frozen properties
         PersistentProperty[] props = node.getProperties();
         List propList = new ArrayList();
+
         for (int i = 0; i < props.length; i++) {
             PersistentProperty prop = props[i];
-            if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_UUID)) {
-                // special property
-                frozenUUID = node.getPropertyValue(VersionManager.PROPNAME_FROZEN_UUID).internalValue().toString();
-            } else if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE)) {
-                // special property
-                frozenPrimaryType = (QName) node.getPropertyValue(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE).internalValue();
-            } else if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES)) {
-                // special property
-                InternalValue[] values = node.getPropertyValues(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES);
-                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();
+            if (FREEZEMODE_CLONE) {
+                if (prop.getName().equals(ItemImpl.PROPNAME_PRIMARYTYPE)) {
+                    frozenPrimaryType = (QName) node.getPropertyValue(prop.getName()).internalValue();
+                } else if (prop.getName().equals(ItemImpl.PROPNAME_UUID)) {
+                    frozenUUID = node.getPropertyValue(prop.getName()).toString();
+                } else if (prop.getName().equals(ItemImpl.PROPNAME_MIXINTYPES)) {
+                    InternalValue[] values = node.getPropertyValues(prop.getName());
+                    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 {
+                    propList.add(prop);
                 }
-            } else if (prop.getName().equals(ItemImpl.PROPNAME_PRIMARYTYPE)) {
-                // ignore
-            } else if (prop.getName().equals(ItemImpl.PROPNAME_UUID)) {
-                // ignore
+
             } else {
-                propList.add(prop);
+                if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_UUID)) {
+                    // special property
+                    frozenUUID = node.getPropertyValue(VersionManager.PROPNAME_FROZEN_UUID).internalValue().toString();
+                } else if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE)) {
+                    // special property
+                    frozenPrimaryType = (QName) node.getPropertyValue(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE).internalValue();
+                } else if (prop.getName().equals(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES)) {
+                    // special property
+                    InternalValue[] values = node.getPropertyValues(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES);
+                    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(ItemImpl.PROPNAME_PRIMARYTYPE)) {
+                    // ignore
+                } else if (prop.getName().equals(ItemImpl.PROPNAME_UUID)) {
+                    // ignore
+                } else {
+                    propList.add(prop);
+                }
             }
         }
         frozenProperties = (PersistentProperty[]) propList.toArray(new PersistentProperty[propList.size()]);
@@ -130,6 +162,10 @@
 
     }
 
+    public String getInternalUUID() {
+        return node.getUUID();
+    }
+
     /**
      * Returns the name of this frozen node
      *
@@ -209,24 +245,39 @@
     protected static PersistentNode checkin(PersistentNode parent, QName name, NodeImpl src, boolean initOnly, boolean forceCopy)
             throws RepositoryException {
 
-        // create new node
-        PersistentNode node = parent.addNode(name, NodeTypeRegistry.NT_UNSTRUCTURED);
+        PersistentNode node;
+        if (FREEZEMODE_CLONE) {
+            // identiycopy
+            // create new node
+            NodeType[] mixins = src.getMixinNodeTypes();
+            QName[] mixinNames = new QName[mixins.length];
+            for (int i = 0; i < mixins.length; i++) {
+                mixinNames[i]=((NodeTypeImpl) mixins[i]).getQName();
+            }
+            node = parent.addNode(name, ((NodeTypeImpl) src.getPrimaryNodeType()).getQName());
+            node.setMixinNodeTypes(mixinNames);
 
-        // initialize the internal properties
-        if (src.isNodeType(NodeTypeRegistry.MIX_REFERENCEABLE)) {
-            node.setPropertyValue(VersionManager.PROPNAME_FROZEN_UUID, InternalValue.create(src.getUUID()));
-        }
+        } else {
+            // emulated
+            // create new node
+            node = parent.addNode(name, NodeTypeRegistry.NT_UNSTRUCTURED);
+
+            // initialize the internal properties
+            if (src.isNodeType(NodeTypeRegistry.MIX_REFERENCEABLE)) {
+                node.setPropertyValue(VersionManager.PROPNAME_FROZEN_UUID, InternalValue.create(src.getUUID()));
+            }
 
-        node.setPropertyValue(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE,
-                InternalValue.create(((NodeTypeImpl) src.getPrimaryNodeType()).getQName()));
+            node.setPropertyValue(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE,
+                    InternalValue.create(((NodeTypeImpl) src.getPrimaryNodeType()).getQName()));
 
-        if (src.hasProperty(NodeImpl.PROPNAME_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());
+            if (src.hasProperty(NodeImpl.PROPNAME_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(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, PropertyType.NAME, ivalues);
             }
-            node.setPropertyValues(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, PropertyType.NAME, ivalues);
         }
 
         if (!initOnly) {
@@ -250,6 +301,7 @@
                 }
             }
 
+
             // add the frozen children and vistories
             NodeIterator niter = src.getNodes();
             while (niter.hasNext()) {
@@ -265,14 +317,14 @@
                     case OnParentVersionAction.VERSION:
                         if (child.isNodeType(NodeTypeRegistry.MIX_VERSIONABLE)) {
                             // create frozen versionable child
-                            PersistentNode newChild = node.addNode(child.getQName(), NodeTypeRegistry.NT_UNSTRUCTURED);
+                            PersistentNode newChild = node.addNode(child.getQName(), NodeTypeRegistry.NT_FROZEN_VERSIONABLE_CHILD);
                             newChild.setPropertyValue(VersionManager.PROPNAME_VERSION_HISTORY,
-                                    InternalValue.create(child.getVersionHistory().getUUID()));
+                                    InternalValue.create(UUID.fromString(child.getVersionHistory().getUUID())));
                             newChild.setPropertyValue(VersionManager.PROPNAME_BASE_VERSION,
-                                    InternalValue.create(child.getBaseVersion().getUUID()));
+                                    InternalValue.create(UUID.fromString(child.getBaseVersion().getUUID())));
+                            break;
                         }
-                        // else ignore
-                        break;
+                        // else copy
                     case OnParentVersionAction.COPY:
                         checkin(node, child.getQName(), child, false, true);
                         break;

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?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersion.java&r2=111518
==============================================================================
--- 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 Dec 10 08:10:53 2004
@@ -63,11 +63,6 @@
     private HashSet labelCache = null;
 
     /**
-     * the internal frozen node that was versioned with this version
-     */
-    private InternalFrozenNode frozen;
-
-    /**
      * the id of this version
      */
     private String versionId;
@@ -83,9 +78,8 @@
      *
      * @param vh
      * @param node
-     * @throws RepositoryException
      */
-    InternalVersion(InternalVersionHistory vh, PersistentNode node) throws RepositoryException {
+    InternalVersion(InternalVersionHistory vh, PersistentNode node) {
         super(null);
         this.versionHistory = vh;
         this.node = node;
@@ -96,10 +90,6 @@
         // get id
         versionId = (String) node.getPropertyValue(PersistentVersionManager.PROPNAME_VERSION_ID).internalValue();
 
-        // get frozen node
-        PersistentNode pNode = node.getNode(PersistentVersionManager.NODENAME_FROZEN, 1);
-        frozen = pNode == null ? null : new InternalFrozenNode(this, pNode);
-
         // init internal values
         InternalValue[] values = node.getPropertyValues(VersionManager.PROPNAME_CREATED);
         if (values != null) {
@@ -139,7 +129,14 @@
      * @return
      */
     public InternalFrozenNode getFrozenNode() {
-        return frozen;
+        // get frozen node
+        try {
+            PersistentNode pNode = node.getNode(PersistentVersionManager.NODENAME_FROZEN, 1);
+            return pNode == null ? null : new InternalFrozenNode(this, pNode);
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return null;
     }
 
     /**

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?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/InternalVersionHistory.java&r2=111518
==============================================================================
--- 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 Dec 10 08:10:53 2004
@@ -191,6 +191,15 @@
     }
 
     /**
+     * Checks if the version for the given uuid exists
+     * @param uuid
+     * @return
+     */
+    public boolean hasVersion(String uuid) {
+        return versionCache.containsKey(uuid);
+    }
+
+    /**
      * Returns the version with the given uuid or <code>null</code> if the
      * respective version does not exist.
      *
@@ -374,6 +383,14 @@
      */
     protected Iterator getVersions() {
         return versionCache.values().iterator();
+    }
+
+    /**
+     * Returns the number of versions
+     * @return
+     */
+    protected int getNumVersions() {
+        return versionCache.size();
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentNode.java	Fri Dec 10 08:10:53 2004
@@ -385,11 +385,20 @@
         NodeTypeImpl nodeType = ntMgr.getNodeType(nodeTypeName);
         NodeDefImpl def;
         try {
-            def = getApplicableChildNodeDef(nodeName, nodeType == null ? null : nodeType.getQName());
+            def = getApplicableChildNodeDef(name, nodeType == null ? null : nodeType.getQName());
         } catch (RepositoryException re) {
-            String msg = "no definition found in parent node's node type for new node";
-            throw new ConstraintViolationException(msg, re);
+            // hack, use nt:unstructured as parent
+            try {
+                NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
+                EffectiveNodeType ent = ntReg.buildEffectiveNodeType(new QName[]{NodeTypeRegistry.NT_UNSTRUCTURED});
+                ChildNodeDef cnd = ent.getApplicableChildNodeDef(name, nodeTypeName);
+                def = ntMgr.getNodeDef(new NodeDefId(cnd));
+            } catch (NodeTypeConflictException e) {
+                String msg = "no definition found in parent node's node type for new node";
+                throw new ConstraintViolationException(msg, re);
+            }
         }
+
         if (nodeType == null) {
             // use default node type
             nodeType = (NodeTypeImpl) def.getDefaultPrimaryType();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/PersistentVersionManager.java	Fri Dec 10 08:10:53 2004
@@ -24,6 +24,7 @@
 import org.apache.jackrabbit.core.state.PersistentNodeState;
 import org.apache.jackrabbit.core.state.PersistentItemStateProvider;
 import org.apache.log4j.Logger;
+import org.apache.commons.collections.ReferenceMap;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
@@ -32,12 +33,15 @@
 import java.util.Iterator;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Map;
 
 /**
- * This Class provides general versioning functions.
+ * This Class provides implements the persistent part of the versionin. the
+ * current implementation uses the 'normal' repository content as storage.
  */
 public class PersistentVersionManager {
 
+
     /**
      * the logger
      */
@@ -99,10 +103,10 @@
     private HashMap versionManagers = new HashMap();
 
     /**
-     * the version histories
+     * the version histories. key=uuid, value=version history
      */
-    private HashMap histories = new HashMap();
-
+    private Map histories = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.WEAK);
+    
     /**
      * Creates a new PersistentVersionManager.
      *
@@ -116,7 +120,7 @@
         try {
             NodeImpl systemRoot = ((RepositoryImpl) session.getRepository()).getSystemRootNode(session);
             // enable this to make the persistence storage visible
-            if (false) {
+            if (true) {
                 // check for versionhistory root
                 if (!systemRoot.hasNode(VERSION_HISTORY_ROOT_NAME)) {
                     // if not exist, create
@@ -142,13 +146,27 @@
     }
 
     /**
+     * returns the version manager
+     * @return
+     */
+    public synchronized VersionManager getVersionManager(Workspace wsp) {
+        VersionManager vm = (VersionManager) versionManagers.get(wsp.getName());
+        if (vm==null) {
+            vm = new VersionManager(this);
+            versionManagers.put(wsp.getName(), vm);
+        }
+        return vm;
+    }
+
+
+    /**
      * Creates a new Version History.
      *
      * @param node the node for which the version history is to be initialized
      * @return the newly created version history.
      * @throws RepositoryException
      */
-    public synchronized InternalVersionHistory createVersionHistory(NodeImpl node)
+    synchronized InternalVersionHistory createVersionHistory(NodeImpl node)
             throws RepositoryException {
 
         // create deep path
@@ -175,7 +193,7 @@
      * @return
      * @throws RepositoryException
      */
-    public synchronized InternalVersionHistory getVersionHistory(String histId)
+    synchronized InternalVersionHistory getVersionHistory(String histId)
             throws RepositoryException {
 
         InternalVersionHistory hist = (InternalVersionHistory) histories.get(histId);
@@ -183,18 +201,33 @@
             // we cannot used the uuid, since the persistent state do not share the same ids
             QName historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, histId);
             PersistentNode hNode = historyRoot.getNode(historyNodeName, 1);
-            hist = new InternalVersionHistory(this, hNode);
-            histories.put(histId, hist);
+            if (hNode!=null) {
+                hist = new InternalVersionHistory(this, hNode);
+                histories.put(histId, hist);
+            }
         }
         return hist;
     }
 
     /**
+     * Checks if the versionhistory for the given id exists
+     * @param histId
+     * @return
+     */
+    synchronized boolean hasVersionHistory(String histId) {
+        if (histories.containsKey(histId)) {
+            return true;
+        } else {
+            return historyRoot.hasNode(new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, histId));
+        }
+    }
+
+    /**
      * returns an iterator over all existing version histories
      * @return
      * @throws RepositoryException
      */
-    public synchronized Iterator getVersionHistories() throws RepositoryException {
+    synchronized Iterator getVersionHistories() throws RepositoryException {
         PersistentNode[] ph = historyRoot.getChildNodes();
         ArrayList list = new ArrayList(ph.length);
         for (int i=0; i<ph.length; i++) {
@@ -204,23 +237,74 @@
     }
 
     /**
+     * returns the number of version histories
+     * @return
+     * @throws RepositoryException
+     */
+    synchronized int getNumVersionHistories() throws RepositoryException {
+        return historyRoot.getChildNodes().length;
+    }
+
+    /**
      * returns the internal version for the id
      *
      * @param versionId
      * @return
      * @throws RepositoryException
      */
-    public synchronized InternalVersion getVersion(String histId, String versionId)
+    synchronized InternalVersion getVersion(String histId, String versionId)
             throws RepositoryException {
         InternalVersionHistory history = getVersionHistory(histId);
         return history.getVersion(versionId);
     }
 
     /**
+     * returns the version with the given id
+     * @param versionId
+     * @return
+     * @throws RepositoryException
+     */
+    synchronized InternalVersion getVersion(String versionId)
+            throws RepositoryException {
+
+        // todo: implement better
+        PersistentNode[] ph = historyRoot.getChildNodes();
+        for (int i=0; i<ph.length; i++) {
+            InternalVersionHistory vh = getVersionHistory(ph[i].getName().getLocalName());
+            InternalVersion v = vh.getVersion(versionId);
+            if (v!=null) {
+                return v;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the version with the given id exists
+     * @param versionId
+     * @return
+     */
+    synchronized boolean hasVersion(String versionId) {
+        // todo: implement better
+        try {
+            PersistentNode[] ph = historyRoot.getChildNodes();
+            for (int i=0; i<ph.length; i++) {
+                InternalVersionHistory vh = getVersionHistory(ph[i].getName().getLocalName());
+                if (vh.hasVersion(versionId)) {
+                    return true;
+                }
+            }
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return false;
+    }
+
+    /**
      * is informed by the versions if they were modified
      * @param version
      */
-    protected void onVersionModified(InternalVersion version)  throws RepositoryException {
+    void onVersionModified(InternalVersion version)  throws RepositoryException {
         // check if version manager already generated item states
         Iterator iter = versionManagers.values().iterator();
         while (iter.hasNext()) {
@@ -232,7 +316,7 @@
      * is informed by the versions if they were modified
      * @param vh
      */
-    protected void onVersionHistoryModified(InternalVersionHistory vh)  throws RepositoryException {
+    void onVersionHistoryModified(InternalVersionHistory vh)  throws RepositoryException {
         // check if version manager already generated item states
         Iterator iter = versionManagers.values().iterator();
         while (iter.hasNext()) {
@@ -248,7 +332,7 @@
      * @throws RepositoryException
      * @see Node#checkin()
      */
-    public synchronized InternalVersion checkin(NodeImpl node) throws RepositoryException {
+    synchronized InternalVersion checkin(NodeImpl node) throws RepositoryException {
         // assuming node is versionable and checkout (check in nodeimpl)
         // To create a new version of a versionable node N, the client calls N.checkin.
         // This causes the following series of events:
@@ -294,24 +378,4 @@
         return history.checkin(new QName("", versionName), node);
     }
 
-    /**
-     * returns the version manager
-     * @return
-     */
-    public synchronized VersionManager getVersionManager(Workspace wsp) {
-        VersionManager vm = (VersionManager) versionManagers.get(wsp.getName());
-        if (vm==null) {
-            vm = new VersionManager(this);
-            versionManagers.put(wsp.getName(), vm);
-        }
-        return vm;
-    }
-
-    /**
-     * returns the node type manager of the version storage
-     * @return
-     */
-    public NodeTypeManagerImpl getNodeTypeManager(){
-        return ntMgr;
-    }
 }

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionHistoryNodeState.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionHistoryNodeState.java?view=auto&rev=111518
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionHistoryNodeState.java	Fri Dec 10 08:10:53 2004
@@ -0,0 +1,93 @@
+/*
+ * 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.virtual.VirtualNodeState;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+
+import javax.jcr.RepositoryException;
+import java.util.*;
+
+/**
+ * This Class implements...
+ *
+ * @author tripod
+ * @version $Revision:$, $Date:$
+ */
+public class VersionHistoryNodeState extends VirtualNodeState {
+
+    private final InternalVersionHistory vh;
+
+    public VersionHistoryNodeState(VersionItemStateProvider vm, InternalVersionHistory vh, String parentUUID) {
+        super(vm, vh.getId(), NodeTypeRegistry.NT_VERSION_HISTORY, parentUUID);
+        this.vh =  vh;
+
+        setDefinitionId(vm.getNodeDefId(NodeTypeRegistry.NT_VERSION_HISTORY));
+        // we do not initialize the childnode entry array, but rather
+        // generate it every time.
+    }
+
+    public synchronized boolean hasChildNodeEntry(QName name) {
+        return vh.hasVersion(name);
+    }
+
+    public synchronized boolean hasChildNodeEntry(QName name, int index) {
+        // no same name siblings
+        return index<=1 ? vh.hasVersion(name) : false;
+    }
+
+    public synchronized ChildNodeEntry getChildNodeEntry(QName nodeName, int index) {
+        try {
+            if (index<=1) {
+                InternalVersion v = vh.getVersion(nodeName);
+                return new ChildNodeEntry(nodeName, v.getId(), 1);
+            }
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return null;
+    }
+
+    public synchronized List getChildNodeEntries() {
+        Iterator iter = vh.getVersions();
+        ArrayList list = new ArrayList(vh.getNumVersions());
+        while (iter.hasNext()) {
+            InternalVersion v = (InternalVersion) iter.next();
+            list.add(new ChildNodeEntry(v.getName(), v.getId(), 1));
+        }
+        return list;
+    }
+
+    public synchronized List getChildNodeEntries(String uuid) {
+        ArrayList list = new ArrayList(1);
+        InternalVersion v = vh.getVersion(uuid);
+        list.add(new ChildNodeEntry(v.getName(), uuid, 1));
+        return list;
+    }
+
+    public synchronized List getChildNodeEntries(QName nodeName) {
+        ArrayList list = new ArrayList(1);
+        try {
+            InternalVersion v = vh.getVersion(nodeName);
+            list.add(new ChildNodeEntry(nodeName, v.getId(), 1));
+        } catch (RepositoryException e) {
+            // ignore
+        }
+        return list;
+    }
+
+}

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java?view=auto&rev=111518
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java	Fri Dec 10 08:10:53 2004
@@ -0,0 +1,181 @@
+/*
+ * 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.virtual.VirtualItemStateProvider;
+import org.apache.jackrabbit.core.virtual.VirtualNodeState;
+import org.apache.jackrabbit.core.state.*;
+import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.NodeDefId;
+import org.apache.jackrabbit.core.nodetype.PropDefId;
+import org.apache.log4j.Logger;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * This Class implements...
+ *
+ * @author tripod
+ * @version $Revision:$, $Date:$
+ */
+public class VersionItemStateProvider implements VirtualItemStateProvider {
+
+    /**
+     * the default logger
+     */
+    private static Logger log = Logger.getLogger(VersionItemStateProvider.class);
+
+    private final HistoryRootNodeState root;
+
+    private final VersionManager vMgr;
+
+    public VersionItemStateProvider(VersionManager vMgr, String rootId, String parentId) {
+        this.vMgr = vMgr;
+        this.root = new HistoryRootNodeState(this, rootId, parentId);
+    }
+
+    public VersionManager getVersionManager() {
+        return vMgr;
+    }
+
+    public ItemState getItemState(ItemId id)
+            throws NoSuchItemStateException, ItemStateException {
+        if (id instanceof NodeId) {
+            return getNodeState((NodeId) id);
+        } else {
+            return getPropertyState((PropertyId) id);
+        }
+    }
+
+    public boolean hasNodeState(NodeId id) {
+        if (id.equals(root.getId())) {
+            return true;
+        }
+        // check version history
+        if (vMgr.hasVersionHistory(id.getUUID())) {
+            return true;
+        }
+        // check verion
+        if (vMgr.hasVersion(id.getUUID())) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public NodeState getNodeState(NodeId id)
+            throws NoSuchItemStateException, ItemStateException {
+
+        // check if root
+        if (id.equals(root.getId())) {
+            return root;
+        }
+
+        // check version history
+        try {
+            InternalVersionHistory vh = vMgr.getVersionHistory(id.getUUID());
+            if (vh!=null) {
+                return new VersionHistoryNodeState(this, vh, root.getUUID());
+            }
+        } catch (RepositoryException e) {
+            log.error("Unable to check for version history:" + e.toString());
+            throw new ItemStateException(e);
+        }
+
+        // check version
+        try {
+            InternalVersion v = vMgr.getVersion(id.getUUID());
+            if (v!=null) {
+                return new VersionNodeState(this, v);
+            }
+        } catch (RepositoryException e) {
+            log.error("Unable to check for version:" + e.toString());
+            throw new ItemStateException(e);
+        }
+
+        // not found, throw
+        throw new NoSuchItemStateException(id.toString());
+    }
+
+    public PropertyState getPropertyState(PropertyId id)
+            throws NoSuchItemStateException, ItemStateException {
+
+        // get parent state
+        NodeState parent = getNodeState(new NodeId(id.getParentUUID()));
+
+        // handle some default prop states
+        if (parent instanceof VirtualNodeState) {
+            return ((VirtualNodeState) parent).getPropertyState(id.getName());
+        }
+        throw new NoSuchItemStateException(id.toString());
+    }
+
+    public boolean hasPropertyState(PropertyId id) {
+
+        try {
+            // get parent state
+            NodeState parent = getNodeState(new NodeId(id.getParentUUID()));
+
+            // handle some default prop states
+            if (parent instanceof VirtualNodeState) {
+                return ((VirtualNodeState) parent).getPropertyState(id.getName())!=null;
+            }
+        } catch (ItemStateException e) {
+            // ignore
+        }
+        return false;
+    }
+
+    public boolean hasItemState(ItemId id) {
+        if (id instanceof NodeId) {
+            return hasNodeState((NodeId) id);
+        } else {
+            return hasPropertyState((PropertyId) id);
+        }
+    }
+
+    public NodeDefId getNodeDefId(QName nodename) {
+        return vMgr.getNodeDefId(nodename);
+    }
+
+    public PropDefId getPropDefId(QName propname) {
+        return vMgr.getPropDefId(propname);
+    }
+
+    /**
+     * virtual item state provider do not have attics.
+     *
+     * @throws NoSuchItemStateException always
+     */
+    public ItemState getItemStateInAttic(ItemId id) throws NoSuchItemStateException {
+        // never has states in attic
+        throw new NoSuchItemStateException(id.toString());
+    }
+
+    /**
+     * virtual item state provider do not have attics.
+     *
+     * @return <code>false</code>
+     */
+    public boolean hasItemStateInAttic(ItemId id) {
+        // never has states in attic
+        return false;
+    }
+
+}

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?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionManager.java&r2=111518
==============================================================================
--- 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 Dec 10 08:10:53 2004
@@ -16,23 +16,20 @@
 package org.apache.jackrabbit.core.version;
 
 import org.apache.jackrabbit.core.*;
-import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
-import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.ItemStateProvider;
-import org.apache.jackrabbit.core.state.NoSuchItemStateException;
 import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.core.util.uuid.UUID;
-import org.apache.jackrabbit.core.virtual.DefaultItemStateProvider;
-import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
-import org.apache.jackrabbit.core.virtual.VirtualNodeState;
+import org.apache.jackrabbit.core.nodetype.*;
+import org.apache.jackrabbit.core.virtual.*;
 import org.apache.log4j.Logger;
 
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeDef;
-import javax.jcr.version.Version;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.version.VersionHistory;
+import javax.jcr.version.Version;
 import java.util.Iterator;
+import java.util.HashMap;
 
 /**
  * This Class implements the session tied version manager. It is also repsonsible
@@ -49,7 +46,7 @@
     /**
      * root path for version storage
      */
-    public static final QName VERSION_HISTORY_ROOT_NAME = new QName(NamespaceRegistryImpl.NS_JCR_URI, "versionStorage");
+    public static final QName NODENAME_HISTORY_ROOT = new QName(NamespaceRegistryImpl.NS_JCR_URI, "versionStorage");
     /**
      * name of the 'jcr:frozenUUID' property
      */
@@ -103,12 +100,12 @@
     /**
      * The virtual item manager that exposes the versions to the content
      */
-    private DefaultItemStateProvider virtProvider;
+    private VersionItemStateProvider virtProvider;
 
     /**
-     * The virtual history root
+     * the definition id manager helper class
      */
-    private VirtualNodeState historyRoot;
+    private DefinitionIdMgr idMgr;
 
 
     /**
@@ -128,24 +125,21 @@
     public synchronized VirtualItemStateProvider getVirtualItemStateProvider(SessionImpl session, ItemStateProvider base) {
         if (virtProvider == null) {
             try {
+                // init the definition id mgr
+                idMgr = new DefinitionIdMgr(session.getNodeTypeManager());
+
+                session.getNodeTypeManager().getNodeType(NodeTypeRegistry.NT_BASE).getApplicablePropertyDef(ItemImpl.PROPNAME_PRIMARYTYPE, PropertyType.NAME, false).unwrap();
                 // check, if workspace of session has history root
                 NodeImpl systemRoot = ((RepositoryImpl) session.getRepository()).getSystemRootNode(session);
-                if (!systemRoot.hasNode(VersionManager.VERSION_HISTORY_ROOT_NAME)) {
+                if (!systemRoot.hasNode(VersionManager.NODENAME_HISTORY_ROOT)) {
                     // if not exist, create
-                    systemRoot.addNode(VersionManager.VERSION_HISTORY_ROOT_NAME, NodeTypeRegistry.NT_UNSTRUCTURED);
+                    systemRoot.addNode(VersionManager.NODENAME_HISTORY_ROOT, NodeTypeRegistry.NT_UNSTRUCTURED);
                 }
                 systemRoot.save();
-                String rootId = systemRoot.getNode(VersionManager.VERSION_HISTORY_ROOT_NAME).internalGetUUID();
+                String rootId = systemRoot.getNode(VersionManager.NODENAME_HISTORY_ROOT).internalGetUUID();
 
-                virtProvider = new DefaultItemStateProvider(vMgr.getNodeTypeManager());
-                // create a duplicate of the version history root name
                 NodeState virtRootState = (NodeState) base.getItemState(new NodeId(rootId));
-                historyRoot = virtProvider.addOverlay(virtRootState);
-                Iterator iter = vMgr.getVersionHistories();
-                while (iter.hasNext()) {
-                    InternalVersionHistory vh = (InternalVersionHistory) iter.next();
-                    mapVersionHistory(vh);
-                }
+                virtProvider = new VersionItemStateProvider(this, rootId, virtRootState.getParentUUID());
             } catch (Exception e) {
                 // todo: better error handling
                 log.error("Error while initializing virtual items.", e);
@@ -156,6 +150,24 @@
     }
 
     /**
+     * returns the node definition id for the given name
+     * @param name
+     * @return
+     */
+    public NodeDefId getNodeDefId(QName name) {
+        return idMgr.getNodeDefId(name);
+    }
+
+    /**
+     * returns the property definition id for the given name
+     * @param name
+     * @return
+     */
+    public PropDefId getPropDefId(QName name) {
+        return idMgr.getPropDefId(name);
+    }
+
+    /**
      * Creates a new version history. This action is needed either when creating
      * a new 'mix:versionable' node or when adding the 'mix:versionalbe' mixin
      * to a node.
@@ -198,6 +210,86 @@
         return (VersionHistory) node.getSession().getNodeByUUID(history.getId());
     }
 
+    //-----------------------------------------------------< internal stuff >---
+
+    /**
+     * Checks, if the version history with the given name exists
+     * @param name
+     * @return
+     */
+    boolean hasVersionHistory(QName name) {
+        // name is uuid of version history
+        String id = name.getLocalName();
+        return vMgr.hasVersionHistory(id);
+    }
+
+    /**
+     * Returns the vesion history impl for the given name
+     * @param name
+     * @return
+     * @throws RepositoryException
+     */
+    InternalVersionHistory getVersionHistory(QName name) throws RepositoryException {
+        // name is uuid of version history
+        String id = name.getLocalName();
+        return vMgr.getVersionHistory(id);
+    }
+
+    /**
+     * Checks if the version history with the given id exists
+     * @param id
+     * @return
+     */
+    boolean hasVersionHistory(String id) {
+        return vMgr.hasVersionHistory(id);
+    }
+
+    /**
+     * Returns the version history with the given id
+     * @param id
+     * @return
+     * @throws RepositoryException
+     */
+    InternalVersionHistory getVersionHistory(String id) throws RepositoryException {
+        return vMgr.getVersionHistory(id);
+    }
+
+    /**
+     * Returns the number of version histories
+     * @return
+     * @throws RepositoryException
+     */
+    int getNumVersionHistories() throws RepositoryException {
+        return vMgr.getNumVersionHistories();
+    }
+
+    /**
+     * Returns an iterator over all {@link InternalVersionHistory}s.
+     * @return
+     * @throws RepositoryException
+     */
+    Iterator getVersionHistories() throws RepositoryException {
+        return vMgr.getVersionHistories();
+    }
+
+    /**
+     * Checks if the version with the given id exists
+     * @param id
+     * @return
+     */
+    boolean hasVersion(String id) {
+        return vMgr.hasVersion(id);
+    }
+
+    /**
+     * Returns the version with the given id
+     * @param id
+     * @return
+     * @throws RepositoryException
+     */
+    InternalVersion getVersion(String id) throws RepositoryException {
+        return vMgr.getVersion(id);
+    }
 
     /**
      * Creates a new VersionHistoryImpl instance. this is usually called by
@@ -261,6 +353,7 @@
      */
     public synchronized Version checkin(NodeImpl node) throws RepositoryException {
         InternalVersion version = vMgr.checkin(node);
+
         vMgr.onVersionHistoryModified(version.getVersionHistory());
 
         // invalidate predecessors 'sucessors' properties
@@ -268,6 +361,7 @@
         for (int i = 0; i < pred.length; i++) {
             onVersionModified(pred[i]);
         }
+
         return (Version) node.getSession().getNodeByUUID(version.getId());
     }
 
@@ -280,12 +374,6 @@
      */
     protected synchronized void onVersionModified(InternalVersion v)
             throws RepositoryException {
-        try {
-            VirtualNodeState ns = (VirtualNodeState) virtProvider.getItemState(new NodeId(v.getId()));
-            mapDynamicProperties(ns, v);
-        } catch (NoSuchItemStateException e) {
-            throw new RepositoryException(e);
-        }
     }
 
     /**
@@ -297,176 +385,60 @@
      */
     protected synchronized void onVersionHistoryModified(InternalVersionHistory vh)
             throws RepositoryException {
-        mapVersionHistory(vh);
-    }
-
-    /**
-     * Maps the version history and it's versions to the content representation.
-     *
-     * @param vh
-     * @throws RepositoryException
-     */
-    private void mapVersionHistory(InternalVersionHistory vh)
-            throws RepositoryException {
-        try {
-            String uuid = vh.getId();
-            VirtualNodeState parent = historyRoot;
-            QName historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid.substring(0, 2));
-            if (!parent.hasChildNodeEntry(historyNodeName)) {
-                parent = virtProvider.addNode(parent, historyNodeName, null, NodeTypeRegistry.NT_UNSTRUCTURED, null);
-            } else {
-                parent = virtProvider.getNode(parent, historyNodeName, 1);
-            }
-            historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid.substring(2, 4));
-            if (!parent.hasChildNodeEntry(historyNodeName)) {
-                parent = virtProvider.addNode(parent, historyNodeName, null, NodeTypeRegistry.NT_UNSTRUCTURED, null);
-            } else {
-                parent = virtProvider.getNode(parent, historyNodeName, 1);
-            }
-
-            historyNodeName = new QName(NamespaceRegistryImpl.NS_DEFAULT_URI, uuid.substring(4));
-            VirtualNodeState vhNode;
-            if (parent.hasChildNodeEntry(historyNodeName)) {
-                vhNode = virtProvider.getNode(parent, historyNodeName, 1);
-            } else {
-                vhNode = virtProvider.addNode(parent, historyNodeName, vh.getId(), NodeTypeRegistry.NT_VERSION_HISTORY, null);
-            }
-
-            // add the versions
-            Iterator iter = vh.getVersions();
-            while (iter.hasNext()) {
-                InternalVersion v = (InternalVersion) iter.next();
-                mapVersion(vhNode, v);
-            }
-
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
-        }
     }
 
     /**
-     * Maps the internal version to its respective content representation
-     *
-     * @param vhNode
-     * @param version
-     * @throws RepositoryException
+     * Helper class that generates and hold generic definition ids
      */
-    private void mapVersion(VirtualNodeState vhNode, InternalVersion version)
-            throws RepositoryException {
-        try {
-            VirtualNodeState vNode;
-            if (vhNode.hasChildNodeEntry(version.getName())) {
-                vNode = virtProvider.getNode(vhNode, version.getName(), 1);
-            } else {
-                vNode = virtProvider.addNode(vhNode, version.getName(), version.getId(), NodeTypeRegistry.NT_VERSION, null);
-                // initialize the version
-                virtProvider.setPropertyValue(vNode, VersionManager.PROPNAME_CREATED, InternalValue.create(version.getCreated()));
-
-                // initialize the primary properties
-                InternalFrozenNode fNode = version.getFrozenNode();
-                virtProvider.setPropertyValue(vNode, VersionManager.PROPNAME_FROZEN_UUID, InternalValue.create(fNode.getFrozenUUID()));
-                virtProvider.setPropertyValue(vNode, VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE, InternalValue.create(fNode.getFrozenPrimaryType()));
-                virtProvider.setPropertyValues(vNode, VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, PropertyType.NAME, InternalValue.create(fNode.getFrozenMixinTypes()));
-                if (!version.isRootVersion()) {
-                    // don't map for root verion
-                    //mapFrozenProperties(vNode, fNode);
-                    mapFrozenNode(vNode, PersistentVersionManager.NODENAME_FROZEN, fNode);
-                }
-            }
+    private static class DefinitionIdMgr {
 
-            // map dynamic ones
-            mapDynamicProperties(vNode, version);
+        private final HashMap ids = new HashMap();
 
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
-        }
-    }
-
-    /**
-     * Maps those properties of the internal version to the content that might
-     * change over time. such as labels and successors.
-     *
-     * @param vNode
-     * @param version
-     * @throws RepositoryException
-     */
-    private void mapDynamicProperties(VirtualNodeState vNode, InternalVersion version) throws RepositoryException {
-        // add version labels
-        virtProvider.setPropertyValues(vNode, VersionManager.PROPNAME_VERSION_LABELS, PropertyType.STRING, InternalValue.create(version.internalGetLabels()));
-
-        // add predecessors
-        InternalVersion[] preds = version.getPredecessors();
-        InternalValue[] predV = new InternalValue[preds.length];
-        for (int i = 0; i < preds.length; i++) {
-            predV[i] = InternalValue.create(new UUID(preds[i].getId()));
-        }
-        virtProvider.setPropertyValues(vNode, VersionManager.PROPNAME_PREDECESSORS, PropertyType.REFERENCE, predV);
+        private final NodeTypeManagerImpl ntMgr;
 
-        // add successors
-        InternalVersion[] succ = version.getSuccessors();
-        InternalValue[] succV = new InternalValue[succ.length];
-        for (int i = 0; i < succ.length; i++) {
-            succV[i] = InternalValue.create(new UUID(succ[i].getId()));
+        public DefinitionIdMgr(NodeTypeManagerImpl ntMgr)
+                throws NoSuchNodeTypeException, RepositoryException {
+            this.ntMgr = ntMgr;
+            add(VersionManager.NODENAME_ROOTVERSION, NodeTypeRegistry.NT_VERSION, NodeTypeRegistry.NT_VERSION_HISTORY);
+            add(VersionManager.NODENAME_HISTORY_ROOT, NodeTypeRegistry.NT_UNSTRUCTURED, NodeTypeRegistry.NT_UNSTRUCTURED);
+            add(NodeTypeRegistry.NT_VERSION_HISTORY, NodeTypeRegistry.NT_VERSION_HISTORY, NodeTypeRegistry.NT_UNSTRUCTURED);
+            add(ItemImpl.PROPNAME_PRIMARYTYPE, NodeTypeRegistry.NT_BASE, PropertyType.NAME, false);
+            add(ItemImpl.PROPNAME_MIXINTYPES, NodeTypeRegistry.NT_BASE, PropertyType.NAME, true);
+            add(ItemImpl.PROPNAME_UUID, NodeTypeRegistry.MIX_REFERENCEABLE, PropertyType.STRING, false);
+            add(VersionManager.PROPNAME_CREATED, NodeTypeRegistry.NT_VERSION, PropertyType.DATE, false);
+            add(VersionManager.PROPNAME_FROZEN_UUID, NodeTypeRegistry.NT_VERSION, PropertyType.STRING, false);
+            add(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE, NodeTypeRegistry.NT_VERSION, PropertyType.NAME, false);
+            add(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES, NodeTypeRegistry.NT_VERSION, PropertyType.NAME, true);
+            add(VersionManager.PROPNAME_VERSION_LABELS, NodeTypeRegistry.NT_VERSION, PropertyType.STRING, true);
+            add(VersionManager.PROPNAME_PREDECESSORS, NodeTypeRegistry.NT_VERSION, PropertyType.REFERENCE, true);
+            add(VersionManager.PROPNAME_SUCCESSORS, NodeTypeRegistry.NT_VERSION, PropertyType.REFERENCE, true);
+        }
+
+        private void add(QName nodeName, QName nt, QName parentNt)
+                throws NoSuchNodeTypeException, RepositoryException {
+            NodeDefId id = new NodeDefId(
+                ntMgr.getNodeType(parentNt).getApplicableChildNodeDef(
+                    nodeName, nt
+                ).unwrap()
+            );
+            ids.put(nodeName, id);
+        }
+
+        private void add(QName propName, QName nt, int type, boolean multivalued)
+                throws NoSuchNodeTypeException, RepositoryException {
+            PropDefId id = new PropDefId(
+                ntMgr.getNodeType(nt).getApplicablePropertyDef(
+                        propName, type, multivalued
+                ).unwrap()
+            );
+            ids.put(propName, id);
         }
-        virtProvider.setPropertyValues(vNode, VersionManager.PROPNAME_SUCCESSORS, PropertyType.REFERENCE, succV);
-    }
 
-    private void mapFrozenProperties(VirtualNodeState node, InternalFrozenNode fNode)
-            throws RepositoryException {
-        try {
-            // initialize the content
-            PersistentProperty[] props = fNode.getFrozenProperties();
-            for (int i = 0; i < props.length; i++) {
-                virtProvider.setPropertyValues(node, props[i].getName(), props[i].getType(), props[i].getValues(), props[i].isMultiple());
-            }
-            InternalFreeze[] freezes = fNode.getFrozenChildNodes();
-            for (int i = 0; i < freezes.length; i++) {
-                if (freezes[i] instanceof InternalFrozenVersionHistory) {
-                    InternalFrozenVersionHistory vh = (InternalFrozenVersionHistory) freezes[i];
-                    VirtualNodeState fChild = virtProvider.addNode(node.getId(), vh.getName(), null, NodeTypeRegistry.NT_FROZEN_VERSIONABLE_CHILD);
-                    virtProvider.setPropertyValue(fChild, VersionManager.PROPNAME_VERSION_HISTORY, InternalValue.create(UUID.fromString(vh.getVersionHistoryId())));
-                } else { // instance of InternalFrozenNode
-                    InternalFrozenNode fn = (InternalFrozenNode) freezes[i];
-                    mapFrozenNode(node, fn.getName(), fn);
-                }
-            }
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
+        public NodeDefId getNodeDefId(QName name) {
+            return (NodeDefId) ids.get(name);
         }
-    }
-
-    /**
-     * Maps the frozen content of an internal version to the content
-     * representation.
-     *
-     * @param parent
-     * @param name
-     * @param fNode
-     * @throws RepositoryException
-     */
-    private void mapFrozenNode(VirtualNodeState parent, QName name, InternalFrozenNode fNode) throws RepositoryException {
-        try {
-            VirtualNodeState node = virtProvider.addNode(parent, name, null, fNode.getFrozenPrimaryType(), fNode.getFrozenMixinTypes());
-
-            // initialize the content
-            PersistentProperty[] props = fNode.getFrozenProperties();
-            for (int i = 0; i < props.length; i++) {
-                virtProvider.setPropertyValues(node, props[i].getName(), props[i].getType(), props[i].getValues(), props[i].isMultiple());
-            }
-            InternalFreeze[] freezes = fNode.getFrozenChildNodes();
-            for (int i = 0; i < freezes.length; i++) {
-                if (freezes[i] instanceof InternalFrozenVersionHistory) {
-                    InternalFrozenVersionHistory vh = (InternalFrozenVersionHistory) freezes[i];
-                    VirtualNodeState fChild = virtProvider.addNode(node.getId(), vh.getName(), null, NodeTypeRegistry.NT_FROZEN_VERSIONABLE_CHILD);
-                    virtProvider.setPropertyValue(fChild, VersionManager.PROPNAME_VERSION_HISTORY, InternalValue.create(UUID.fromString(vh.getVersionHistoryId())));
-                } else { // instance of InternalFrozenNode
-                    InternalFrozenNode fn = (InternalFrozenNode) freezes[i];
-                    mapFrozenNode(node, fn.getName(), fn);
-                }
-            }
-        } catch (ItemStateException e) {
-            throw new RepositoryException(e);
+        public PropDefId getPropDefId(QName name) {
+            return (PropDefId) ids.get(name);
         }
-
     }
 }

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionNodeState.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionNodeState.java?view=auto&rev=111518
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/version/VersionNodeState.java	Fri Dec 10 08:10:53 2004
@@ -0,0 +1,117 @@
+/*
+ * 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.virtual.VirtualNodeState;
+import org.apache.jackrabbit.core.virtual.VirtualPropertyState;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.InternalValue;
+import org.apache.jackrabbit.core.util.uuid.UUID;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+
+import javax.jcr.PropertyType;
+import java.util.Calendar;
+
+/**
+ * This Class implements...
+ *
+ * @author tripod
+ * @version $Revision:$, $Date:$
+ */
+public class VersionNodeState extends VirtualNodeState {
+
+    private final InternalVersion v;
+
+    public VersionNodeState(VersionItemStateProvider vm, InternalVersion v) {
+        super(vm, v.getId(), NodeTypeRegistry.NT_VERSION, v.getVersionHistory().getId());
+        this.v = v;
+
+        // we map the property entries, since they do not change
+        addPropertyEntry(VersionManager.PROPNAME_CREATED);
+        addPropertyEntry(VersionManager.PROPNAME_FROZEN_UUID);
+        addPropertyEntry(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE);
+        addPropertyEntry(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES);
+        addPropertyEntry(VersionManager.PROPNAME_VERSION_LABELS);
+        addPropertyEntry(VersionManager.PROPNAME_PREDECESSORS);
+        addPropertyEntry(VersionManager.PROPNAME_SUCCESSORS);
+
+        // and the frozen node if not root version
+        if (!v.isRootVersion()) {
+            addChildNodeEntry(v.getFrozenNode().getName(), v.getFrozenNode().getInternalUUID());
+        }
+
+        setDefinitionId(vm.getNodeDefId(VersionManager.NODENAME_ROOTVERSION));
+    }
+
+    public VirtualPropertyState getPropertyState(QName name) throws NoSuchItemStateException {
+        if (name.equals(VersionManager.PROPNAME_CREATED)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_CREATED));
+            state.setType(PropertyType.DATE);
+            state.setValues(InternalValue.create(new Calendar[]{v.getCreated()}));
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_FROZEN_UUID)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_FROZEN_UUID));
+            state.setType(PropertyType.STRING);
+            state.setValues(InternalValue.create(new String[]{v.getFrozenNode().getUUID()}));
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_FROZEN_PRIMARY_TYPE));
+            state.setType(PropertyType.NAME);
+            state.setValues(InternalValue.create(new QName[]{v.getFrozenNode().getFrozenPrimaryType()}));
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_FROZEN_MIXIN_TYPES));
+            state.setType(PropertyType.NAME);
+            state.setValues(InternalValue.create(v.getFrozenNode().getFrozenMixinTypes()));
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_VERSION_LABELS)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_VERSION_LABELS));
+            state.setType(PropertyType.STRING);
+            state.setValues(InternalValue.create(v.internalGetLabels()));
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_PREDECESSORS)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_PREDECESSORS));
+            state.setType(PropertyType.STRING);
+            InternalVersion[] preds = v.getPredecessors();
+            InternalValue[] predV = new InternalValue[preds.length];
+            for (int i=0; i<preds.length; i++) {
+                predV[i] = InternalValue.create(new UUID(preds[i].getId()));
+            }
+            state.setValues(predV);
+            return state;
+        } else if (name.equals(VersionManager.PROPNAME_SUCCESSORS)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(VersionManager.PROPNAME_SUCCESSORS));
+            state.setType(PropertyType.STRING);
+            InternalVersion[] succs = v.getSuccessors();
+            InternalValue[] succV = new InternalValue[succs.length];
+            for (int i=0; i<succs.length; i++) {
+                succV[i] = InternalValue.create(new UUID(succs[i].getId()));
+            }
+            state.setValues(succV);
+            return state;
+        } else {
+            return super.getPropertyState(name);
+        }
+    }
+}

Deleted: /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/DefaultItemStateProvider.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/DefaultItemStateProvider.java?view=auto&rev=111517
==============================================================================

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualItemStateProvider.java	Fri Dec 10 08:10:53 2004
@@ -16,9 +16,25 @@
 package org.apache.jackrabbit.core.virtual;
 
 import org.apache.jackrabbit.core.state.ItemStateProvider;
+import org.apache.jackrabbit.core.nodetype.NodeDefId;
+import org.apache.jackrabbit.core.nodetype.PropDefId;
+import org.apache.jackrabbit.core.QName;
 
 /**
  * This Interface defines a virtual item state provider.
  */
 public interface VirtualItemStateProvider extends ItemStateProvider {
+    /**
+     * Returns a predefined node definition id. 
+     * @param nodename
+     * @return
+     */
+    public NodeDefId getNodeDefId(QName nodename);
+
+    /**
+     * Returns a predefined property definition id
+     * @param propname
+     * @return
+     */
+    public PropDefId getPropDefId(QName propname);
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java?view=diff&rev=111518&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java&r1=111517&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java&r2=111518
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java	(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/virtual/VirtualNodeState.java	Fri Dec 10 08:10:53 2004
@@ -16,21 +16,58 @@
 package org.apache.jackrabbit.core.virtual;
 
 import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.ItemImpl;
+import org.apache.jackrabbit.core.InternalValue;
 import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.NoSuchItemStateException;
+
+import javax.jcr.PropertyType;
 
 /**
  * This Class implements a virtual node state
  */
 public class VirtualNodeState extends NodeState {
 
+    protected VirtualItemStateProvider provider;
+    
     /**
      * @param uuid
      * @param nodeTypeName
      * @param parentUUID
      */
-    protected VirtualNodeState(String uuid, QName nodeTypeName, String parentUUID) {
+    protected VirtualNodeState(VirtualItemStateProvider provider,
+                               String uuid, QName nodeTypeName, String parentUUID) {
         super(uuid, nodeTypeName, parentUUID, ItemState.STATUS_EXISTING);
+
+        this.provider = provider;
+
+        // add some props
+        addPropertyEntry(ItemImpl.PROPNAME_PRIMARYTYPE);
+        addPropertyEntry(ItemImpl.PROPNAME_MIXINTYPES);
     }
 
+    public VirtualPropertyState getPropertyState(QName name)
+            throws NoSuchItemStateException {
+        if (name.equals(ItemImpl.PROPNAME_PRIMARYTYPE)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(ItemImpl.PROPNAME_PRIMARYTYPE));
+            state.setType(PropertyType.NAME);
+            state.setValues(InternalValue.create(new QName[]{getNodeTypeName()}));
+            return state;
+        } else if (name.equals(ItemImpl.PROPNAME_MIXINTYPES)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(ItemImpl.PROPNAME_MIXINTYPES));
+            state.setType(PropertyType.NAME);
+            state.setValues(InternalValue.create((QName[]) getMixinTypeNames().toArray(new QName[getMixinTypeNames().size()])));
+            return state;
+        } else if (name.equals(ItemImpl.PROPNAME_UUID)) {
+            VirtualPropertyState state = new VirtualPropertyState(name, getUUID());
+            state.setDefinitionId(provider.getPropDefId(ItemImpl.PROPNAME_UUID));
+            state.setType(PropertyType.STRING);
+            state.setValues(InternalValue.create(new String[]{getUUID()}));
+            return state;
+        }
+        throw new NoSuchItemStateException(name.toString());
+    }
 }