You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2006/09/20 18:14:31 UTC

svn commit: r448249 - in /jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav: ./ version/ version/report/

Author: angela
Date: Wed Sep 20 09:14:30 2006
New Revision: 448249

URL: http://svn.apache.org/viewvc?view=rev&rev=448249
Log:
- add AbstractLocatorFactory (preparation for JCR-417)
- missing DeltaV property definitions
- missing DeltaV features
- add constants for compliance classes

Added:
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java   (with props)
Modified:
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/DeltaVConstants.java
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionControlledResource.java
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionResource.java

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,387 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.util.Text;
+
+/**
+ * <code>AbstractLocatorFactory</code> is an implementation of the DavLocatorFactory
+ * interface that defines how a given uri is split to workspace path an
+ * resource path and how it's implementation of <code>DavResourceLocator</code>
+ * builds the href. In contrast, the conversion from repository path to
+ * resource path and vice versa is left to subclasses.
+ */
+public abstract class AbstractLocatorFactory implements DavLocatorFactory {
+
+    private static Logger log = LoggerFactory.getLogger(AbstractLocatorFactory.class);
+
+    private final String pathPrefix;
+
+    /**
+     * Create a new factory
+     *
+     * @param pathPrefix Prefix, that needs to be removed in order to retrieve
+     * the path of the repository item from a given <code>DavResourceLocator</code>.
+     */
+    public AbstractLocatorFactory(String pathPrefix) {
+        this.pathPrefix = pathPrefix;
+    }
+
+    //--------------------------------------------------< DavLocatorFactory >---
+    /**
+     * Create a new <code>DavResourceLocator</code>. Any leading prefix and
+     * path-prefix (as defined with the constructor) are removed from the
+     * given request handle. The same applies for trailing '/'. The remaining
+     * String is called the 'resource handle' and it's first segment is treated
+     * as workspace name. If resource handle (and therefore workspace name
+     * are missing, both values are set to <code>null</code>.<p/>
+     * Examples:
+     *
+     * <pre>
+     * http://www.foo.bar/ (path prefix missing)
+     * -> workspace path = null
+     * -> resource path  = null
+     * -> href           = http://www.foo.bar/pathPrefix/
+     *
+     * http://www.foo.bar/pathPrefix/
+     * -> workspace path = null
+     * -> resource path  = null
+     * -> href           = http://www.foo.bar/pathPrefix/
+     *
+     * http://www.foo.bar/pathPrefix/wspName
+     * -> workspace path = /wspName
+     * -> resource path  = /wspName
+     * -> href           = http://www.foo.bar/pathPrefix/wspName
+     *
+     * http://www.foo.bar/pathPrefix/wspName/anypath
+     * -> workspace path = /wspName
+     * -> resource path  = /wspName/anypath
+     * -> href           = http://www.foo.bar/pathPrefix/wspName/anypath
+     * </pre>
+     *
+     * NOTE: If the given href is an absolute uri it must start with the
+     * specified prefix.
+     *
+     * @param prefix
+     * @param href
+     * @return a new <code>DavResourceLocator</code>
+     * @throws IllegalArgumentException if the given href is <code>null</code>
+     */
+    public DavResourceLocator createResourceLocator(String prefix, String href) {
+        if (href == null) {
+            throw new IllegalArgumentException("Request handle must not be null.");
+        }
+
+        // build prefix string and remove all prefixes from the given href.
+        StringBuffer b = new StringBuffer("");
+        if (prefix != null && prefix.length() > 0) {
+            b.append(prefix);
+            if (href.startsWith(prefix)) {
+                href = href.substring(prefix.length());
+            }
+        }
+        if (pathPrefix != null && pathPrefix.length() > 0 && !prefix.endsWith(pathPrefix)) {
+            b.append(pathPrefix);
+            if (href.startsWith(pathPrefix)) {
+                href = href.substring(pathPrefix.length());
+            }
+        }
+
+        // remove trailing "/" that is present with collections
+        if (href.endsWith("/")) {
+            href = href.substring(0, href.length() - 1);
+        }
+
+        String resourcePath;
+        String workspacePath;
+
+        // an empty requestHandle (after removal of the "/") signifies a request
+        // to the root that does not represent a repository item.
+        if ("".equals(href)) {
+            resourcePath = null;
+            workspacePath = null;
+        } else {
+            resourcePath = Text.unescape(href);
+            // retrieve wspPath: look for the first slash ignoring the leading one
+            int pos = href.indexOf('/', 1);
+            if (pos == -1) {
+                // request to a 'workspace' resource
+                workspacePath = resourcePath;
+            } else {
+                // separate the workspace path from the resource path.
+                workspacePath = Text.unescape(href.substring(0, pos));
+            }
+        }
+
+        return new DavResourceLocatorImpl(b.toString(), workspacePath, resourcePath, this);
+    }
+
+    /**
+     * Create a new <code>DavResourceLocator</code> from the specified prefix,
+     * workspace path and resource path, whithout modifying the specified Strings.
+     * Note, that it is expected that the resource path starts with the
+     * given workspace path unless both values are <code>null</code>.
+     *
+     * @param prefix
+     * @param workspacePath path or the workspace containing this resource or
+     * <code>null</code>.
+     * @param resourcePath Path of the resource or <code>null</code>. Any non
+     * null value must start with the specified workspace path.
+     * @return a new <code>DavResourceLocator</code>
+     * @see DavLocatorFactory#createResourceLocator(String, String, String)
+     */
+    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String resourcePath) {
+        return createResourceLocator(prefix, workspacePath, resourcePath, true);
+    }
+
+    /**
+     * Create a new <code>DavResourceLocator</code> from the specified prefix,
+     * workspace path and resource path. If <code>isResourcePath</code> is set
+     * to <code>false</code>, the given 'resourcePath' is converted by calling
+     * {@link #getResourcePath(String, String)}. Otherwise the same restriction
+     * applies as for {@link #createResourceLocator(String, String, String)}.
+     *
+     * @param prefix
+     * @param workspacePath
+     * @param path
+     * @param isResourcePath
+     * @return
+     * @see DavLocatorFactory#createResourceLocator(String, String, String, boolean)
+     */
+    public DavResourceLocator createResourceLocator(String prefix, String workspacePath, String path, boolean isResourcePath) {
+        String resourcePath = (isResourcePath) ? path : getResourcePath(path, workspacePath);
+        return new DavResourceLocatorImpl(prefix, workspacePath, resourcePath, this);
+    }
+
+    //--------------------------------------------------------------------------
+    /**
+     * Subclasses must defined how the repository path is built from the given
+     * resource and workspace path.
+     *
+     * @param resourcePath
+     * @param wspPath
+     * @return
+     */
+    protected abstract String getRepositoryPath(String resourcePath, String wspPath);
+
+    /**
+     * Subclasses must defined how the resource path is built from the given
+     * repository and workspace path.
+     *
+     * @param repositoryPath
+     * @param wspPath
+     * @return
+     */
+    protected abstract String getResourcePath(String repositoryPath, String wspPath);
+
+    //--------------------------------------------------------< DavResource >---
+    /**
+     * Private inner class <code>DavResourceLocatorImpl</code> implementing
+     * the <code>DavResourceLocator</code> interface.
+     */
+    private class DavResourceLocatorImpl implements DavResourceLocator {
+
+        private final String prefix;
+        private final String workspacePath;
+        private final String resourcePath;
+        private final AbstractLocatorFactory factory;
+
+        private final String href;
+
+        /**
+         * Create a new <code>DavResourceLocatorImpl</code>.
+         *
+         * @param prefix
+         * @param workspacePath
+         * @param resourcePath
+         */
+        private DavResourceLocatorImpl(String prefix, String workspacePath, String resourcePath, AbstractLocatorFactory factory) {
+
+            this.prefix = prefix;
+            this.workspacePath = workspacePath;
+            this.resourcePath = resourcePath;
+            this.factory = factory;
+
+            StringBuffer buf = new StringBuffer(prefix);
+            // NOTE: no need to append the workspace path, since it is must
+            // be part of the resource path.
+            if (resourcePath != null && resourcePath.length() > 0) {
+                // check if condition is really met
+                if (!resourcePath.startsWith(workspacePath)) {
+                    throw new IllegalArgumentException("Resource path '" + resourcePath + "' does not start with workspace path '" + workspacePath + ".");
+                }
+                buf.append(Text.escapePath(resourcePath));
+            }
+            int length = buf.length();
+            if (length > 0 && buf.charAt(length - 1) != '/') {
+                buf.append("/");
+            }
+            href = buf.toString();
+        }
+
+        /**
+         * Return the prefix used to build the href String. This includes the initial
+         * hrefPrefix as well a the path prefix.
+         *
+         * @return prefix String used to build the href.
+         */
+        public String getPrefix() {
+            return prefix;
+        }
+
+        /**
+         * Returns the resource path which always starts with the workspace
+         * path, if a workspace resource exists. For the top most resource
+         * (request handle '/'), <code>null</code> is returned.
+         *
+         * @return resource path or <code>null</code>
+         * @see org.apache.jackrabbit.webdav.DavResourceLocator#getResourcePath()
+         */
+        public String getResourcePath() {
+            return resourcePath;
+        }
+
+        /**
+         * Return the workspace path or <code>null</code> if this locator object
+         * represents the '/' request handle.
+         *
+         * @return workspace path or <code>null</code>
+         * @see org.apache.jackrabbit.webdav.DavResourceLocator#getWorkspacePath()
+         */
+        public String getWorkspacePath() {
+            return workspacePath;
+        }
+
+        /**
+         * Return the workspace name or <code>null</code> if this locator object
+         * represents the '/' request handle, which does not contain a workspace
+         * path.
+         *
+         * @return workspace name or <code>null</code>
+         * @see org.apache.jackrabbit.webdav.DavResourceLocator#getWorkspaceName()
+         */
+        public String getWorkspaceName() {
+            if (workspacePath != null && workspacePath.length() > 0) {
+                return workspacePath.substring(1);
+            }
+            return null;
+        }
+
+        /**
+         * Returns true if the specified locator object refers to a resource within
+         * the same workspace.
+         *
+         * @param locator
+         * @return true if the workspace name obtained from the given locator
+         * refers to the same workspace as the workspace name of this locator.
+         * @see DavResourceLocator#isSameWorkspace(org.apache.jackrabbit.webdav.DavResourceLocator)
+         */
+        public boolean isSameWorkspace(DavResourceLocator locator) {
+            return (locator == null) ? false : isSameWorkspace(locator.getWorkspaceName());
+        }
+
+        /**
+         * Returns true if the specified string equals to this workspace name or
+         * if both names are null.
+         *
+         * @param workspaceName
+         * @return true if the workspace name is equal to this workspace name.
+         * @see DavResourceLocator#isSameWorkspace(String)
+         */
+        public boolean isSameWorkspace(String workspaceName) {
+            String thisWspName = getWorkspaceName();
+            return (thisWspName == null) ? workspaceName == null : thisWspName.equals(workspaceName);
+        }
+
+        /**
+         * Returns an 'href' consisting of prefix and resource path (which starts
+         * with the workspace path). It assures a trailing '/' in case the href
+         * is used for collection. Note, that the resource path is
+         * {@link Text#escapePath(String) escaped}.
+         *
+         * @param isCollection
+         * @return href String representing the text of the href element
+         * @see org.apache.jackrabbit.webdav.DavConstants#XML_HREF
+         * @see DavResourceLocator#getHref(boolean)
+         */
+        public String getHref(boolean isCollection) {
+            return (isCollection) ? href : href.substring(0, href.length() - 1);
+        }
+
+        /**
+         * Returns true if the 'workspacePath' field is <code>null</code>.
+         *
+         * @return true if the 'workspacePath' field is <code>null</code>.
+         * @see org.apache.jackrabbit.webdav.DavResourceLocator#isRootLocation()
+         */
+        public boolean isRootLocation() {
+            return getWorkspacePath() == null;
+        }
+
+        /**
+         * Return the factory that created this locator.
+         *
+         * @return factory
+         * @see org.apache.jackrabbit.webdav.DavResourceLocator#getFactory()
+         */
+        public DavLocatorFactory getFactory() {
+            return factory;
+        }
+
+        /**
+         * Uses {@link AbstractLocatorFactory#getRepositoryPath(String, String)}
+         * to build the repository path.
+         *
+         * @see DavResourceLocator#getRepositoryPath()
+         */
+        public String getRepositoryPath() {
+            return factory.getRepositoryPath(getResourcePath(), getWorkspacePath());
+        }
+
+        /**
+         * Computes the hash code from the href, that is built from the prefix,
+         * the workspace name and the resource path all of them representing
+         * final instance fields.
+         *
+         * @return the hash code
+         */
+        public int hashCode() {
+            return href.hashCode();
+        }
+
+        /**
+         * Returns true, if the given object is a <code>DavResourceLocatorImpl</code>
+         * with the same hash code.
+         *
+         * @param obj the object to compare to
+         * @return <code>true</code> if the 2 objects are equal;
+         *         <code>false</code> otherwise
+         */
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (obj instanceof DavResourceLocatorImpl) {
+                DavResourceLocatorImpl other = (DavResourceLocatorImpl) obj;
+                return hashCode() == other.hashCode();
+            }
+            return false;
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/AbstractLocatorFactory.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <code>DavCompliance</code> defines constants for the various compliance
+ * classes defined RFC 2518 and it's extensions.
+ */
+public final class DavCompliance {
+
+    private static Logger log = LoggerFactory.getLogger(DavCompliance.class);
+
+    // RFC 2518
+    public static final String _1_ = "1";
+    public static final String _2_ = "2";
+
+    // RFC 3253
+    public static final String ACTIVITY = "activity";
+    public static final String BASELINE = "baseline";
+    public static final String CHECKOUT_IN_PLACE = "checkout-in-place";
+    public static final String LABEL = "label";
+    public static final String MERGE = "merge";
+    public static final String UPDATE = "update";
+    public static final String VERSION_CONTROL = "version-control";
+    public static final String VERSION_CONTROLLED_COLLECTION = "version-controlled-collection";
+    public static final String VERSION_HISTORY = "version-history";
+    public static final String WORKING_RESOURCE = "working-resource";
+    public static final String WORKSPACE = "workspace";
+
+    // RFC 3648
+    public static final String ORDERED_COLLECTIONS = "ordered-collections";
+
+    // RFC 3744
+    public static final String ACCESS_CONTROLL = "access-control";
+
+    // no RFC
+    public static final String OBSERVATION = "observation";
+
+    public static String concatComplianceClasses(String[] complianceClasses) {
+        StringBuffer b = new StringBuffer();
+        for (int i = 0; i < complianceClasses.length; i++) {
+            if (i > 0) {
+                b.append(",");
+            }
+            b.append(complianceClasses[i]);
+        }
+        return b.toString();
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavCompliance.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.version;
+
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+
+/**
+ * An activity is a resource that selects a set of versions that are on a single
+ * "line of descent", where a line of descent is a sequence of versions connected
+ * by successor relationships. If an activity selects versions from multiple
+ * version histories, the versions selected in each version history must be on a
+ * single line of descent.
+ * <p/>
+ * RFC 3253 defines the following required live properties for an Activity
+ * resource.
+ * <ul>
+ * <li>{@link #ACTIVITY_VERSION_SET DAV:activity-version-set}</li>
+ * <li>{@link #ACTIVITY_CHECKOUT_SET DAV:activity-checkout-set}</li>
+ * <li>{@link #SUBACTIVITY_SET DAV:subactivity-set}</li>
+ * <li>{@link #CURRENT_WORKSPACE_SET DAV:current-workspace-set}</li>
+ * <li>all DeltaV-compliant resource properties}.</li>
+ * <li>Note, that the {@link org.apache.jackrabbit.webdav.DavConstants#PROPERTY_RESOURCETYPE DAV:resourcetype}
+ * property returned by an Activity resource must be
+ * {@link org.apache.jackrabbit.webdav.property.ResourceType#ACTIVITY DAV:activity}</li>
+ * </ul>
+ * <p/>
+ * The Activity resource must support all methods defined for a
+ * {@link DeltaVResource DeltaV-compliant resource}. Since no additional methods
+ * are required for an activity this interface mainly acts as marker.
+ * <p/>
+ * Please refer to <a href="http://www.ietf.org/rfc/rfc3253.txt">RFC 3253</a>
+ * Section 13 for a complete description of this resource type.
+ */
+public interface ActivityResource extends DeltaVResource {
+
+    /**
+     * The computed DAV:activity-version-set property identifies each version
+     * whose DAV:activity-set property identifies this activity. Multiple
+     * versions of a single version history can be selected by an activity's
+     * DAV:activity-version-set property, but all DAV:activity-version-set
+     * versions from a given version history must be on a single line of descent
+     * from the root version of that version history.<p/>
+     *
+     * Note that the DAV:activity-version-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName ACTIVITY_VERSION_SET = DavPropertyName.create("activity-version-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * The computed DAV:activity-checkout-set property identifies each
+     * checked-out resource whose DAV:activity-set identifies this activity.<p/>
+     *
+     * Note that the DAV:activity-checkout-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName ACTIVITY_CHECKOUT_SET = DavPropertyName.create("activity-checkout-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * The DAV:subactivity-set property identifies each activity that forms a
+     * part of the logical change being captured by this activity. An activity
+     * behaves as if its DAV:activity-version-set is extended by the
+     * DAV:activity-version-set of each activity identified in the
+     * DAV:subactivity-set. In particular, the versions in this extended set
+     * MUST be on a single line of descent, and when an activity selects a version
+     * for merging, the latest version in this extended set is the one that will
+     * be merged.<p/>
+     * A server MAY reject attempts to modify the DAV:subactivity-set of an activity.<p/>
+     *
+     * Note that the DAV:subactivity-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName SUBACTIVITY_SET = DavPropertyName.create("subactivity-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * The computed DAV:current-workspace-set property identifies identifies
+     * each workspace whose DAV:current-activity-set identifies this activity.<p/>
+     *
+     * Note that the DAV:current-workspace-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName CURRENT_WORKSPACE_SET = DavPropertyName.create("current-workspace-set", DeltaVConstants.NAMESPACE);
+
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/ActivityResource.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.version;
+
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+
+/**
+ * <code>BaselineResource</code> represents the 'version' of a configuration
+ * which is represented by a 'version-controlled-configuration' (VCC) resource.
+ * Such as new versions are created by CHECKIN of a version-controlled
+ * resource, a new baseline is created, whenever the VCC resource, that
+ * represents a set of resources rather than a single resource, is checked-in.
+ * <p/>
+ * Since the baseline behaves like a <code>VersionResource</code> and only is
+ * defined to provide additional protected properties, this interface only adds
+ * a convenience method that allows to retrieve the baseline collection.
+ * <p>
+ * Supported live properties:
+ * <pre>
+ * DAV:baseline-collection
+ * DAV:subbaseline-set
+ * all version properties.
+ * </pre>
+ *
+ * Supported methods:
+ * <pre>
+ * all version methods.
+ * </pre>
+ */
+public interface BaselineResource extends VersionResource {
+
+    /**
+     * The protected DAV:baseline-collection property identifies a distinct
+     * collection that lists as members all version-controlled resources of
+     * the configuration this baseline belongs to (the baseline being one
+     * version of the corresponding vc-configuration-resource). In other words:
+     * each member in the list must correspond to a member of the baseline-controlled
+     * collection at the time this baseline (version) was created.
+     * <p/>
+     *
+     * Note that the DAV:baseline-collection represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName BASELINE_COLLECTION = DavPropertyName.create("baseline-collection", DeltaVConstants.NAMESPACE);
+
+    /**
+     * The protected DAV:subbaseline-set property identifies a set of baseline
+     * resources. Note however, that the subbaselines of this resource are
+     * not only formed from the baseline resources listed in this property
+     * but also includes all subbaseline resources of the latter.
+     *
+     * Note that the DAV:subbaseline-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName SUBBASELINE_SET = DavPropertyName.create("subbaseline-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * Return the resource that represents the baseline-collection of this
+     * baseline, which is identified the href present in the {@link #BASELINE_COLLECTION}
+     * property.
+     *
+     * @return baseline collection
+     */
+    public DavResource getBaselineCollection() throws DavException;
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/BaselineResource.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/DeltaVConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/DeltaVConstants.java?view=diff&rev=448249&r1=448248&r2=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/DeltaVConstants.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/DeltaVConstants.java Wed Sep 20 09:14:30 2006
@@ -37,7 +37,13 @@
  * DAV:supported-method-set
  * DAV:supported-live-property-set
  * DAV:supported-report-set
- * DAV:workspace
+ * </pre>
+ *
+ * Some additional resource properties are defined by the various advanced
+ * version features:
+ * <pre>
+ * DAV:workspace (workspace feature)
+ * DAV:version-controlled-configuration (baseline)
  * </pre>
  */
 public interface DeltaVConstants {
@@ -133,10 +139,34 @@
 
     /**
      * Protected "workspace" property indicating the workspace of a resource.
+     * This property is required for all resources if (but only if) the workspace
+     * feature is supported.
+     * <p/>
+     * Note that the DAV:activity-version-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}.
+     * It is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT workspace (href)&gt;
+     * </pre>
      *
-     * @see #WORKSPACE
+     * @see WorkspaceResource
      */
     public static final DavPropertyName WORKSPACE = DavPropertyName.create("workspace", NAMESPACE);
+
+    /**
+     * The Baseline feature introduces the computed DAV:version-controlled-configuration
+     * property for all resources that are member of a version-controlled
+     * configuration. This may be the case if the resource is a collection under
+     * baseline control or is a member of a collection under baseline control.
+     * <p/>
+     * Note that the DAV:activity-version-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}.
+     * It is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT version-controlled-configuration (href)&gt;
+     * </pre>
+     */
+    public static final DavPropertyName VERSION_CONTROLLED_CONFIGURATION = DavPropertyName.create("version-controlled-configuration", NAMESPACE);
 
 
     //---< XML Element, Attribute Names >---------------------------------------

Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionControlledResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionControlledResource.java?view=diff&rev=448249&r1=448248&r2=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionControlledResource.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionControlledResource.java Wed Sep 20 09:14:30 2006
@@ -52,6 +52,21 @@
  * <li>DAV:unreserved (activity)</li>
  * <li>DAV:activity-set (activity)</li>
  * </ul>
+ *
+ * If the Version-Controlled-Collection feature is supported (see section 14
+ * of RFC 3253) the following computed property is required:
+ * <ul>
+ * <li>DAV:eclipsed-set</li>
+ * </ul>
+ *
+ * If the Baseline feature is supported (see section 12 of RFC 3253), a version-
+ * controlled resource may represent a 'configuration' rather than a single
+ * resource. In this case the RFC defines the following required properties:
+ * <ul>
+ * <li>DAV:baseline-controlled-collection</li>
+ * <li>DAV:subbaseline-set (if the configuration resource is checked-out)</li>
+ * </ul>
+ *
  * <p/>
  * In addition a version-controlled resource must support the following METHODS:
  * <ul>
@@ -192,6 +207,94 @@
      * @see #merge(MergeInfo)
      */
     public static final DavPropertyName AUTO_MERGE_SET = DavPropertyName.create("auto-merge-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * DAV:unreserved is a property for a checked-out resource, if the server
+     * supports the activity feature.<br>
+     * It indicates whether the DAV:activity-set of another checked-out resource
+     * associated with the version history of this version-controlled resource
+     * can have an activity that is in the DAV:activity-set property of this
+     * checked-out resource.
+     * <br>
+     * A result of the requirement that an activity must form a single line of
+     * descent through a given version history is that if multiple checked-out
+     * resources for a given version history are checked out unreserved into a
+     * single activity, only the first CHECKIN will succeed. Before another of
+     * these checked-out resources can be checked in, the user will first have
+     * to merge into that checked-out resource the latest version selected by
+     * that activity from that version history, and then modify the
+     * DAV:predecessor-set of that checked-out resource to identify that version.
+     * <p/>
+     * This property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT unreserved (#PCDATA)&gt;
+     * PCDATA value: boolean
+     * </pre>
+     * @see VersionResource#ACTIVITY_SET
+     */
+    public static final DavPropertyName UNRESERVED = DavPropertyName.create("activity-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * DAV:activity-set is a property for a checked-out resource, if the
+     * server supports the activity feature.<br>
+     * This property determines the DAV:activity-set property of the version that
+     * results from checking in this resource.
+     *
+     * @see VersionResource#ACTIVITY_SET
+     */
+    public static final DavPropertyName ACTIVITY_SET = DavPropertyName.create("activity-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * If the 'Version-Controlled-Collection Feature' is supported the
+     * DAV:eclipsed-set property present on a collection identifies all
+     * internal members that are not version-controlled and hide a vc internal
+     * member with the same name.
+     * <p/>
+     * This property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT eclipsed-set (binding-name*)&gt;
+     * &lt;!ELEMENT binding-name (#PCDATA)&gt;
+     * PCDATA value: URL segment
+     * </pre>
+     *
+     * @see VersionResource#VERSION_CONTROLLED_BINDING_SET
+     */
+    public static final DavPropertyName ECLIPSED_SET = DavPropertyName.create("eclipsed-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * If the 'Baseline' feature is supported, DAV:baseline-controlled-collection
+     * is a required property of any version-controlled resource, that represents
+     * a 'configuration'. It identifies the collection that contains the
+     * version-controlled resources whose versions are tracked by this
+     * configuration.<p/>
+     *
+     * This property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT baseline-controlled-collection (href)&gt;
+     * </pre>
+     * Note that the DAV:baseline-controlled-collection represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     *
+     * @see DeltaVConstants#VERSION_CONTROLLED_CONFIGURATION for the corresponding
+     * property, that is required for all resources that are contained in this
+     * version-controlled-configuration.
+     */
+    public static final DavPropertyName BASELINE_CONTROLLED_COLLECTION = DavPropertyName.create("baseline-controlled-collection", DeltaVConstants.NAMESPACE);
+
+    /**
+     * This property is mandatory for all checked-out version-controlled-configuration
+     * resources. It determines the DAV:subbaseline-set property of the baseline
+     * that results from checking in this resource.<p/>
+     *
+     * This property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT subbaseline-set (href*)&gt;
+     * </pre>
+     * Note that the DAV:baseline-controlled-collection represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     * @see BaselineResource#SUBBASELINE_SET
+     */
+    public static final DavPropertyName SUBBASELINE_SET = DavPropertyName.create("subbaseline-set", DeltaVConstants.NAMESPACE);
 
     /**
      * Perform a checkin on the version controlled resource.

Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionResource.java?view=diff&rev=448249&r1=448248&r2=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionResource.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/VersionResource.java Wed Sep 20 09:14:30 2006
@@ -40,6 +40,14 @@
  * <li>DAV:activity-set (activity)</li>
  * <li>all DeltaV-compliant resource properties.</li>
  * </ul>
+ *
+ * If the 'Version-Controlled-Collection Feature' is supported (see section 14
+ * of RFC 3253) the following protected property is defined for a version
+ * resource associated with a version-controlled collection.
+ * <ul>
+ * <li>DAV:version-controlled-binding-set</li>
+ * </ul>
+ *
  * <p/>
  * In addition a version resource must support the following METHODS:
  * <ul>
@@ -140,6 +148,43 @@
      * has a successor.
      */
     public static final DavPropertyName CHECKIN_FORK = DavPropertyName.create("checkin-fork", DeltaVConstants.NAMESPACE);
+
+    /**
+     * DAV:activity-set is a required property for a version resource, if the
+     * server supports the activity feature.<br>
+     * It identifies the activities that determine to which logical changes this
+     * version contributes, and on which lines of descent this version appears.
+     * A server MAY restrict the DAV:activity-set to identify a single activity.
+     * A server MAY refuse to allow the value of the DAV:activity-set property
+     * of a version to be modified.
+     * <p/>
+     * The property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT activity-set (href*)&gt;
+     * </pre>
+     * Note that the DAV:activity-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName ACTIVITY_SET = DavPropertyName.create("activity-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * If the 'Version-Controlled-Collection Feature' is supported the
+     * DAV:version-controlled-binding-set property identifies the name and the
+     * version history of all version-controlled internal members of the
+     * collection this version resource belongs to.
+     * <p/>
+     * This property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT version-controlled-binding-set (version-controlled-binding*)&gt;
+     * &lt;!ELEMENT version-controlled-binding (binding-name, version-history)&gt;
+     * &lt;!ELEMENT binding-name (#PCDATA)&gt;
+     * PCDATA value: URL segment
+     * &lt;!ELEMENT version-history (href)&gt;
+     * </pre>
+     *
+     * @see VersionControlledResource#ECLIPSED_SET
+     */
+    public static final DavPropertyName VERSION_CONTROLLED_BINDING_SET = DavPropertyName.create("version-controlled-binding-set", DeltaVConstants.NAMESPACE);
 
     /**
      * Modify the labels of this version resource. The modifications (SET, ADD or

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.version;
+
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+
+/**
+ * A workspace resource is a collection whose members are related
+ * version-controlled and non-version-controlled resources.
+ *
+ * <p/>
+ * RFC 3253 defines the following required live properties for an Workspace
+ * resource.
+ * <ul>
+ * <li>{@link #WORKSPACE_CHECKOUT_SET DAV:workspace-checkout-set}</li>
+ * <li>all DeltaV-compliant resource properties}</li>
+ * <li>DAV:baseline-controlled-collection-set (baseline)</li>
+ * <li>DAV:current-activity-set (activity)</li>
+ * </ul>
+ * Note, that RFC 3253 doesn't define a separate resource type for a workspace.<p/>
+ *
+ * The workspace resource must support all methods defined for a DeltaV-compliant
+ * collection. Since no additional methods are required for a workspace this
+ * interface mainly acts as marker.
+ * <p/>
+ * Please refer to <a href="http://www.ietf.org/rfc/rfc3253.txt">RFC 3253</a>
+ * Section 6 for a complete description of this resource type.
+ */
+public interface WorkspaceResource extends DeltaVResource {
+
+    /**
+     * The DAV:workspace-checkout-set property is the only required property
+     * which is additionally added to a workspace resource.<br>
+     * This computed property identifies each checked-out resource whose
+     * DAV:workspace property identifies this workspace.<p/>
+     *
+     * Note that the DAV:workspace-checkout-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}.
+     */
+    public static final DavPropertyName WORKSPACE_CHECKOUT_SET = DavPropertyName.create("workspace-checkout-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * DAV:current-activity-set is a required property for a workspace resource,
+     * if the server supports the activity feature.<br>
+     * It identifies the activities that currently are being performed in this
+     * workspace. When a member of this workspace is checked out, if no activity
+     * is specified in the checkout request, the DAV:current-activity-set will
+     * be used. This allows an activity-unaware client to update a workspace in
+     * which activity tracking is required. The DAV:current-activity-set MAY be
+     * restricted to identify at most one activity.
+     * <p/>
+     * The property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT current-activity-set (href*)&gt;
+     * </pre>
+     * Note that the DAV:current-activity-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName CUURENT_ACTIVITY_SET = DavPropertyName.create("current-activity-set", DeltaVConstants.NAMESPACE);
+
+    /**
+     * The Baseline feature (section 12) defines the following computed property
+     * for a workspace resource: DAV:baseline-controlled-collection-set lists
+     * all collections of this workspace, that are under baseline control. This
+     * list may include the workspace itself.
+     * <p/>
+     * The property is defined to have the following format:
+     * <pre>
+     * &lt;!ELEMENT baseline-controlled-collection-set (href*)&gt;
+     * </pre>
+     * Note that the DAV:baseline-controlled-collection-set represents a
+     * {@link org.apache.jackrabbit.webdav.property.HrefProperty HrefProperty}
+     */
+    public static final DavPropertyName BASELINE_CONTROLLED_COLLECTION_SET = DavPropertyName.create("baseline-controlled-collection-set", DeltaVConstants.NAMESPACE);
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/WorkspaceResource.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.version.report;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.DavResourceIterator;
+import org.apache.jackrabbit.webdav.property.HrefProperty;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.version.DeltaVConstants;
+import org.apache.jackrabbit.webdav.version.BaselineResource;
+import org.apache.jackrabbit.webdav.version.VersionResource;
+import org.apache.jackrabbit.webdav.version.VersionControlledResource;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * <code>CompareBaselineReport</code>...
+ */
+public class CompareBaselineReport implements Report {
+
+    private static Logger log = LoggerFactory.getLogger(CompareBaselineReport.class);
+
+    private static final String XML_COMPARE_BASELINE = "compare-baseline";
+    private static final String XML_COMPARE_BASELINE_REPORT = "compare-baseline-report";
+    private static final String XML_ADDED_VERSION = "added-version";
+    private static final String XML_DELETED_VERSION = "deleted-version";
+    private static final String XML_CHANGED_VERSION = "changed-version";
+
+    public static final ReportType COMPARE_BASELINE = ReportType.register(XML_COMPARE_BASELINE, DeltaVConstants.NAMESPACE, CompareBaselineReport.class);
+
+    private BaselineResource requestBaseline;
+    private BaselineResource compareBaseline;
+
+    /**
+     * Returns {@link #COMPARE_BASELINE}.
+     *
+     * @see Report#getType()
+     */
+    public ReportType getType() {
+        return COMPARE_BASELINE;
+    }
+
+    /**
+     * Always returns <code>false</code>.
+     *
+     * @return false
+     * @see Report#isMultiStatusReport()
+     */
+    public boolean isMultiStatusReport() {
+        return false;
+    }
+
+    /**
+     *
+     * @param resource
+     * @param info
+     * @throws DavException
+     * @see Report#init(DavResource, ReportInfo)
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        // validate info
+        if (!getType().isRequestedReportType(info)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:compare-baseline element expected.");
+        }
+
+        // make sure the report is applied to a vh-resource
+        if (resource != null && (resource instanceof BaselineResource)) {
+            this.requestBaseline = (BaselineResource) resource;
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:compare-baseline report can only be created for a baseline resource.");
+        }
+
+        // make sure the DAV:href element inside the request body points to
+        // an baseline resource (precondition for this report).
+        String compareHref = DomUtil.getText(info.getContentElement(DavConstants.XML_HREF, DavConstants.NAMESPACE));
+        DavResourceLocator locator = resource.getLocator();
+        DavResourceLocator compareLocator = locator.getFactory().createResourceLocator(locator.getPrefix(), compareHref);
+
+        DavResource compRes = resource.getFactory().createResource(compareLocator, resource.getSession());
+        if (compRes instanceof BaselineResource) {
+            compareBaseline = (BaselineResource) compRes;
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:latest-activity-version report: The DAV:href in the request body MUST identify an activity.");
+        }
+
+        // TODO: ev. add check for 'same-baseline-history' (RFC: "A server MAY require that the baselines being compared be from the same baseline history.")
+    }
+
+    /**
+     * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        Element el = DomUtil.createElement(document, XML_COMPARE_BASELINE_REPORT, DeltaVConstants.NAMESPACE);
+        try {
+            // TODO: check if correct
+            List requestVs = new ArrayList();
+            getVersions(requestBaseline.getBaselineCollection(), requestVs);
+
+            List compareVs = new ArrayList();
+            getVersions(compareBaseline.getBaselineCollection(), compareVs);
+
+            VersionResource[] rArr = (VersionResource[]) requestVs.toArray(new VersionResource[requestVs.size()]);
+            for (int i = 0; i < rArr.length; i++) {
+                VersionResource requestV = rArr[i];
+                if (!compareVs.remove(requestV)) {
+                    // check if another version of the same vh is present (change)
+                    VersionResource changedV = findChangedVersion(requestV, compareVs);
+                    if (changedV != null) {
+                        // found a 'changed-version' entry
+                        Element cv = DomUtil.addChildElement(el, XML_CHANGED_VERSION, DeltaVConstants.NAMESPACE);
+                        cv.appendChild(DomUtil.hrefToXml(requestV.getHref(), document));
+                        cv.appendChild(DomUtil.hrefToXml(changedV.getHref(), document));
+                    } else {
+                        // no corresponding version => 'deleted-version'
+                        Element cv = DomUtil.addChildElement(el, XML_DELETED_VERSION, DeltaVConstants.NAMESPACE);
+                        cv.appendChild(DomUtil.hrefToXml(requestV.getHref(), document));
+                    }
+
+                } // else: both baseline contain a vc-resource with the same checked-in version
+            }
+
+            // all remaining versions from the 'compare-baseline' can be considered
+            // to be added-versions.
+            Iterator it = compareVs.iterator();
+            while (it.hasNext()) {
+                VersionResource addedV = (VersionResource) it.next();
+                Element cv = DomUtil.addChildElement(el, XML_ADDED_VERSION, DeltaVConstants.NAMESPACE);
+                cv.appendChild(DomUtil.hrefToXml(addedV.getHref(), document));
+            }
+        } catch (DavException e) {
+            log.error("Internal error while building report", e);
+        }
+        return el;
+    }
+
+    private void getVersions(DavResource collection, List vList) throws DavException {
+        DavResourceIterator it = collection.getMembers();
+        while (it.hasNext()) {
+            DavResource member = it.nextResource();
+            if (member instanceof VersionControlledResource) {
+                String href = (String) new HrefProperty(member.getProperty(VersionControlledResource.CHECKED_IN)).getHrefs().get(0);
+                DavResourceLocator locator = member.getLocator();
+                DavResourceLocator vLocator = locator.getFactory().createResourceLocator(locator.getPrefix(), href);
+
+                DavResource v = member.getFactory().createResource(vLocator, member.getSession());
+                if (v instanceof VersionResource) {
+                    vList.add(v);
+                } else {
+                    log.error("Internal error: DAV:checked-in property must point to a VersionResource.");
+                }
+            }
+            if (member.isCollection()) {
+                getVersions(member, vList);
+            }
+        }
+    }
+
+    private VersionResource findChangedVersion(VersionResource requestV, List compareVs) throws DavException {
+        VersionResource[] vs = requestV.getVersionHistory().getVersions();
+        for (int i = 0; i < vs.length; i++) {
+            if (compareVs.remove(vs[i])) {
+                // another version of the same versionhistory is present among
+                // the compare-baseline versions.
+                return vs[i];
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/CompareBaselineReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java?view=auto&rev=448249
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java Wed Sep 20 09:14:30 2006
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.webdav.version.report;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.property.HrefProperty;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.version.VersionHistoryResource;
+import org.apache.jackrabbit.webdav.version.ActivityResource;
+import org.apache.jackrabbit.webdav.version.DeltaVConstants;
+import org.apache.jackrabbit.webdav.version.VersionResource;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.util.List;
+
+/**
+ * <code>LatestActivityVersionReport</code> is applied to a version history to
+ * identify the latest version that is selected from that version history by a
+ * given activity.
+ */
+public class LatestActivityVersionReport implements Report {
+
+    private static Logger log = LoggerFactory.getLogger(LatestActivityVersionReport.class);
+
+    private static final String XML_LATEST_ACTIVITY_VERSION = "latest-activity-version";
+    private static final String XML_LATEST_ACTIVITY_VERSION_REPORT = "latest-activity-version-report";
+
+    public static final ReportType LATEST_ACTIVITY_VERSION = ReportType.register(XML_LATEST_ACTIVITY_VERSION, DeltaVConstants.NAMESPACE, LatestActivityVersionReport.class);
+
+    private VersionHistoryResource vhResource;
+    private DavResource activity;
+
+    /**
+     * Returns {@link #LATEST_ACTIVITY_VERSION}.
+     *
+     * @see Report#getType()
+     */
+    public ReportType getType() {
+        return LATEST_ACTIVITY_VERSION;
+    }
+
+    /**
+     * Always returns <code>false</code>.
+     *
+     * @return false
+     * @see Report#isMultiStatusReport()
+     */
+    public boolean isMultiStatusReport() {
+        return false;
+    }
+
+    /**
+     * Check all the preconditions for this report.
+     *
+     * @throws DavException if a precondition is not met.
+     * @see Report#init(DavResource, ReportInfo)
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        // validate info
+        if (!getType().isRequestedReportType(info)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:latest-activity-version element expected.");
+        }
+
+        // make sure the report is applied to a vh-resource
+        if (resource != null && (resource instanceof VersionHistoryResource)) {
+            vhResource = (VersionHistoryResource) resource;
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:latest-activity-version report can only be created for a version history resource.");
+        }
+
+        // make sure the DAV:href element inside the request body points to
+        // an activity resource (precondition for this report).
+        String activityHref = DomUtil.getText(info.getContentElement(DavConstants.XML_HREF, DavConstants.NAMESPACE));
+        DavResourceLocator vhLocator = resource.getLocator();
+        DavResourceLocator activityLocator = vhLocator.getFactory().createResourceLocator(vhLocator.getPrefix(), activityHref);
+
+        activity = resource.getFactory().createResource(activityLocator, resource.getSession());
+        if (!(activity instanceof ActivityResource)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:latest-activity-version report: The DAV:href in the request body MUST identify an activity.");
+        }
+    }
+
+    /**
+     *
+     * @see org.apache.jackrabbit.webdav.xml.XmlSerializable#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        String latestVersionHref = getLatestVersionHref();
+
+        Element el = DomUtil.createElement(document, XML_LATEST_ACTIVITY_VERSION_REPORT, DeltaVConstants.NAMESPACE);
+        el.appendChild(DomUtil.hrefToXml(latestVersionHref, document));
+        return el;
+    }
+
+    /**
+     * The latest-version-href MUST identify the version of the given
+     * version history that is a member of the DAV:activity-version-set of the
+     * given activity and has no descendant that is a member of the
+     * DAV:activity-version-set of that activity.
+     *
+     * @return href of the latest version or ""
+     */
+    private String getLatestVersionHref() {
+        String latestVersionHref = ""; // not found (TODO: check if this valid according to the RFC)
+        try {
+            List versionHrefs = new HrefProperty(activity.getProperty(ActivityResource.ACTIVITY_VERSION_SET)).getHrefs();
+            VersionResource[] versions = vhResource.getVersions();
+
+            for (int i = 0; i < versions.length; i++) {
+                VersionResource vr = versions[i];
+                String href = vr.getHref();
+                if (versionHrefs.contains(href)) {
+                    if ("".equals(latestVersionHref)) {
+                        // shortcut
+                        latestVersionHref = href;
+                    } else {
+                        // if this vr is a decendant of the one already found, set latestVersion again
+                        List predecessors = new HrefProperty(vr.getProperty(VersionResource.PREDECESSOR_SET)).getHrefs();
+                        if (predecessors.contains(latestVersionHref)) {
+                            // version is a decendant of the vr identified by latestVersionHref
+                            latestVersionHref = href;
+                        } // else: version is predecessor -> nothing to do.
+                    }
+                }
+            }
+
+        } catch (DavException e) {
+            log.error("Unexpected error while retrieving href of latest version.", e);
+        }
+        return latestVersionHref;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/version/report/LatestActivityVersionReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url