You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2006/01/11 15:24:32 UTC

svn commit: r368026 [2/3] - in /incubator/jackrabbit/trunk/jackrabbit/src: main/java/org/apache/jackrabbit/core/ main/java/org/apache/jackrabbit/core/lock/ main/java/org/apache/jackrabbit/core/observation/ main/java/org/apache/jackrabbit/core/state/ ma...

Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java?rev=368026&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java Wed Jan 11 06:22:57 2006
@@ -0,0 +1,194 @@
+/*
+ * 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.ItemLifeCycleListener;
+import org.apache.jackrabbit.core.ItemManager;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.log4j.Logger;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.NodeIterator;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import java.util.Calendar;
+
+/**
+ * Base implementation of the {@link javax.jcr.version.Version} interface.
+ */
+public abstract class AbstractVersion extends NodeImpl implements Version {
+
+    /**
+     * Logger instance.
+     */
+    private static Logger log = Logger.getLogger(AbstractVersion.class);
+
+    /**
+     * Create a new instance of this class.
+     * @param itemMgr item manager
+     * @param session session
+     * @param id node id
+     * @param state node state
+     * @param definition node definition
+     * @param listeners life cycle listeners
+     */
+    protected AbstractVersion(ItemManager itemMgr, SessionImpl session, NodeId id,
+                          NodeState state, NodeDefinition definition,
+                          ItemLifeCycleListener[] listeners) {
+        super(itemMgr, session, id, state, definition, listeners);
+    }
+
+    /**
+     * Returns the internal version. Subclass responsibility.
+     * @return internal version
+     * @throws RepositoryException if the internal version is not available
+     */
+    protected abstract InternalVersion getInternalVersion()
+            throws RepositoryException;
+
+    /**
+     * {@inheritDoc}
+     */
+    public Calendar getCreated() throws RepositoryException {
+        return getInternalVersion().getCreated();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Version[] getSuccessors() throws RepositoryException {
+        // need to wrap it around proper node
+        InternalVersion[] suc = getInternalVersion().getSuccessors();
+        Version[] ret = new Version[suc.length];
+        for (int i = 0; i < suc.length; i++) {
+            ret[i] = (Version) session.getNodeByUUID(suc[i].getId());
+        }
+        return ret;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Version[] getPredecessors() throws RepositoryException {
+        // need to wrap it around proper node
+        InternalVersion[] pred = getInternalVersion().getPredecessors();
+        Version[] ret = new Version[pred.length];
+        for (int i = 0; i < pred.length; i++) {
+            ret[i] = (Version) session.getNodeByUUID(pred[i].getId());
+        }
+        return ret;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException {
+        return getInternalVersion().getId();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public VersionHistory getContainingHistory() throws RepositoryException {
+        return (VersionHistory) getParent();
+    }
+
+    /**
+     * Returns the frozen node of this version
+     *
+     * @return
+     * @throws javax.jcr.RepositoryException
+     */
+    public InternalFrozenNode getFrozenNode() throws RepositoryException {
+        return getInternalVersion().getFrozenNode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isSame(Item otherItem) {
+        if (otherItem instanceof AbstractVersion) {
+            // since all versions live in the same workspace, we can compare the uuids
+            try {
+                InternalVersion other = ((AbstractVersion) otherItem).getInternalVersion();
+                return other.getId().equals(getInternalVersion().getId());
+            } catch (RepositoryException e) {
+                log.warn("Unable to retrieve internal version objects: " + e.getMessage());
+                log.debug("Stack dump:", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Checks if this version is more recent than the given version <code>v</code>.
+     * A version is more recent if and only if it is a successor (or a successor
+     * of a successor, etc., to any degree of separation) of the compared one.
+     *
+     * @param v the version to check
+     * @return <code>true</code> if the version is more recent;
+     *         <code>false</code> otherwise.
+     */
+    public boolean isMoreRecent(AbstractVersion v) throws RepositoryException {
+        return getInternalVersion().isMoreRecent(v.getInternalVersion());
+    }
+
+    /**
+     * Checks if this is the root version.
+     * @return <code>true</code> if this version is the root version;
+     *         <code>false</code> otherwise.
+     */
+    public boolean isRootVersion() throws RepositoryException {
+        return getInternalVersion().isRootVersion();
+    }
+
+    //--------------------------------------< Overwrite "protected" methods >---
+
+
+    /**
+     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
+     * is protected.
+     *
+     * @throws javax.jcr.nodetype.ConstraintViolationException
+     */
+    public void update(String srcWorkspaceName) throws ConstraintViolationException {
+        String msg = "update operation not allowed on a version node: " + safeGetJCRPath();
+        log.debug(msg);
+        throw new ConstraintViolationException(msg);
+    }
+
+    /**
+     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
+     * is protected.
+     *
+     * @throws javax.jcr.nodetype.ConstraintViolationException
+     */
+    public NodeIterator merge(String srcWorkspace, boolean bestEffort)
+            throws ConstraintViolationException {
+        String msg = "merge operation not allowed on a version node: " + safeGetJCRPath();
+        log.debug(msg);
+        throw new ConstraintViolationException(msg);
+    }
+
+}

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

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersion.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java?rev=368026&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java Wed Jan 11 06:22:57 2006
@@ -0,0 +1,319 @@
+/*
+ * 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.ItemLifeCycleListener;
+import org.apache.jackrabbit.core.ItemManager;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.log4j.Logger;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.NodeIterator;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+
+/**
+ * Base implementation of the {@link javax.jcr.version.VersionHistory} interface.
+ */
+public abstract class AbstractVersionHistory extends NodeImpl implements VersionHistory {
+
+    /**
+     * Logger instance.
+     */
+    private static Logger log = Logger.getLogger(AbstractVersionHistory.class);
+
+    /**
+     * Create a new instance of this class.
+     * @param itemMgr item manager
+     * @param session session
+     * @param id node id
+     * @param state node state
+     * @param definition node definition
+     * @param listeners life cycle listeners
+     */
+    public AbstractVersionHistory(ItemManager itemMgr, SessionImpl session, NodeId id,
+                              NodeState state, NodeDefinition definition,
+                              ItemLifeCycleListener[] listeners) {
+        super(itemMgr, session, id, state, definition, listeners);
+    }
+
+    /**
+     * Returns the internal version history. Subclass responsibility.
+     * @return internal version history
+     * @throws RepositoryException if the internal version history is not available
+     */
+    protected abstract InternalVersionHistory getInternalVersionHistory()
+            throws RepositoryException;
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getRootVersion()
+     */
+    public Version getRootVersion() throws RepositoryException {
+        return (Version) session.getNodeByUUID(
+                getInternalVersionHistory().getRootVersion().getId());
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getAllVersions()
+     */
+    public VersionIterator getAllVersions() throws RepositoryException {
+        return new VersionIteratorImpl(session,
+                getInternalVersionHistory().getRootVersion());
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getVersion(String)
+     */
+    public Version getVersion(String versionName)
+            throws VersionException, RepositoryException {
+        try {
+            QName name = QName.fromJCRName(versionName, session.getNamespaceResolver());
+            InternalVersion v = getInternalVersionHistory().getVersion(name);
+            if (v == null) {
+                throw new VersionException("No version with name '" + versionName + "' exists in this version history.");
+            }
+            return (Version) session.getNodeByUUID(v.getId());
+        } catch (IllegalNameException e) {
+            throw new VersionException(e);
+        } catch (UnknownPrefixException e) {
+            throw new VersionException(e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getVersionByLabel(String)
+     */
+    public Version getVersionByLabel(String label) throws RepositoryException {
+        try {
+            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
+            InternalVersion v = getInternalVersionHistory().getVersionByLabel(qLabel);
+            if (v == null) {
+                throw new VersionException("No version with label '" + label + "' exists in this version history.");
+            }
+            return (Version) session.getNodeByUUID(v.getId());
+        } catch (IllegalNameException e) {
+            throw new VersionException(e);
+        } catch (UnknownPrefixException e) {
+            throw new VersionException(e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#addVersionLabel(String, String, boolean)
+     */
+    public void addVersionLabel(String versionName, String label, boolean move)
+            throws VersionException, RepositoryException {
+        try {
+            session.getVersionManager().setVersionLabel(this,
+                    QName.fromJCRName(versionName, session.getNamespaceResolver()),
+                    QName.fromJCRName(label, session.getNamespaceResolver()),
+                    move);
+        } catch (IllegalNameException e) {
+            throw new VersionException(e);
+        } catch (UnknownPrefixException e) {
+            throw new VersionException(e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#removeVersionLabel(String)
+     */
+    public void removeVersionLabel(String label) throws RepositoryException {
+        try {
+            Version existing = session.getVersionManager().setVersionLabel(this,
+                    null,
+                    QName.fromJCRName(label, session.getNamespaceResolver()),
+                    true);
+            if (existing == null) {
+                throw new VersionException("No version with label '" + label + "' exists in this version history.");
+            }
+        } catch (IllegalNameException e) {
+            throw new VersionException(e);
+        } catch (UnknownPrefixException e) {
+            throw new VersionException(e);
+        }
+    }
+
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getVersionLabels
+     */
+    public String[] getVersionLabels() throws RepositoryException {
+        try {
+            QName[] labels = getInternalVersionHistory().getVersionLabels();
+            String[] ret = new String[labels.length];
+            for (int i = 0; i < labels.length; i++) {
+                ret[i] = labels[i].toJCRName(session.getNamespaceResolver());
+            }
+            return ret;
+        } catch (NoPrefixDeclaredException e) {
+            throw new IllegalArgumentException("Unable to resolve label name: " + e.toString());
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#getVersionLabels(javax.jcr.version.Version)
+     */
+    public String[] getVersionLabels(Version version)
+            throws VersionException, RepositoryException {
+        checkOwnVersion(version);
+        try {
+            QName[] labels = ((AbstractVersion) version).getInternalVersion().getLabels();
+            String[] ret = new String[labels.length];
+            for (int i = 0; i < labels.length; i++) {
+                ret[i] = labels[i].toJCRName(session.getNamespaceResolver());
+            }
+            return ret;
+        } catch (NoPrefixDeclaredException e) {
+            throw new IllegalArgumentException("Unable to resolve label name: " + e.toString());
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#hasVersionLabel(String)
+     */
+    public boolean hasVersionLabel(String label) throws RepositoryException {
+        try {
+            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
+            return getInternalVersionHistory().getVersionByLabel(qLabel) != null;
+        } catch (IllegalNameException e) {
+            throw new IllegalArgumentException("Unable to resolve label: " + e);
+        } catch (UnknownPrefixException e) {
+            throw new IllegalArgumentException("Unable to resolve label: " + e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#hasVersionLabel(javax.jcr.version.Version, String)
+     */
+    public boolean hasVersionLabel(Version version, String label)
+            throws VersionException, RepositoryException {
+        checkOwnVersion(version);
+        try {
+            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
+            return ((AbstractVersion) version).getInternalVersion().hasLabel(qLabel);
+        } catch (IllegalNameException e) {
+            throw new VersionException(e);
+        } catch (UnknownPrefixException e) {
+            throw new VersionException(e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.version.VersionHistory#removeVersion(String)
+     */
+    public void removeVersion(String versionName)
+            throws UnsupportedRepositoryOperationException, VersionException,
+            RepositoryException {
+        try {
+            session.getVersionManager().removeVersion(this,
+                    QName.fromJCRName(versionName, session.getNamespaceResolver()));
+        } catch (IllegalNameException e) {
+            throw new RepositoryException(e);
+        } catch (UnknownPrefixException e) {
+            throw new RepositoryException(e);
+        }
+    }
+
+    /**
+     * @see javax.jcr.Node#getUUID()
+     */
+    public String getUUID()
+            throws UnsupportedRepositoryOperationException, RepositoryException {
+        return getInternalVersionHistory().getId();
+    }
+
+    /**
+     * @see javax.jcr.Item#isSame(javax.jcr.Item)
+     */
+    public boolean isSame(Item otherItem) {
+        if (otherItem instanceof AbstractVersionHistory) {
+            // since all version histories live in the same workspace, we can compare the uuids
+            try {
+                InternalVersionHistory other = ((AbstractVersionHistory) otherItem).getInternalVersionHistory();
+                return other.getId().equals(getInternalVersionHistory().getId());
+            } catch (RepositoryException e) {
+                log.warn("Unable to retrieve internal version history objects: " + e.getMessage());
+                log.debug("Stack dump:", e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the UUID of the node that was versioned.
+     *
+     * @return
+     */
+    public String getVersionableUUID() throws RepositoryException {
+        return getInternalVersionHistory().getVersionableUUID();
+    }
+
+    /**
+     * Checks if the given version belongs to this history
+     *
+     * @param version
+     * @throws javax.jcr.version.VersionException
+     * @throws javax.jcr.RepositoryException
+     */
+    private void checkOwnVersion(Version version)
+            throws VersionException, RepositoryException {
+        if (!version.getParent().isSame(this)) {
+            throw new VersionException("Specified version not contained in this history.");
+        }
+    }
+
+    //--------------------------------------< Overwrite "protected" methods >---
+
+    /**
+     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
+     * is protected.
+     *
+     * @throws javax.jcr.nodetype.ConstraintViolationException
+     */
+    public void update(String srcWorkspaceName) throws ConstraintViolationException {
+        String msg = "update operation not allowed on a version history node: " + safeGetJCRPath();
+        log.debug(msg);
+        throw new ConstraintViolationException(msg);
+    }
+
+    /**
+     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
+     * is protected.
+     *
+     * @throws javax.jcr.nodetype.ConstraintViolationException
+     */
+    public NodeIterator merge(String srcWorkspace, boolean bestEffort)
+            throws ConstraintViolationException {
+        String msg = "merge operation not allowed on a version history node: " + safeGetJCRPath();
+        log.debug(msg);
+        throw new ConstraintViolationException(msg);
+    }
+}

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

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionHistory.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java?rev=368026&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java (added)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java Wed Jan 11 06:22:57 2006
@@ -0,0 +1,370 @@
+/*
+ * 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.NodeImpl;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.LocalItemStateManager;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.uuid.UUID;
+import org.apache.log4j.Logger;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.Session;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+import java.util.List;
+
+/**
+ * Base implementation of the {@link VersionManager} interface.
+ */
+abstract class AbstractVersionManager implements VersionManager {
+
+    /**
+     * Logger instance.
+     */
+    private static Logger log = Logger.getLogger(AbstractVersionManager.class);
+
+    /**
+     * State manager for the version storage.
+     */
+    protected LocalItemStateManager stateMgr;
+
+    /**
+     * Persistent root node of the version histories.
+     */
+    protected NodeStateEx historyRoot;
+
+    //-------------------------------------------------------< VersionManager >
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersion getVersion(String uuid) throws RepositoryException {
+        return (InternalVersion) getItem(uuid);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InternalVersionHistory getVersionHistory(String uuid)
+            throws RepositoryException {
+
+        return (InternalVersionHistory) getItem(uuid);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasVersionHistory(String id) {
+        return hasItem(id);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasVersion(String id) {
+        return hasItem(id);
+    }
+
+    //-------------------------------------------------------< implementation >
+
+    /**
+     * {@inheritDoc}
+     */
+    public VersionHistory getVersionHistory(Session session, NodeState node)
+            throws RepositoryException {
+
+        String vhId = getVersionHistoryId(node);
+        if (vhId == null) {
+            return null;
+        }
+        return (VersionHistory) session.getNodeByUUID(vhId);
+    }
+
+    /**
+     * Returns the item with the given persistent id. Subclass responsibility.
+     * @param uuid uuid of item
+     * @return version item
+     * @throws RepositoryException if an error occurs
+     */
+    protected abstract InternalVersionItem getItem(String uuid)
+            throws RepositoryException;
+
+    /**
+     * Return a flag indicating if the item specified exists.
+     * Subclass responsibility.
+     * @param uuid uuid of item
+     * @return <code>true</code> if the item exists;
+     *         <code>false</code> otherwise
+     */
+    protected abstract boolean hasItem(String uuid);
+
+    /**
+     * Returns the item references that reference the given version item.
+     * Subclass responsiblity.
+     * @param item version item
+     * @return list of item references, may be empty.
+     */
+    protected abstract List getItemReferences(InternalVersionItem item);
+
+    /**
+     * 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 javax.jcr.RepositoryException
+     */
+    InternalVersionHistory createVersionHistory(NodeState node)
+            throws RepositoryException {
+
+        try {
+            stateMgr.edit();
+        } catch (IllegalStateException e) {
+            throw new RepositoryException("Unable to start edit operation", e);
+        }
+
+        boolean succeeded = false;
+
+        try {
+            // create deep path
+            String uuid = node.getUUID();
+            NodeStateEx root = historyRoot;
+            for (int i = 0; i < 3; i++) {
+                QName name = new QName(QName.NS_DEFAULT_URI, uuid.substring(i * 2, i * 2 + 2));
+                if (!root.hasNode(name)) {
+                    root.addNode(name, QName.REP_VERSIONSTORAGE, null, false);
+                    root.store();
+                }
+                root = root.getNode(name, 1);
+            }
+            QName historyNodeName = new QName(QName.NS_DEFAULT_URI, uuid);
+            if (root.hasNode(historyNodeName)) {
+                // already exists
+                return null;
+            }
+
+            // create new history node in the persistent state
+            InternalVersionHistoryImpl hist = InternalVersionHistoryImpl.create(
+                    this, root, UUID.randomUUID().toString(), historyNodeName, node);
+
+            // end update
+            stateMgr.update();
+            succeeded = true;
+
+            log.info("Created new version history " + hist.getId() + " for " + node + ".");
+            return hist;
+
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        } finally {
+            if (!succeeded) {
+                // update operation failed, cancel all modifications
+                stateMgr.cancel();
+            }
+        }
+    }
+
+    /**
+     * Returns the id of the version history associated with the given node
+     * or <code>null</code> if that node doesn't have a version history.
+     *
+     * @param node the node whose version history's id is to be returned.
+     * @return the the id of the version history associated with the given node
+     *         or <code>null</code> if that node doesn't have a version history.
+     * @throws javax.jcr.RepositoryException if an error occurs
+     */
+    String getVersionHistoryId(NodeState node) throws RepositoryException {
+
+        // build and traverse path
+        String uuid = node.getUUID();
+        NodeStateEx n = historyRoot;
+        for (int i = 0; i < 3; i++) {
+            QName name = new QName(QName.NS_DEFAULT_URI, uuid.substring(i * 2, i * 2 + 2));
+            if (!n.hasNode(name)) {
+                return null;
+            }
+            n = n.getNode(name, 1);
+        }
+        QName historyNodeName = new QName(QName.NS_DEFAULT_URI, uuid);
+        if (!n.hasNode(historyNodeName)) {
+            return null;
+        }
+        return n.getNode(historyNodeName, 1).getUUID();
+    }
+
+    /**
+     * Checks in a node
+     *
+     * @param node node to checkin
+     * @return internal version
+     * @throws javax.jcr.RepositoryException if an error occurs
+     * @see javax.jcr.Node#checkin()
+     */
+    protected InternalVersion checkin(InternalVersionHistoryImpl history, NodeImpl node)
+            throws RepositoryException {
+
+        // 0. resolve the predecessors
+        Value[] values = node.getProperty(QName.JCR_PREDECESSORS).getValues();
+        InternalVersion[] preds = new InternalVersion[values.length];
+        for (int i = 0; i < values.length; i++) {
+            preds[i] = history.getVersion(values[i].getString());
+        }
+
+        // 0.1 search a predecessor, suitable for generating the new name
+        String versionName = null;
+        int maxDots = Integer.MAX_VALUE;
+        for (int i = 0; i < preds.length; i++) {
+            // take the first pred. without a successor
+            if (preds[i].getSuccessors().length == 0) {
+                versionName = preds[i].getName().getLocalName(); //assuming no namespaces in version names
+                // need to count the dots
+                int pos = -1;
+                int numDots = 0;
+                while (versionName.indexOf('.', pos + 1) >= 0) {
+                    pos = versionName.indexOf('.', pos + 1);
+                    numDots++;
+                }
+                if (numDots < maxDots) {
+                    maxDots = numDots;
+                    if (pos < 0) {
+                        versionName = "1.0";
+                    } else {
+                        versionName = versionName.substring(0, pos + 1)
+                                + (Integer.parseInt(versionName.substring(pos + 1)) + 1);
+                    }
+                }
+                break;
+            }
+        }
+        // if no empty found, generate new name
+        if (versionName == null) {
+            versionName = preds[0].getName().getLocalName();
+            do {
+                versionName += ".1";
+            } while (history.hasVersion(new QName("", versionName)));
+        }
+
+        try {
+            stateMgr.edit();
+        } catch (IllegalStateException e) {
+            throw new RepositoryException("Unable to start edit operation.");
+        }
+
+        boolean succeeded = false;
+
+        try {
+            InternalVersionImpl v = history.checkin(new QName("", versionName), node);
+            stateMgr.update();
+            succeeded = true;
+
+            return v;
+        } catch (ItemStateException e) {
+            throw new RepositoryException(e);
+        } finally {
+            if (!succeeded) {
+                // update operation failed, cancel all modifications
+                stateMgr.cancel();
+            }
+        }
+    }
+
+
+    /**
+     * Removes the specified version from the history
+     *
+     * @param history the version history from where to remove the version.
+     * @param name the name of the version to remove.
+     * @throws javax.jcr.version.VersionException if the version <code>history</code> does
+     *  not have a version with <code>name</code>.
+     * @throws javax.jcr.RepositoryException if any other error occurs.
+     */
+    protected void removeVersion(InternalVersionHistoryImpl history, QName name)
+            throws VersionException, RepositoryException {
+
+        try {
+            stateMgr.edit();
+        } catch (IllegalStateException e) {
+            throw new VersionException("Unable to start edit operation", e);
+        }
+        boolean succeeded = false;
+        try {
+            history.removeVersion(name);
+            stateMgr.update();
+            succeeded = true;
+        } catch (ItemStateException e) {
+            log.error("Error while storing: " + e.toString());
+        } finally {
+            if (!succeeded) {
+                // update operation failed, cancel all modifications
+                stateMgr.cancel();
+            }
+        }
+    }
+
+    /**
+     * Set version label on the specified version.
+     * @param history version history
+     * @param version version name
+     * @param label version label
+     * @param move <code>true</code> to move from existing version;
+     *             <code>false</code> otherwise
+     * @throws RepositoryException if an error occurs
+     */
+    protected InternalVersion setVersionLabel(InternalVersionHistoryImpl history,
+                                              QName version, QName label,
+                                              boolean move)
+            throws RepositoryException {
+
+        try {
+            stateMgr.edit();
+        } catch (IllegalStateException e) {
+            throw new VersionException("Unable to start edit operation", e);
+        }
+        InternalVersion v = null;
+        boolean success = false;
+        try {
+            v = history.setVersionLabel(version, label, move);
+            stateMgr.update();
+            success = true;
+        } catch(ItemStateException e) {
+            log.error("Error while storing: " + e.toString());
+        } finally {
+            if (!success) {
+                // update operation failed, cancel all modifications
+                stateMgr.cancel();
+            }
+        }
+        return v;
+    }
+
+    /**
+     * Invoked when a new internal item has been created.
+     * @param version internal version item
+     */
+    protected void versionCreated(InternalVersion version) {
+    }
+
+    /**
+     * Invoked when a new internal item has been destroyed.
+     * @param version internal version item
+     */
+    protected void versionDestroyed(InternalVersion version) {
+    }
+}

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

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/AbstractVersionManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFreezeImpl.java Wed Jan 11 06:22:57 2006
@@ -33,7 +33,7 @@
      * @param vMgr
      * @param parent
      */
-    protected InternalFreezeImpl(VersionManagerImpl vMgr, InternalVersionItem parent) {
+    protected InternalFreezeImpl(AbstractVersionManager vMgr, InternalVersionItem parent) {
         super(vMgr);
         this.parent = parent;
     }

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenNodeImpl.java Wed Jan 11 06:22:57 2006
@@ -40,7 +40,7 @@
 /**
  * Implements a <code>InternalFrozenNode</code>
  */
-public class InternalFrozenNodeImpl extends InternalFreezeImpl
+class InternalFrozenNodeImpl extends InternalFreezeImpl
         implements InternalFrozenNode {
 
     /**
@@ -90,7 +90,7 @@
      * @param node
      * @throws javax.jcr.RepositoryException
      */
-    public InternalFrozenNodeImpl(VersionManagerImpl vMgr, NodeStateEx node,
+    public InternalFrozenNodeImpl(AbstractVersionManager vMgr, NodeStateEx node,
                                   InternalVersionItem parent)
             throws RepositoryException {
         super(vMgr, parent);
@@ -169,7 +169,7 @@
             int i = 0;
             while (iter.hasNext()) {
                 NodeState.ChildNodeEntry entry = (NodeState.ChildNodeEntry) iter.next();
-                freezes[i++] = (InternalFreeze) getVersionManager().getItem(entry.getUUID());
+                freezes[i++] = (InternalFreeze) vMgr.getItem(entry.getUUID());
             }
             return freezes;
         } catch (RepositoryException e) {
@@ -184,7 +184,7 @@
         try {
             NodeState.ChildNodeEntry entry  = node.getState().getChildNodeEntry(uuid);
             if (entry != null) {
-                return getVersionManager().getItem(uuid) instanceof InternalFrozenVersionHistory;
+                return vMgr.getItem(uuid) instanceof InternalFrozenVersionHistory;
             }
         } catch (RepositoryException e) {
             // ignore

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalFrozenVHImpl.java Wed Jan 11 06:22:57 2006
@@ -24,7 +24,7 @@
 /**
  * Implements a <code>InternalFrozenVersionHistory</code>
  */
-public class InternalFrozenVHImpl extends InternalFreezeImpl
+class InternalFrozenVHImpl extends InternalFreezeImpl
         implements InternalFrozenVersionHistory {
 
     /**
@@ -37,7 +37,7 @@
      *
      * @param node
      */
-    public InternalFrozenVHImpl(VersionManagerImpl vMgr, NodeStateEx node,
+    public InternalFrozenVHImpl(AbstractVersionManager vMgr, NodeStateEx node,
                                 InternalVersionItem parent) {
         super(vMgr, parent);
         this.node = node;
@@ -71,7 +71,7 @@
     public InternalVersionHistory getVersionHistory()
             throws VersionException {
         try {
-            return getVersionManager().getVersionHistory(getVersionHistoryId());
+            return vMgr.getVersionHistory(getVersionHistoryId());
         } catch (RepositoryException e) {
             throw new VersionException(e);
         }
@@ -90,7 +90,7 @@
     public InternalVersion getBaseVesion()
             throws VersionException {
         try {
-            InternalVersionHistory history = getVersionManager().getVersionHistory(getVersionHistoryId());
+            InternalVersionHistory history = vMgr.getVersionHistory(getVersionHistoryId());
             return history.getVersion(getBaseVersionId());
         } catch (RepositoryException e) {
             throw new VersionException(e);

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionHistoryImpl.java Wed Jan 11 06:22:57 2006
@@ -39,7 +39,7 @@
 /**
  * Implements a <code>InternalVersionHistory</code>
  */
-public class InternalVersionHistoryImpl extends InternalVersionItemImpl
+class InternalVersionHistoryImpl extends InternalVersionItemImpl
         implements InternalVersionHistory {
 
     /**
@@ -67,6 +67,11 @@
     private HashMap versionCache = new HashMap();
 
     /**
+     * Temporary version cache, used on a refresh.
+     */
+    private HashMap tempVersionCache = new HashMap();
+
+    /**
      * The nodes state of this version history
      */
     private NodeStateEx node;
@@ -89,7 +94,7 @@
     /**
      * Creates a new VersionHistory object for the given node state.
      */
-    public InternalVersionHistoryImpl(VersionManagerImpl vMgr, NodeStateEx node)
+    public InternalVersionHistoryImpl(AbstractVersionManager vMgr, NodeStateEx node)
             throws RepositoryException {
         super(vMgr);
         this.node = node;
@@ -119,11 +124,12 @@
                 labelNode = child;
                 continue;
             }
-            InternalVersionImpl v = new InternalVersionImpl(this, child, child.getName());
+            InternalVersionImpl v = createVersionInstance(child);
             versionCache.put(v.getId(), v);
             if (v.isRootVersion()) {
                 rootVersion = v;
             }
+            vMgr.versionCreated(v);
         }
 
         // resolve successors and predecessors
@@ -152,6 +158,38 @@
     }
 
     /**
+     * Reload this object and all its dependent version objects.
+     */
+    void reload() throws RepositoryException {
+        tempVersionCache.putAll(versionCache);
+
+        init();
+
+        // invalidate all versions that are not referenced any more
+        Iterator iter = tempVersionCache.values().iterator();
+        while (iter.hasNext()) {
+            InternalVersionImpl v = (InternalVersionImpl) iter.next();
+            v.invalidate();
+        }
+        tempVersionCache.clear();
+    }
+
+    /**
+     * Create a version instance. May resurrect versions temporarily swapped
+     * out when refreshing this history.
+     */
+    InternalVersionImpl createVersionInstance(NodeStateEx child) {
+        InternalVersionImpl v = (InternalVersionImpl) tempVersionCache.remove(child.getUUID());
+        if (v != null) {
+            v.clear();
+        }
+        if (v == null) {
+            v = new InternalVersionImpl(this, child, child.getName());
+        }
+        return v;
+    }
+
+    /**
      * {@inheritDoc}
      */
     public String getId() {
@@ -279,7 +317,7 @@
             throw new VersionException(msg);
         }
         // check if any references (from outside the version storage) exist on this version
-        List refs = getVersionManager().getItemReferences(v);
+        List refs = vMgr.getItemReferences(v);
         if (!refs.isEmpty()) {
             throw new ReferentialIntegrityException("Unable to remove version. At least once referenced.");
         }
@@ -298,6 +336,7 @@
 
         // and remove from history
         versionCache.remove(v.getId());
+        vMgr.versionDestroyed(v);
 
         // store changes
         node.store();
@@ -403,6 +442,7 @@
         // update version graph
         InternalVersionImpl version = new InternalVersionImpl(this, vNode, name);
         version.resolvePredecessors();
+        vMgr.versionCreated(version);
 
         // and store
         node.store();
@@ -422,29 +462,25 @@
      * @return
      * @throws RepositoryException
      */
-    static InternalVersionHistoryImpl create(VersionManagerImpl vMgr,
+    static InternalVersionHistoryImpl create(AbstractVersionManager vMgr,
                                              NodeStateEx parent,
                                              String historyId, QName name,
-                                             NodeState nodeState,
-                                             List created)
+                                             NodeState nodeState)
             throws RepositoryException {
 
         // create history node
         NodeStateEx pNode = parent.addNode(name, QName.NT_VERSIONHISTORY, historyId, true);
-        created.add(pNode.getUUID());
 
         // set the versionable uuid
         pNode.setPropertyValue(QName.JCR_VERSIONABLEUUID, InternalValue.create(nodeState.getUUID()));
 
         // create label node
-        NodeStateEx lNode = pNode.addNode(QName.JCR_VERSIONLABELS, QName.NT_VERSIONLABELS, null, false);
-        created.add(lNode.getUUID());
+        pNode.addNode(QName.JCR_VERSIONLABELS, QName.NT_VERSIONLABELS, null, false);
 
         // create root version
         String versionId = UUID.randomUUID().toString();
 
         NodeStateEx vNode = pNode.addNode(QName.JCR_ROOTVERSION, QName.NT_VERSION, versionId, true);
-        created.add(vNode.getUUID());
 
         // initialize 'created' and 'predecessors'
         vNode.setPropertyValue(QName.JCR_CREATED, InternalValue.create(Calendar.getInstance()));
@@ -453,8 +489,7 @@
 
         // add also an empty frozen node to the root version
         NodeStateEx node = vNode.addNode(QName.JCR_FROZENNODE, QName.NT_FROZENNODE, null, true);
-        created.add(node.getUUID());
-        
+
         // initialize the internal properties
         node.setPropertyValue(QName.JCR_FROZENUUID, InternalValue.create(nodeState.getUUID()));
         node.setPropertyValue(QName.JCR_FROZENPRIMARYTYPE,

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionImpl.java Wed Jan 11 06:22:57 2006
@@ -31,7 +31,7 @@
 /**
  * Implements a <code>InternalVersion</code>
  */
-public class InternalVersionImpl extends InternalVersionItemImpl
+class InternalVersionImpl extends InternalVersionItemImpl
         implements InternalVersion {
 
     /**
@@ -126,7 +126,7 @@
             if (entry == null) {
                 throw new InternalError("version has no frozen node: " + getId());
             }
-            return (InternalFrozenNode) getVersionManager().getItem(entry.getUUID());
+            return (InternalFrozenNode) vMgr.getItem(entry.getUUID());
         } catch (RepositoryException e) {
             throw new IllegalStateException("unable to retrieve frozen node: " + e);
         }
@@ -210,6 +210,15 @@
     }
 
     /**
+     * Clear the list of predecessors/successors and the label cache.
+     */
+    void clear() {
+        successors.clear();
+        predecessors.clear();
+        labelCache = null;
+    }
+
+    /**
      * adds a successor version to the internal cache
      *
      * @param successor
@@ -250,9 +259,7 @@
         }
 
         // clear properties
-        successors.clear();
-        predecessors.clear();
-        labelCache = null;
+        clear();
     }
 
     /**
@@ -349,5 +356,12 @@
         } else {
             return (QName[]) labelCache.toArray(new QName[labelCache.size()]);
         }
+    }
+
+    /**
+     * Invalidate this item.
+     */
+    void invalidate() {
+        node.getState().discard();
     }
 }

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/InternalVersionItemImpl.java Wed Jan 11 06:22:57 2006
@@ -24,14 +24,14 @@
     /**
      * the version manager
      */
-    private final VersionManagerImpl vMgr;
+    protected final AbstractVersionManager vMgr;
 
     /**
      * Creates a new Internal version item impl
      *
      * @param vMgr
      */
-    protected InternalVersionItemImpl(VersionManagerImpl vMgr) {
+    protected InternalVersionItemImpl(AbstractVersionManager vMgr) {
         this.vMgr = vMgr;
     }
 
@@ -40,7 +40,7 @@
      *
      * @return
      */
-    protected VersionManagerImpl getVersionManager() {
+    protected AbstractVersionManager getVersionManager() {
         return vMgr;
     }
 

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java Wed Jan 11 06:22:57 2006
@@ -20,34 +20,14 @@
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.name.IllegalNameException;
-import org.apache.jackrabbit.name.NoPrefixDeclaredException;
-import org.apache.jackrabbit.name.QName;
-import org.apache.jackrabbit.name.UnknownPrefixException;
-import org.apache.log4j.Logger;
 
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.NodeIterator;
 import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
-import javax.jcr.version.VersionIterator;
 
 /**
  * This Class implements a version history that extends a node.
  */
-public class VersionHistoryImpl extends NodeImpl implements VersionHistory {
-
-    /**
-     * the default logger.
-     */
-    private static Logger log = Logger.getLogger(VersionHistoryImpl.class);
+public class VersionHistoryImpl extends AbstractVersionHistory {
 
     /**
      * the internal version history
@@ -74,250 +54,9 @@
     }
 
     /**
-     * @see VersionHistory#getRootVersion()
-     */
-    public Version getRootVersion() throws RepositoryException {
-        return (Version) session.getNodeByUUID(history.getRootVersion().getId());
-    }
-
-    /**
-     * @see VersionHistory#getAllVersions()
-     */
-    public VersionIterator getAllVersions() throws RepositoryException {
-        return new VersionIteratorImpl(session, history.getRootVersion());
-    }
-
-    /**
-     * @see VersionHistory#getVersion(String)
-     */
-    public Version getVersion(String versionName)
-            throws VersionException, RepositoryException {
-        try {
-            QName name = QName.fromJCRName(versionName, session.getNamespaceResolver());
-            InternalVersion v = history.getVersion(name);
-            if (v == null) {
-                throw new VersionException("No version with name '" + versionName + "' exists in this version history.");
-            }
-            return (Version) session.getNodeByUUID(v.getId());
-        } catch (IllegalNameException e) {
-            throw new VersionException(e);
-        } catch (UnknownPrefixException e) {
-            throw new VersionException(e);
-        }
-    }
-
-    /**
-     * @see VersionHistory#getVersionByLabel(String)
-     */
-    public Version getVersionByLabel(String label) throws RepositoryException {
-        try {
-            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
-            InternalVersion v = history.getVersionByLabel(qLabel);
-            if (v == null) {
-                throw new VersionException("No version with label '" + label + "' exists in this version history.");
-            }
-            return (Version) session.getNodeByUUID(v.getId());
-        } catch (IllegalNameException e) {
-            throw new VersionException(e);
-        } catch (UnknownPrefixException e) {
-            throw new VersionException(e);
-        }
-    }
-
-    /**
-     * @see VersionHistory#addVersionLabel(String, String, boolean)
-     */
-    public void addVersionLabel(String versionName, String label, boolean move)
-            throws VersionException, RepositoryException {
-        try {
-            session.getVersionManager().setVersionLabel(this,
-                    QName.fromJCRName(versionName, session.getNamespaceResolver()),
-                    QName.fromJCRName(label, session.getNamespaceResolver()),
-                    move);
-        } catch (IllegalNameException e) {
-            throw new VersionException(e);
-        } catch (UnknownPrefixException e) {
-            throw new VersionException(e);
-        }
-    }
-
-    /**
-     * @see VersionHistory#removeVersionLabel(String)
-     */
-    public void removeVersionLabel(String label) throws RepositoryException {
-        try {
-            Version existing = session.getVersionManager().setVersionLabel(this,
-                    null,
-                    QName.fromJCRName(label, session.getNamespaceResolver()),
-                    true);
-            if (existing == null) {
-                throw new VersionException("No version with label '" + label + "' exists in this version history.");
-            }
-        } catch (IllegalNameException e) {
-            throw new VersionException(e);
-        } catch (UnknownPrefixException e) {
-            throw new VersionException(e);
-        }
-    }
-
-
-    /**
-     * @see VersionHistory#getVersionLabels
-     */
-    public String[] getVersionLabels() {
-        try {
-            QName[] labels = history.getVersionLabels();
-            String[] ret = new String[labels.length];
-            for (int i = 0; i < labels.length; i++) {
-                ret[i] = labels[i].toJCRName(session.getNamespaceResolver());
-            }
-            return ret;
-        } catch (NoPrefixDeclaredException e) {
-            throw new IllegalArgumentException("Unable to resolve label name: " + e.toString());
-        }
-    }
-
-    /**
-     * @see VersionHistory#getVersionLabels(Version)
-     */
-    public String[] getVersionLabels(Version version)
-            throws VersionException, RepositoryException {
-        checkOwnVersion(version);
-        try {
-            QName[] labels = ((VersionImpl) version).getInternalVersion().getLabels();
-            String[] ret = new String[labels.length];
-            for (int i = 0; i < labels.length; i++) {
-                ret[i] = labels[i].toJCRName(session.getNamespaceResolver());
-            }
-            return ret;
-        } catch (NoPrefixDeclaredException e) {
-            throw new IllegalArgumentException("Unable to resolve label name: " + e.toString());
-        }
-    }
-
-    /**
-     * @see VersionHistory#hasVersionLabel(String)
-     */
-    public boolean hasVersionLabel(String label) {
-        try {
-            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
-            return history.getVersionByLabel(qLabel) != null;
-        } catch (IllegalNameException e) {
-            throw new IllegalArgumentException("Unable to resolve label: " + e);
-        } catch (UnknownPrefixException e) {
-            throw new IllegalArgumentException("Unable to resolve label: " + e);
-        }
-    }
-
-    /**
-     * @see VersionHistory#hasVersionLabel(Version, String)
+     * {@inheritDoc}
      */
-    public boolean hasVersionLabel(Version version, String label)
-            throws VersionException, RepositoryException {
-        checkOwnVersion(version);
-        try {
-            QName qLabel = QName.fromJCRName(label, session.getNamespaceResolver());
-            return ((VersionImpl) version).getInternalVersion().hasLabel(qLabel);
-        } catch (IllegalNameException e) {
-            throw new VersionException(e);
-        } catch (UnknownPrefixException e) {
-            throw new VersionException(e);
-        }
-    }
-
-    /**
-     * @see VersionHistory#removeVersion(String)
-     */
-    public void removeVersion(String versionName)
-            throws UnsupportedRepositoryOperationException, VersionException,
-            RepositoryException {
-        try {
-            session.getVersionManager().removeVersion(this,
-                    QName.fromJCRName(versionName, session.getNamespaceResolver()));
-        } catch (IllegalNameException e) {
-            throw new RepositoryException(e);
-        } catch (UnknownPrefixException e) {
-            throw new RepositoryException(e);
-        }
-    }
-
-    /**
-     * @see javax.jcr.Node#getUUID()
-     */
-    public String getUUID()
-            throws UnsupportedRepositoryOperationException, RepositoryException {
-        return history.getId();
-    }
-
-    /**
-     * @see javax.jcr.Item#isSame(javax.jcr.Item)
-     */
-    public boolean isSame(Item otherItem) {
-        if (otherItem instanceof VersionHistoryImpl) {
-            // since all version histories live in the same workspace, we can compare the uuids
-            return ((VersionHistoryImpl) otherItem).history.getId().equals(history.getId());
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the UUID of the node that was versioned.
-     *
-     * @return
-     */
-    public String getVersionableUUID() throws RepositoryException {
-        return history.getVersionableUUID();
-    }
-
-    /**
-     * Checks if the given version belongs to this history
-     *
-     * @param version
-     * @throws VersionException
-     * @throws RepositoryException
-     */
-    private void checkOwnVersion(Version version)
-            throws VersionException, RepositoryException {
-        if (!version.getParent().isSame(this)) {
-            throw new VersionException("Specified version not contained in this history.");
-        }
-    }
-
-    /**
-     * Returns the internal version history
-     *
-     * @return
-     */
-    public InternalVersionHistory getInternalVersionHistory() {
+    protected InternalVersionHistory getInternalVersionHistory() {
         return history;
-    }
-
-    //--------------------------------------< Overwrite "protected" methods >---
-
-
-    /**
-     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
-     * is protected.
-     *
-     * @throws javax.jcr.nodetype.ConstraintViolationException
-     */
-    public void update(String srcWorkspaceName) throws ConstraintViolationException {
-        String msg = "update operation not allowed on a version history node: " + safeGetJCRPath();
-        log.debug(msg);
-        throw new ConstraintViolationException(msg);
-    }
-
-    /**
-     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
-     * is protected.
-     *
-     * @throws javax.jcr.nodetype.ConstraintViolationException
-     */
-    public NodeIterator merge(String srcWorkspace, boolean bestEffort)
-            throws ConstraintViolationException {
-        String msg = "merge operation not allowed on a version history node: " + safeGetJCRPath();
-        log.debug(msg);
-        throw new ConstraintViolationException(msg);
     }
 }

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionImpl.java Wed Jan 11 06:22:57 2006
@@ -20,34 +20,20 @@
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.SessionImpl;
-import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.log4j.Logger;
 
-import javax.jcr.Item;
-import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.NodeIterator;
 import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.version.Version;
-import javax.jcr.version.VersionHistory;
-import java.util.Calendar;
 
 /**
  * This Class implements a Version that extends the node interface
  */
-public class VersionImpl extends NodeImpl implements Version {
-
-    /**
-     * the default logger.
-     */
-    private static Logger log = Logger.getLogger(VersionImpl.class);
+public class VersionImpl extends AbstractVersion {
 
     /**
      * the internal version
      */
-    protected final InternalVersion version;
+    private final InternalVersion version;
+
     /**
      * creates a new version node
      *
@@ -68,109 +54,11 @@
     }
 
     /**
-     * {@inheritDoc}
-     */
-    public Calendar getCreated() throws RepositoryException {
-        return version.getCreated();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Version[] getSuccessors() throws RepositoryException {
-        // need to wrap it around proper node
-        InternalVersion[] suc = version.getSuccessors();
-        Version[] ret = new Version[suc.length];
-        for (int i = 0; i < suc.length; i++) {
-            ret[i] = (Version) session.getNodeByUUID(suc[i].getId());
-        }
-        return ret;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Version[] getPredecessors() throws RepositoryException {
-        // need to wrap it around proper node
-        InternalVersion[] pred = version.getPredecessors();
-        Version[] ret = new Version[pred.length];
-        for (int i = 0; i < pred.length; i++) {
-            ret[i] = (Version) session.getNodeByUUID(pred[i].getId());
-        }
-        return ret;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException {
-        return version.getId();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public VersionHistory getContainingHistory() throws RepositoryException {
-        return (VersionHistory) getParent();
-    }
-
-    /**
      * Returns the internal version
      *
      * @return
      */
-    public InternalVersion getInternalVersion() {
+    protected InternalVersion getInternalVersion() {
         return version;
     }
-
-    /**
-     * Returns the frozen node of this version
-     *
-     * @return
-     * @throws RepositoryException
-     */
-    public InternalFrozenNode getFrozenNode() throws RepositoryException {
-        return version.getFrozenNode();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isSame(Item otherItem) {
-        if (otherItem instanceof VersionImpl) {
-            // since all versions live in the same workspace, we can compare the uuids
-            return ((VersionImpl) otherItem).version.getId().equals(version.getId());
-        } else {
-            return false;
-        }
-    }
-
-    //--------------------------------------< Overwrite "protected" methods >---
-
-
-    /**
-     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
-     * is protected.
-     *
-     * @throws javax.jcr.nodetype.ConstraintViolationException
-     */
-    public void update(String srcWorkspaceName) throws ConstraintViolationException {
-        String msg = "update operation not allowed on a version node: " + safeGetJCRPath();
-        log.debug(msg);
-        throw new ConstraintViolationException(msg);
-    }
-
-    /**
-     * Always throws a {@link javax.jcr.nodetype.ConstraintViolationException} since this node
-     * is protected.
-     *
-     * @throws javax.jcr.nodetype.ConstraintViolationException
-     */
-    public NodeIterator merge(String srcWorkspace, boolean bestEffort)
-            throws ConstraintViolationException {
-        String msg = "merge operation not allowed on a version node: " + safeGetJCRPath();
-        log.debug(msg);
-        throw new ConstraintViolationException(msg);
-    }
-
 }

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionItemStateProvider.java Wed Jan 11 06:22:57 2006
@@ -27,6 +27,7 @@
 import org.apache.jackrabbit.core.state.NodeReferencesId;
 import org.apache.jackrabbit.core.state.PropertyState;
 import org.apache.jackrabbit.core.state.SharedItemStateManager;
+import org.apache.jackrabbit.core.state.ItemStateListener;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
 import org.apache.jackrabbit.core.virtual.VirtualNodeState;
@@ -40,7 +41,7 @@
 /**
  * This Class implements a virtual item state provider.
  */
-public class VersionItemStateProvider implements VirtualItemStateProvider {
+class VersionItemStateProvider implements VirtualItemStateProvider, ItemStateListener {
 
     /**
      * the default logger

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionIteratorImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionIteratorImpl.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionIteratorImpl.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionIteratorImpl.java Wed Jan 11 06:22:57 2006
@@ -31,7 +31,7 @@
  * a version can be deleted while traversing this iterator and the 'nextVesion'
  * would produce a  ConcurrentModificationException.
  */
-public class VersionIteratorImpl implements VersionIterator {
+class VersionIteratorImpl implements VersionIterator {
 
     /**
      * the id's of the versions to return

Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java?rev=368026&r1=368025&r2=368026&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/version/VersionManager.java Wed Jan 11 06:22:57 2006
@@ -150,6 +150,4 @@
      * @throws Exception if an error occurs
      */
     void close() throws Exception;
-
-
 }