incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jus...@apache.org
Subject svn commit: r959677 [1/2] - in /sling/trunk: bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/ bundles/servlets/post/src/main/java/org/apache/sling/servlets/post...
Date Thu, 01 Jul 2010 14:28:46 GMT
Author: justin
Date: Thu Jul  1 14:28:45 2010
New Revision: 959677

URL: http://svn.apache.org/viewvc?rev=959677&view=rev
Log:
SLING-1573 - adding versionable node support to post servlet

Added:
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
    sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletVersionableTest.java
Modified:
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/Modification.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
    sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
    sling/trunk/bundles/servlets/post/src/main/resources/OSGI-INF/metatype/metatype.properties

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java Thu Jul  1 14:28:45 2010
@@ -19,10 +19,13 @@ package org.apache.sling.servlets.post;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Set;
 
 import javax.jcr.Item;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
@@ -65,7 +68,9 @@ public abstract class AbstractSlingPostO
                     HtmlResponse response,
                     SlingPostProcessor[] processors) {
         Session session = request.getResourceResolver().adaptTo(Session.class);
-
+        
+        VersioningConfiguration versionableConfiguration = getVersioningConfiguration(request);
+        
         try {
             // calculate the paths
             String path = getItemPath(request);
@@ -90,6 +95,8 @@ public abstract class AbstractSlingPostO
                 processors[i].process(request, changes);
             }
 
+            Set<String> nodesToCheckin = new LinkedHashSet<String>();
+
             // set changes on html response
             for(Modification change : changes) {
                 switch ( change.getType() ) {
@@ -97,14 +104,36 @@ public abstract class AbstractSlingPostO
                     case DELETE : response.onDeleted(change.getSource()); break;
                     case MOVE :   response.onMoved(change.getSource(), change.getDestination()); break;
                     case COPY :   response.onCopied(change.getSource(), change.getDestination()); break;
-                    case CREATE : response.onCreated(change.getSource()); break;
+                    case CREATE :
+                        response.onCreated(change.getSource());
+                        if (versionableConfiguration.isCheckinOnNewVersionableNode()) {
+                            nodesToCheckin.add(change.getSource());
+                        }
+                        break;
                     case ORDER : response.onChange("ordered", change.getSource(), change.getDestination()); break;
+                    case CHECKOUT :
+                        response.onChange("checkout", change.getSource());
+                        nodesToCheckin.add(change.getSource());
+                        break;
+                    case CHECKIN :
+                        response.onChange("checkin", change.getSource());
+                        nodesToCheckin.remove(change.getSource());
+                        break;
                 }
             }
             if (session.hasPendingChanges()) {
                 session.save();
             }
 
+            if (!isSkipCheckin(request)) {
+                // now do the checkins
+                for(String checkinPath : nodesToCheckin) {
+                    if (checkin(session, checkinPath)) {
+                        response.onChange("checkin", checkinPath);
+                    }
+                }
+            }
+
         } catch (Exception e) {
 
             log.error("Exception during response processing.", e);
@@ -123,6 +152,16 @@ public abstract class AbstractSlingPostO
 
     }
 
+    protected VersioningConfiguration getVersioningConfiguration(SlingHttpServletRequest request) {
+        VersioningConfiguration versionableConfiguration =
+            (VersioningConfiguration) request.getAttribute(VersioningConfiguration.class.getName());
+        return versionableConfiguration != null ? versionableConfiguration : new VersioningConfiguration();
+    }
+
+    protected boolean isSkipCheckin(SlingHttpServletRequest request) {
+        return !getVersioningConfiguration(request).isAutoCheckin();
+    }
+
     /**
      * Remove the workspace name, if any, from the start of the path and validate that the
      * session's workspace name matches the path workspace name.
@@ -354,6 +393,47 @@ public abstract class AbstractSlingPostO
         }
     }
 
+    protected Node findVersionableAncestor(Node node) throws RepositoryException {
+        if (isVersionable(node)) {
+            return node;
+        } else {
+            try {
+                node = node.getParent();
+                return findVersionableAncestor(node);
+            } catch (ItemNotFoundException e) {
+                // top-level
+                return null;
+            }
+        }
+    }
+
+    protected boolean isVersionable(Node node) throws RepositoryException {
+        return node.isNodeType("mix:versionable");
+    }
+    
+    protected void checkoutIfNecessary(Node node, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration) throws RepositoryException {
+        if (versioningConfiguration.isAutoCheckout()) {
+            Node versionableNode = findVersionableAncestor(node);
+            if (versionableNode != null) {
+                if (!versionableNode.isCheckedOut()) {
+                    versionableNode.checkout();
+                    changes.add(Modification.onCheckout(versionableNode.getPath()));
+                }
+            }
+        }
+    }
+
+    private boolean checkin(Session session, String path) throws RepositoryException {
+        Node node = (Node) session.getItem(path);
+        if (node.isCheckedOut() && isVersionable(node)) {
+            node.checkin();
+            return true;
+        }
+
+        return false;
+    }
+
     private static class ApplyToIterator implements Iterator<Resource> {
 
         private final ResourceResolver resolver;

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/Modification.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/Modification.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/Modification.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/Modification.java Thu Jul  1 14:28:45 2010
@@ -118,6 +118,14 @@ public class Modification {
         return new Modification(type, source, dest);
     }
 
+    public static Modification onCheckin(String path) {
+        return onChange(ModificationType.CHECKIN, path, null);
+    }
+
+    public static Modification onCheckout(String path) {
+        return onChange(ModificationType.CHECKOUT, path, null);
+    }
+
     public String toString() {
         StringBuilder builder = new StringBuilder();
         builder.append("Modification[type=").append(type).append(", source=").append(source);

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/ModificationType.java Thu Jul  1 14:28:45 2010
@@ -58,5 +58,15 @@ public enum ModificationType {
      * the sibbling node before which the source Node has been ordered. which
      * the
      */
-    ORDER
+    ORDER,
+
+    /**
+     * A Node has been checked out. The source path provides the path of the node.
+     */
+    CHECKOUT,
+
+    /**
+     * A Node has been checked in. The source path provides the path of the node.
+     */
+    CHECKIN
 }

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java Thu Jul  1 14:28:45 2010
@@ -110,6 +110,28 @@ public interface SlingPostConstants {
     public static final String OPERATION_NOP = "nop";
 
     /**
+     * Name of the predefined checkin operation (value is "checkin").
+     * <p>
+     * The checkin operation requires no further request parameters and just
+     * checks in the content addressed by the request.
+     * <p>
+     * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
+     * parameter are checked in instead of the request resource.
+     */
+    public static final String OPERATION_CHECKIN = "checkin";
+
+    /**
+     * Name of the predefined checkout operation (value is "checkout").
+     * <p>
+     * The checkout operation requires no further request parameters and just
+     * checks out the content addressed by the request.
+     * <p>
+     * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
+     * parameter are checked out instead of the request resource.
+     */
+    public static final String OPERATION_CHECKOUT = "checkout";
+
+    /**
      * Name of the predefined import operation (value is "import").
      * 
      * <p>
@@ -119,8 +141,7 @@ public interface SlingPostConstants {
      * an existing item at the destination should be overwritten or not.
      */
     public static final String OPERATION_IMPORT = "import";
-    
-    
+
     /**
      * Name of the request parameter used to indicate the resource to apply the
      * operation to (value is ":applyTo").

Added: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java?rev=959677&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java (added)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/VersioningConfiguration.java Thu Jul  1 14:28:45 2010
@@ -0,0 +1,65 @@
+/*
+ * 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.sling.servlets.post;
+
+
+/**
+ * Data structure to hold the various options associated with how versionable
+ * nodes are handled in the post servlet.
+ */
+public class VersioningConfiguration implements Cloneable {
+    
+    private boolean autoCheckout = true;
+    
+    private boolean checkinOnNewVersionableNode = false;
+    
+    private boolean autoCheckin = true;
+
+    @Override
+    public VersioningConfiguration clone() {
+        VersioningConfiguration cfg = new VersioningConfiguration();
+        cfg.checkinOnNewVersionableNode = checkinOnNewVersionableNode;
+        cfg.autoCheckout = autoCheckout;
+        cfg.autoCheckin = autoCheckin;
+        return cfg;
+    }
+
+    public boolean isAutoCheckout() {
+        return autoCheckout;
+    }
+
+    public boolean isCheckinOnNewVersionableNode() {
+        return checkinOnNewVersionableNode;
+    }
+
+    public boolean isAutoCheckin() {
+        return autoCheckin;
+    }
+
+    public void setAutoCheckin(boolean autoCheckin) {
+        this.autoCheckin = autoCheckin;
+    }
+
+    public void setAutoCheckout(boolean autoCheckout) {
+        this.autoCheckout = autoCheckout;
+    }
+
+    public void setCheckinOnNewVersionableNode(boolean checkinOnNewVersionableNode) {
+        this.checkinOnNewVersionableNode = checkinOnNewVersionableNode;
+    }
+    
+}

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/SlingPostServlet.java Thu Jul  1 14:28:45 2010
@@ -38,10 +38,13 @@ import org.apache.sling.servlets.post.No
 import org.apache.sling.servlets.post.SlingPostConstants;
 import org.apache.sling.servlets.post.SlingPostOperation;
 import org.apache.sling.servlets.post.SlingPostProcessor;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 import org.apache.sling.servlets.post.impl.helper.DateParser;
 import org.apache.sling.servlets.post.impl.helper.DefaultNodeNameGenerator;
 import org.apache.sling.servlets.post.impl.helper.JSONResponse;
 import org.apache.sling.servlets.post.impl.helper.MediaRangeList;
+import org.apache.sling.servlets.post.impl.operations.CheckinOperation;
+import org.apache.sling.servlets.post.impl.operations.CheckoutOperation;
 import org.apache.sling.servlets.post.impl.operations.CopyOperation;
 import org.apache.sling.servlets.post.impl.operations.DeleteOperation;
 import org.apache.sling.servlets.post.impl.operations.ImportOperation;
@@ -119,6 +122,32 @@ public class SlingPostServlet extends Sl
     private static final String PROP_NODE_NAME_MAX_LENGTH = "servlet.post.nodeNameMaxLength";
 
     /**
+     * @scr.property valueRef="DEFAULT_CHECKIN_ON_CREATE" type="Boolean"
+     */
+    private static final String PROP_CHECKIN_ON_CREATE = "servlet.post.checkinNewVersionableNodes";
+
+    /**
+     * @scr.property valueRef="DEFAULT_AUTO_CHECKOUT" type="Boolean"
+     */
+    private static final String PROP_AUTO_CHECKOUT = "servlet.post.autoCheckout";
+    /**
+     * @scr.property valueRef="DEFAULT_AUTO_CHECKIN" type="Boolean"
+     */
+    private static final String PROP_AUTO_CHECKIN = "servlet.post.autoCheckin";
+    
+    private static final boolean DEFAULT_CHECKIN_ON_CREATE = false;
+    
+    private static final boolean DEFAULT_AUTO_CHECKOUT = true;
+    
+    private static final boolean DEFAULT_AUTO_CHECKIN = true;
+    
+    private static final String PARAM_CHECKIN_ON_CREATE = ":checkinNewVersionableNodes";
+
+    private static final String PARAM_AUTO_CHECKOUT = ":autoCheckout";
+
+    private static final String PARAM_AUTO_CHECKIN = ":autoCheckin";
+
+    /**
      * utility class for parsing date strings
      */
     private DateParser dateParser;
@@ -151,6 +180,8 @@ public class SlingPostServlet extends Sl
      * The content importer reference. 
      */
 	private ContentImporter contentImporter;
+
+    private VersioningConfiguration baseVersioningConfiguration;
     
     @Override
     public void init() {
@@ -167,12 +198,14 @@ public class SlingPostServlet extends Sl
         postOperations.put(SlingPostConstants.OPERATION_DELETE,
             new DeleteOperation());
         postOperations.put(SlingPostConstants.OPERATION_NOP, new NopOperation());
-        
+        postOperations.put(SlingPostConstants.OPERATION_CHECKIN, new CheckinOperation());
+        postOperations.put(SlingPostConstants.OPERATION_CHECKOUT, new CheckoutOperation());
+
         importOperation = new ImportOperation(defaultNodeNameGenerator, 
-        		contentImporter);
+            contentImporter);
         importOperation.setExtraNodeNameGenerators(cachedNodeNameGenerators);
         postOperations.put(SlingPostConstants.OPERATION_IMPORT,
-                importOperation);
+            importOperation);
     }
 
     @Override
@@ -184,6 +217,9 @@ public class SlingPostServlet extends Sl
     @Override
     protected void doPost(SlingHttpServletRequest request,
             SlingHttpServletResponse response) throws IOException {
+        VersioningConfiguration localVersioningConfig = createRequestVersioningConfiguration(request);
+        
+        request.setAttribute(VersioningConfiguration.class.getName(), localVersioningConfig);
 
         // prepare the response
         HtmlResponse htmlResponse = createHtmlResponse(request);
@@ -377,6 +413,8 @@ public class SlingPostServlet extends Sl
             }
             this.delayedNodeNameGenerators.clear();
         }
+        
+        this.baseVersioningConfiguration = createBaseVersioningConfiguration(props);
     }
 
     protected void deactivate(ComponentContext context) {
@@ -514,17 +552,45 @@ public class SlingPostServlet extends Sl
     }
     
     protected void bindContentImporter(ContentImporter importer) {
-    	this.contentImporter = importer;
-    	if (importOperation != null) {
-    		importOperation.setContentImporter(importer);
-    	}
+        this.contentImporter = importer;
+        if (importOperation != null) {
+            importOperation.setContentImporter(importer);
+        }
     }
 
     protected void unbindContentImporter(ContentImporter importer) {
-    	this.contentImporter = null;
-    	if (importOperation != null) {
-    		importOperation.setContentImporter(null);
-    	}
+        this.contentImporter = null;
+        if (importOperation != null) {
+            importOperation.setContentImporter(null);
+        }
     }
     
+    private VersioningConfiguration createBaseVersioningConfiguration(Dictionary<?, ?> props) {
+        VersioningConfiguration cfg = new VersioningConfiguration();
+        cfg.setCheckinOnNewVersionableNode(OsgiUtil.toBoolean(
+                props.get(PROP_CHECKIN_ON_CREATE), DEFAULT_CHECKIN_ON_CREATE));
+        cfg.setAutoCheckout(OsgiUtil.toBoolean(
+                props.get(PROP_AUTO_CHECKOUT), DEFAULT_AUTO_CHECKOUT));
+        cfg.setAutoCheckin(OsgiUtil.toBoolean(
+                props.get(PROP_AUTO_CHECKIN), DEFAULT_AUTO_CHECKIN));
+        return cfg;
+    }
+
+    private VersioningConfiguration createRequestVersioningConfiguration(SlingHttpServletRequest request) {
+        VersioningConfiguration cfg = baseVersioningConfiguration.clone();
+        
+        String paramValue = request.getParameter(PARAM_CHECKIN_ON_CREATE);
+        if (paramValue != null) {
+            cfg.setCheckinOnNewVersionableNode(Boolean.parseBoolean(paramValue));
+        }
+        paramValue = request.getParameter(PARAM_AUTO_CHECKOUT);
+        if (paramValue != null) {
+            cfg.setAutoCheckout(Boolean.parseBoolean(paramValue));
+        }
+        paramValue = request.getParameter(PARAM_AUTO_CHECKIN);
+        if (paramValue != null) {
+            cfg.setAutoCheckin(Boolean.parseBoolean(paramValue));
+        }
+        return cfg;
+    }
 }

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java Thu Jul  1 14:28:45 2010
@@ -20,6 +20,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import javax.jcr.Item;
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.servlet.http.HttpServletResponse;
@@ -31,6 +32,7 @@ import org.apache.sling.api.servlets.Htm
 import org.apache.sling.servlets.post.AbstractSlingPostOperation;
 import org.apache.sling.servlets.post.Modification;
 import org.apache.sling.servlets.post.SlingPostConstants;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 
 /**
  * The <code>AbstractCopyMoveOperation</code> is the abstract base close for
@@ -44,6 +46,7 @@ abstract class AbstractCopyMoveOperation
             HtmlResponse response,
             List<Modification> changes)
     throws RepositoryException {
+        VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
 
         Resource resource = request.getResource();
         String source = resource.getPath();
@@ -78,17 +81,23 @@ abstract class AbstractCopyMoveOperation
                     "Cannot " + getOperationName() + " " + resource + " to "
                         + dest + ": destination exists");
                 return;
+            } else {
+                checkoutIfNecessary(session.getItem(dest).getParent(), changes, versioningConfiguration);
             }
 
         } else {
 
             // check if path to destination exists and create it, but only
             // if it's a descendant of the current node
-            if (!dstParent.equals("") && !session.itemExists(dstParent)) {
-                response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
-                    "Cannot " + getOperationName() + " " + resource + " to "
-                        + dest + ": parent of destination does not exist");
-                return;
+            if (!dstParent.equals("")) {
+                if (session.itemExists(dstParent)) {
+                    checkoutIfNecessary((Node) session.getItem(dstParent), changes, versioningConfiguration);
+                } else {
+                    response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
+                        "Cannot " + getOperationName() + " " + resource + " to "
+                            + dest + ": parent of destination does not exist");
+                    return;
+                }
             }
 
             // the destination is newly created, hence a create request
@@ -108,7 +117,7 @@ abstract class AbstractCopyMoveOperation
             }
 
             String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
-            destItem = execute(changes, item, dstParent, dstName);
+            destItem = execute(changes, item, dstParent, dstName, versioningConfiguration);
 
         } else {
 
@@ -127,7 +136,7 @@ abstract class AbstractCopyMoveOperation
                 Resource applyTo = resources.next();
                 Item item = applyTo.adaptTo(Item.class);
                 if (item != null) {
-                    execute(changes, item, dstParent, null);
+                    execute(changes, item, dstParent, null, versioningConfiguration);
                 }
             }
             destItem = session.getItem(dest);
@@ -157,6 +166,7 @@ abstract class AbstractCopyMoveOperation
      *             the operation.
      */
     protected abstract Item execute(List<Modification> changes, Item source,
-            String destParent, String destName) throws RepositoryException;
+            String destParent, String destName,
+            VersioningConfiguration versioningConfiguration) throws RepositoryException;
 
 }

Added: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java?rev=959677&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java (added)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckinOperation.java Thu Jul  1 14:28:45 2010
@@ -0,0 +1,78 @@
+/*
+ * 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.sling.servlets.post.impl.operations;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.servlets.post.AbstractSlingPostOperation;
+import org.apache.sling.servlets.post.Modification;
+
+/**
+ * The <code>CheckinOperation</code> class implements the
+ * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_CHECKIN checkin}
+ * operation for the Sling default POST servlet.
+ */
+public class CheckinOperation extends AbstractSlingPostOperation {
+
+    @Override
+    protected void doRun(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes)
+            throws RepositoryException {
+        Iterator<Resource> res = getApplyToResources(request);
+        if (res == null) {
+
+            Resource resource = request.getResource();
+            Node node = resource.adaptTo(Node.class);
+            if (node == null) {
+                response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+                    "Missing source " + resource + " for checkout");
+                return;
+            }
+
+            node.checkin();
+            changes.add(Modification.onCheckin(resource.getPath()));
+
+        } else {
+
+            while (res.hasNext()) {
+                Resource resource = res.next();
+                Node node = resource.adaptTo(Node.class);
+                if (node != null) {
+                    node.checkin();
+                    changes.add(Modification.onCheckin(resource.getPath()));
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Checkin operation always checks in.
+     */
+    @Override
+    protected boolean isSkipCheckin(SlingHttpServletRequest request) {
+        return false;
+    }
+}

Added: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java?rev=959677&view=auto
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java (added)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CheckoutOperation.java Thu Jul  1 14:28:45 2010
@@ -0,0 +1,77 @@
+/*
+ * 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.sling.servlets.post.impl.operations;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.HtmlResponse;
+import org.apache.sling.servlets.post.AbstractSlingPostOperation;
+import org.apache.sling.servlets.post.Modification;
+
+/**
+ * The <code>CheckoutOperation</code> class implements the
+ * {@link org.apache.sling.servlets.post.SlingPostConstants#OPERATION_CHECKOUT checkout}
+ * operation for the Sling default POST servlet.
+ */
+public class CheckoutOperation extends AbstractSlingPostOperation {
+    @Override
+    protected void doRun(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes)
+            throws RepositoryException {
+        Iterator<Resource> res = getApplyToResources(request);
+        if (res == null) {
+
+            Resource resource = request.getResource();
+            Node node = resource.adaptTo(Node.class);
+            if (node == null) {
+                response.setStatus(HttpServletResponse.SC_NOT_FOUND,
+                    "Missing source " + resource + " for checkout");
+                return;
+            }
+
+            node.checkout();
+            changes.add(Modification.onCheckout(resource.getPath()));
+
+        } else {
+
+            while (res.hasNext()) {
+                Resource resource = res.next();
+                Node node = resource.adaptTo(Node.class);
+                if (node != null) {
+                    node.checkout();
+                    changes.add(Modification.onCheckout(resource.getPath()));
+                }
+            }
+
+        }
+
+    }
+
+    /**
+     * Checkout operation is always skipping checkin.
+     */
+    @Override
+    protected boolean isSkipCheckin(SlingHttpServletRequest request) {
+        return true;
+    }
+}

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java Thu Jul  1 14:28:45 2010
@@ -27,6 +27,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.NodeType;
 
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 
 /**
  * The <code>CopyOperation</code> class implements the
@@ -42,7 +43,8 @@ public class CopyOperation extends Abstr
 
     @Override
     protected Item execute(List<Modification> changes, Item source,
-            String destParent, String destName) throws RepositoryException {
+            String destParent, String destName,
+            VersioningConfiguration versioningConfiguration) throws RepositoryException {
 
         Item destItem = copy(source, (Node) source.getSession().getItem(destParent), destName);
 

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java Thu Jul  1 14:28:45 2010
@@ -28,6 +28,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.servlets.HtmlResponse;
 import org.apache.sling.servlets.post.AbstractSlingPostOperation;
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 
 /**
  * The <code>DeleteOperation</code> class implements the
@@ -39,6 +40,7 @@ public class DeleteOperation extends Abs
     @Override
     protected void doRun(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes)
     throws RepositoryException {
+        VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
 
         Iterator<Resource> res = getApplyToResources(request);
         if (res == null) {
@@ -50,6 +52,7 @@ public class DeleteOperation extends Abs
                     "Missing source " + resource + " for delete");
                 return;
             }
+            checkoutIfNecessary(item.getParent(), changes, versioningConfiguration);
 
             item.remove();
             changes.add(Modification.onDeleted(resource.getPath()));
@@ -60,6 +63,7 @@ public class DeleteOperation extends Abs
                 Resource resource = res.next();
                 Item item = resource.adaptTo(Item.class);
                 if (item != null) {
+                    checkoutIfNecessary(item.getParent(), changes, versioningConfiguration);
                     item.remove();
                     changes.add(Modification.onDeleted(resource.getPath()));
                 }

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/ModifyOperation.java Thu Jul  1 14:28:45 2010
@@ -31,6 +31,7 @@ import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
+import javax.jcr.version.VersionException;
 import javax.servlet.ServletContext;
 
 import org.apache.sling.api.SlingException;
@@ -38,12 +39,12 @@ import org.apache.sling.api.SlingHttpSer
 import org.apache.sling.api.request.RequestParameter;
 import org.apache.sling.api.resource.NonExistingResource;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.servlets.HtmlResponse;
 import org.apache.sling.servlets.post.AbstractSlingPostOperation;
 import org.apache.sling.servlets.post.Modification;
 import org.apache.sling.servlets.post.SlingPostConstants;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 import org.apache.sling.servlets.post.impl.helper.DateParser;
 import org.apache.sling.servlets.post.NodeNameGenerator;
 import org.apache.sling.servlets.post.impl.helper.ReferenceParser;
@@ -92,22 +93,24 @@ public class ModifyOperation extends Abs
 
         Map<String, RequestProperty> reqProperties = collectContent(request,
                 response);
+        
+        VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
 
         // do not change order unless you have a very good reason.
         Session session = request.getResourceResolver().adaptTo(Session.class);
 
         // ensure root of new content
-        processCreate(session, reqProperties, response, changes);
+        processCreate(session, reqProperties, response, changes, versioningConfiguration);
 
         // write content from existing content (@Move/CopyFrom parameters)
-        processMoves(session, reqProperties, changes);
-        processCopies(session, reqProperties, changes);
+        processMoves(session, reqProperties, changes, versioningConfiguration);
+        processCopies(session, reqProperties, changes, versioningConfiguration);
 
         // cleanup any old content (@Delete parameters)
-        processDeletes(session, reqProperties, changes);
+        processDeletes(session, reqProperties, changes, versioningConfiguration);
 
         // write content from form
-        writeContent(session, reqProperties, changes);
+        writeContent(session, reqProperties, changes, versioningConfiguration);
 
         // order content
         String path = response.getPath();
@@ -239,14 +242,15 @@ public class ModifyOperation extends Abs
      * @throws RepositoryException if a repository error occurs
      */
     private void processCreate(Session session,
-            Map<String, RequestProperty> reqProperties, HtmlResponse response, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, HtmlResponse response, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
 
         String path = response.getPath();
 
         if (!session.itemExists(path)) {
 
-            deepGetOrCreateNode(session, path, reqProperties, changes);
+            deepGetOrCreateNode(session, path, reqProperties, changes, versioningConfiguration);
             response.setCreateRequest(true);
 
         } else {
@@ -262,6 +266,8 @@ public class ModifyOperation extends Abs
 
                     // clear existing mixins first
                     Node node = (Node) item;
+                    checkoutIfNecessary(node, changes, versioningConfiguration);
+
                     for (NodeType mixin : node.getMixinNodeTypes()) {
                         String mixinName = mixin.getName();
                         if (!newMixins.remove(mixinName)) {
@@ -272,6 +278,12 @@ public class ModifyOperation extends Abs
                     // add new mixins
                     for (String mixin : newMixins) {
                         node.addMixin(mixin);
+                        // this is a bit of a cheat; there isn't a formal checkout, but assigning
+                        // the mix:versionable mixin does an implicit checkout
+                        if (mixin.equals("mix:versionable") &&
+                                versioningConfiguration.isCheckinOnNewVersionableNode()) {
+                            changes.add(Modification.onCheckout(path));
+                        }
                     }
                 }
             }
@@ -281,15 +293,17 @@ public class ModifyOperation extends Abs
     /**
      * Moves all repository content listed as repository move source in the
      * request properties to the locations indicated by the resource properties.
+     * @param checkedOutNodes
      */
     private void processMoves(Session session,
-            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
 
         for (RequestProperty property : reqProperties.values()) {
             if (property.hasRepositoryMoveSource()) {
                 processMovesCopiesInternal(property, true, session,
-                    reqProperties, changes);
+                    reqProperties, changes, versioningConfiguration);
             }
         }
     }
@@ -297,15 +311,17 @@ public class ModifyOperation extends Abs
     /**
      * Copies all repository content listed as repository copy source in the
      * request properties to the locations indicated by the resource properties.
+     * @param checkedOutNodes
      */
     private void processCopies(Session session,
-            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
 
         for (RequestProperty property : reqProperties.values()) {
             if (property.hasRepositoryCopySource()) {
                 processMovesCopiesInternal(property, false, session,
-                    reqProperties, changes);
+                    reqProperties, changes, versioningConfiguration);
             }
         }
     }
@@ -334,7 +350,8 @@ public class ModifyOperation extends Abs
      */
     private void processMovesCopiesInternal(RequestProperty property,
             boolean isMove, Session session,
-            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
 
         String propPath = property.getPath();
@@ -346,11 +363,15 @@ public class ModifyOperation extends Abs
             // if the destination item already exists, remove it
             // first, otherwise ensure the parent location
             if (session.itemExists(propPath)) {
+                Node parent = session.getItem(propPath).getParent();
+                checkoutIfNecessary(parent, changes, versioningConfiguration);
+                
                 session.getItem(propPath).remove();
                 changes.add(Modification.onDeleted(propPath));
             } else {
-                deepGetOrCreateNode(session, property.getParentPath(),
-                    reqProperties, changes);
+                Node parent = deepGetOrCreateNode(session, property.getParentPath(),
+                    reqProperties, changes, versioningConfiguration);
+                checkoutIfNecessary(parent, changes, versioningConfiguration);
             }
 
             // move through the session and record operation
@@ -359,10 +380,12 @@ public class ModifyOperation extends Abs
 
                 // node move/copy through session
                 if (isMove) {
+                    checkoutIfNecessary(sourceItem.getParent(), changes, versioningConfiguration);
                     session.move(source, propPath);
                 } else {
                     Node sourceNode = (Node) sourceItem;
                     Node destParent = (Node) session.getItem(property.getParentPath());
+                    checkoutIfNecessary(destParent, changes, versioningConfiguration);
                     CopyOperation.copy(sourceNode, destParent,
                         property.getName());
                 }
@@ -374,10 +397,12 @@ public class ModifyOperation extends Abs
 
                 // create destination property
                 Node destParent = (Node) session.getItem(property.getParentPath());
+                checkoutIfNecessary(destParent, changes, versioningConfiguration);
                 CopyOperation.copy(sourceProperty, destParent, null);
 
                 // remove source property (if not just copying)
                 if (isMove) {
+                    checkoutIfNecessary(sourceProperty.getParent(), changes, versioningConfiguration);
                     sourceProperty.remove();
                 }
             }
@@ -410,16 +435,19 @@ public class ModifyOperation extends Abs
      */
     private void processDeletes(Session session,
             Map<String, RequestProperty> reqProperties,
-            List<Modification> changes) throws RepositoryException {
+            List<Modification> changes,
+            VersioningConfiguration versioningConfiguration) throws RepositoryException {
 
         for (RequestProperty property : reqProperties.values()) {
 
             if (property.isDelete() && session.itemExists(property.getPath())) {
+                Node parent = (Node) session.getItem(property.getParentPath());
+
+                checkoutIfNecessary(parent, changes, versioningConfiguration);
 
                 if (property.getName().equals("jcr:mixinTypes")) {
 
                     // clear all mixins
-                    Node parent = (Node) session.getItem(property.getParentPath());
                     for (NodeType mixin : parent.getMixinNodeTypes()) {
                         parent.removeMixin(mixin.getName());
                     }
@@ -443,7 +471,8 @@ public class ModifyOperation extends Abs
      * @throws ServletException if an internal error occurs
      */
     private void writeContent(Session session,
-            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
 
         SlingPropertyValueHandler propHandler = new SlingPropertyValueHandler(
@@ -452,7 +481,10 @@ public class ModifyOperation extends Abs
         for (RequestProperty prop : reqProperties.values()) {
             if (prop.hasValues()) {
                 Node parent = deepGetOrCreateNode(session,
-                    prop.getParentPath(), reqProperties, changes);
+                    prop.getParentPath(), reqProperties, changes, versioningConfiguration);
+
+                checkoutIfNecessary(parent, changes, versioningConfiguration); 
+                
                 // skip jcr special properties
                 if (prop.getName().equals("jcr:primaryType")
                     || prop.getName().equals("jcr:mixinTypes")) {
@@ -715,13 +747,15 @@ public class ModifyOperation extends Abs
      * the path is empty, the given parent node is returned.
      *
      * @param path path to node that needs to be deep-created
+     * @param checkedOutNodes
      * @return node at path
      * @throws RepositoryException if an error occurs
      * @throws IllegalArgumentException if the path is relative and parent is
      *             <code>null</code>
      */
     private Node deepGetOrCreateNode(Session session, String path,
-            Map<String, RequestProperty> reqProperties, List<Modification> changes)
+            Map<String, RequestProperty> reqProperties, List<Modification> changes,
+            VersioningConfiguration versioningConfiguration)
             throws RepositoryException {
         if (log.isDebugEnabled()) {
             log.debug("Deep-creating Node '{}'", path);
@@ -768,10 +802,18 @@ public class ModifyOperation extends Abs
                 final String tmpPath = to < 0 ? path : path.substring(0, to);
                 // check for node type
                 final String nodeType = getPrimaryType(reqProperties, tmpPath);
-                if (nodeType != null) {
-                    node = node.addNode(name, nodeType);
-                } else {
-                    node = node.addNode(name);
+                checkoutIfNecessary(node, changes, versioningConfiguration);
+
+                try {
+                    if (nodeType != null) {
+                        node = node.addNode(name, nodeType);
+                    } else {
+                        node = node.addNode(name);
+
+                    }
+                } catch (VersionException e) {
+                    log.error("Unable to create node named " + name + " in "+node.getPath());
+                    throw e;
                 }
                 // check for mixin types
                 final String[] mixinTypes = getMixinTypes(reqProperties,

Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java Thu Jul  1 14:28:45 2010
@@ -23,6 +23,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
 import org.apache.sling.servlets.post.Modification;
+import org.apache.sling.servlets.post.VersioningConfiguration;
 
 /**
  * The <code>MoveOperation</code> class implements the
@@ -38,7 +39,8 @@ public class MoveOperation extends Abstr
 
     @Override
     protected Item execute(List<Modification> changes, Item source,
-            String destParent, String destName) throws RepositoryException {
+            String destParent, String destName,
+            VersioningConfiguration versioningConfiguration) throws RepositoryException {
 
         if (destName == null) {
             destName = source.getName();
@@ -50,11 +52,13 @@ public class MoveOperation extends Abstr
         }
         String destPath = destParent + "/" + destName;
         Session session = source.getSession();
+        
+        checkoutIfNecessary(source.getParent(), changes, versioningConfiguration);
 
         if (session.itemExists(destPath)) {
             session.getItem(destPath).remove();
         }
-
+        
         session.move(sourcePath, destPath);
         changes.add(Modification.onMoved(sourcePath, destPath));
         return session.getItem(destPath);

Modified: sling/trunk/bundles/servlets/post/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=959677&r1=959676&r2=959677&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ sling/trunk/bundles/servlets/post/src/main/resources/OSGI-INF/metatype/metatype.properties Thu Jul  1 14:28:45 2010
@@ -48,3 +48,13 @@ servlet.post.nodeNameMaxLength.descripti
  use for automatically generated node names. The default value is 20. Note, \
  that actual node names may be generated with at most 4 more characters if the \
  numeric suffixes must be appended to make the name unique.
+servlet.post.checkinNewVersionableNodes.name = Checkin New Versionable Nodes
+servlet.post.checkinNewVersionableNodes.description = If true, newly created \
+ versionable nodes or non-versionable nodes which are made versionable by the \
+ addition of the mix:versionable mixin are checked in. By default, false.
+servlet.post.autoCheckout.name = Auto Checkout Nodes
+servlet.post.autoCheckout.description = If true, checked in nodes are \
+ checked out when necessary. By default, true.
+servlet.post.autoCheckin.name = Auto Checkin Nodes
+servlet.post.autoCheckin.description = If true, nodes which are checked out \
+ by the post servlet are checked in. By default, true.
\ No newline at end of file



Mime
View raw message