You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/05/20 12:25:06 UTC
svn commit: r658190 - in /incubator/sling/trunk:
launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/
servlets/post/src/main/java/org/apache/sling/servlets/post/
servlets/post/src/main/java/org/apache/sling/se...
Author: fmeschbe
Date: Tue May 20 03:25:05 2008
New Revision: 658190
URL: http://svn.apache.org/viewvc?rev=658190&view=rev
Log:
SLING-464 Add support for multiple resources to apply operations to and
adapt integration tests accordingly
Modified:
incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletDeleteTest.java
incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletMoveTest.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java (original)
+++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletCopyTest.java Tue May 20 03:25:05 2008
@@ -17,9 +17,15 @@
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.launchpad.webapp.integrationtest.HttpTestBase;
import org.apache.sling.launchpad.webapp.integrationtest.helpers.HttpStatusCodeException;
import org.apache.sling.servlets.post.SlingPostConstants;
@@ -35,41 +41,84 @@
}
public void testCopyNodeAbsolute() throws IOException {
- final String testPath = TEST_BASE_PATH + "/abs/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/abs/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
-
+
// assert content at new location
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
-
+
// assert content at old location
- content = getContent(HTTP_BASE_URL + testPath + "/src.json", CONTENT_TYPE_JSON);
+ content = getContent(HTTP_BASE_URL + testPath + "/src.json",
+ CONTENT_TYPE_JSON);
+ assertJavascript("Hello", content, "out.println(data.text)");
+ }
+
+ public void testCopyNodeAbsoluteBelowDest() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/abs/"
+ + System.currentTimeMillis();
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
+
+ // first test: failure because dest (parent) does not exist
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src",
+ HttpServletResponse.SC_PRECONDITION_FAILED, nvPairs,
+ "Expecting Copy Failure (dest must exist)");
+
+ // create dest as parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", null);
+
+ // copy now succeeds to below dest
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src",
+ HttpServletResponse.SC_CREATED, nvPairs, "Expecting Copy Success");
+
+ // assert content at new location
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.-1.json",
+ CONTENT_TYPE_JSON);
+ assertJavascript("Hello", content, "out.println(data.src.text)");
+
+ // assert content at old location
+ content = getContent(HTTP_BASE_URL + testPath + "/src.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
public void testCopyNodeRelative() throws IOException {
- final String testPath = TEST_BASE_PATH + "/rel/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/rel/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, "dest");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
public void testCopyNodeExistingFail() throws IOException {
- final String testPath = TEST_BASE_PATH + "/exist/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/exist/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
@@ -79,7 +128,8 @@
testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
try {
testClient.createNode(HTTP_BASE_URL + testPath, props);
@@ -91,12 +141,14 @@
}
// expect unmodified dest
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello Destination", content, "out.println(data.text)");
}
public void testCopyNodeExistingReplace() throws IOException {
- final String testPath = TEST_BASE_PATH + "/replace/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/replace/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
@@ -106,24 +158,28 @@
testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
props.put(SlingPostConstants.RP_REPLACE, "true");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
public void testCopyNodeDeepRelative() throws IOException {
- final String testPath = TEST_BASE_PATH + "/new/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/new/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, "deep/new");
-
+
try {
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
fail("Moving node to non existing parent location should fail.");
@@ -136,13 +192,15 @@
}
public void testCopyNodeDeepAbsolute() throws IOException {
- final String testPath = TEST_BASE_PATH + "/new_fail/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/new_fail/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_COPY);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY);
props.put(SlingPostConstants.RP_DEST, "/some/not/existing/structure");
try {
testClient.createNode(HTTP_BASE_URL + testPath + "/*", props);
@@ -156,4 +214,232 @@
}
}
- }
\ No newline at end of file
+ public void testCopyNodeMultipleSourceValid() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/cpmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src4", props);
+
+ // copy the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Copy Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Copy Success");
+
+ // assert existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_OK);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testCopyNodeMultipleSourceInValid() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/cpmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src4", props);
+
+ // copy the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot,
+ HttpServletResponse.SC_INTERNAL_SERVER_ERROR, nvPairs,
+ "Expecting Copy Failure (dest must have trailing slash)");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // retest after creating test
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Copy Failure (dest already exists)");
+
+ // assert non-existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testCopyNodeMultipleSourcePartial() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/cpmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+
+ // copy the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Copy Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Copy Success");
+
+ // assert partial existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testCopyNodeMultipleSourceReplace() throws Exception {
+ final String testPath = TEST_BASE_PATH + "/cpmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+
+ // copy the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Copy Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", null);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Copy Success");
+
+ // assert partial existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ // assert content test
+ String content = getContent(HTTP_BASE_URL + testPath
+ + "/dest/src1.json", CONTENT_TYPE_JSON);
+ JSONObject json = new JSONObject(content);
+ assertEquals("Hello", json.get("text"));
+
+ // modify src1 content
+ nvPairs.clear();
+ nvPairs.add(new NameValuePair("text", "Modified Hello"));
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src1",
+ HttpServletResponse.SC_OK, nvPairs, "Expect Content Update Success");
+
+ // copy the src? nodes
+ nvPairs.clear();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_COPY));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Copy Success");
+
+ // assert content test
+ String content2 = getContent(HTTP_BASE_URL + testPath
+ + "/dest/src1.json", CONTENT_TYPE_JSON);
+ JSONObject json2 = new JSONObject(content2);
+ assertEquals("Modified Hello", json2.get("text"));
+
+ // clean up
+ testClient.delete(testRoot);
+ }
+}
\ No newline at end of file
Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletDeleteTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletDeleteTest.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletDeleteTest.java (original)
+++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletDeleteTest.java Tue May 20 03:25:05 2008
@@ -45,13 +45,13 @@
final String urlB = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);
final String urlC = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);
final String urlD = testClient.createNode(postUrl + "/specific-location/for-delete", null);
-
+
// initially all nodes must be found
assertHttpStatus(urlA, HttpServletResponse.SC_OK, "A must initially exist");
assertHttpStatus(urlB, HttpServletResponse.SC_OK, "B must initially exist");
assertHttpStatus(urlC, HttpServletResponse.SC_OK, "C must initially exist");
assertHttpStatus(urlD, HttpServletResponse.SC_OK, "D must initially exist");
-
+
// delete one and check
final List <NameValuePair> params = new LinkedList<NameValuePair> ();
params.add(new NameValuePair(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_DELETE));
@@ -60,7 +60,7 @@
assertHttpStatus(urlB, HttpServletResponse.SC_OK, "B must still exist");
assertHttpStatus(urlC, HttpServletResponse.SC_OK, "C must still exist");
assertHttpStatus(urlD, HttpServletResponse.SC_OK, "D must still exist");
-
+
// delete the others with successive requests
assertPostStatus(urlB,HttpServletResponse.SC_OK,params,"Delete must return expected status (2)");
assertPostStatus(urlC,HttpServletResponse.SC_OK,params,"Delete must return expected status (2)");
@@ -69,8 +69,45 @@
assertHttpStatus(urlB, HttpServletResponse.SC_NOT_FOUND, "B must be deleted (2)");
assertHttpStatus(urlC, HttpServletResponse.SC_NOT_FOUND, "C must be deleted (2)");
assertHttpStatus(urlD, HttpServletResponse.SC_NOT_FOUND, "D must be deleted (2)");
-
+
// attempting to delete non-existing nodes is ok
assertPostStatus(postUrl,HttpServletResponse.SC_OK,params,"Delete must return expected status (2)");
}
+
+ public void testDeleteMultiple() throws IOException {
+ final String urlA = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);
+ final String urlB = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);
+ final String urlC = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, null);
+ final String urlD = testClient.createNode(postUrl + "/specific-location/for-delete", null);
+
+ // initially all nodes must be found
+ assertHttpStatus(urlA, HttpServletResponse.SC_OK, "A must initially exist");
+ assertHttpStatus(urlB, HttpServletResponse.SC_OK, "B must initially exist");
+ assertHttpStatus(urlC, HttpServletResponse.SC_OK, "C must initially exist");
+ assertHttpStatus(urlD, HttpServletResponse.SC_OK, "D must initially exist");
+
+ // delete one and check
+ final List <NameValuePair> params = new LinkedList<NameValuePair> ();
+ params.add(new NameValuePair(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_DELETE));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlA.substring(HTTP_BASE_URL.length())));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlB.substring(HTTP_BASE_URL.length())));
+ assertPostStatus(urlC,HttpServletResponse.SC_OK,params,"Delete must return expected status (3)");
+ assertHttpStatus(urlA, HttpServletResponse.SC_NOT_FOUND, "A must be deleted (1)");
+ assertHttpStatus(urlB, HttpServletResponse.SC_NOT_FOUND, "B must be deleted (1)");
+ assertHttpStatus(urlC, HttpServletResponse.SC_OK, "C must still exist");
+ assertHttpStatus(urlD, HttpServletResponse.SC_OK, "D must still exist");
+
+ // delete the others with successive requests
+ params.clear();
+ params.add(new NameValuePair(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_DELETE));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlA.substring(HTTP_BASE_URL.length())));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlB.substring(HTTP_BASE_URL.length())));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlC.substring(HTTP_BASE_URL.length())));
+ params.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, urlD.substring(HTTP_BASE_URL.length())));
+ assertPostStatus(urlC,HttpServletResponse.SC_OK,params,"Delete must return expected status (3)");
+ assertHttpStatus(urlA, HttpServletResponse.SC_NOT_FOUND, "A must be deleted (2)");
+ assertHttpStatus(urlB, HttpServletResponse.SC_NOT_FOUND, "B must be deleted (2)");
+ assertHttpStatus(urlC, HttpServletResponse.SC_NOT_FOUND, "C must be deleted (2)");
+ assertHttpStatus(urlD, HttpServletResponse.SC_NOT_FOUND, "D must be deleted (2)");
+ }
}
\ No newline at end of file
Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletMoveTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletMoveTest.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletMoveTest.java (original)
+++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/PostServletMoveTest.java Tue May 20 03:25:05 2008
@@ -17,11 +17,15 @@
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.launchpad.webapp.integrationtest.HttpTestBase;
import org.apache.sling.launchpad.webapp.integrationtest.helpers.HttpStatusCodeException;
import org.apache.sling.servlets.post.SlingPostConstants;
@@ -37,42 +41,83 @@
}
public void testMoveNodeAbsolute() throws IOException {
- final String testPath = TEST_BASE_PATH + "/abs/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/abs/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
-
+
// assert content at new location
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
-
+
// assert no content at old location
assertHttpStatus(HTTP_BASE_URL + testPath + "/src.json",
HttpServletResponse.SC_NOT_FOUND,
"Expected Not_Found for old content");
}
+ public void testMoveNodeAbsoluteBelowDest() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/abs/"
+ + System.currentTimeMillis();
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
+
+ // first test: failure because dest (parent) does not exist
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src",
+ HttpServletResponse.SC_PRECONDITION_FAILED, nvPairs,
+ "Expecting Move Failure (dest must exist)");
+
+ // create dest as parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", null);
+
+ // move now succeeds to below dest
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src",
+ HttpServletResponse.SC_CREATED, nvPairs, "Expecting Move Success");
+
+ // assert content at new location
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.-1.json",
+ CONTENT_TYPE_JSON);
+ assertJavascript("Hello", content, "out.println(data.src.text)");
+
+ // assert content at old location
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src.json",
+ HttpServletResponse.SC_NOT_FOUND);
+ }
+
public void testMoveNodeRelative() throws IOException {
- final String testPath = TEST_BASE_PATH + "/rel/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/rel/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, "dest");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
public void testMoveNodeExistingFail() throws IOException {
- final String testPath = TEST_BASE_PATH + "/exist/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/exist/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
@@ -82,7 +127,8 @@
testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
try {
testClient.createNode(HTTP_BASE_URL + testPath, props);
@@ -94,12 +140,14 @@
}
// expect unmodified dest
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello Destination", content, "out.println(data.text)");
}
public void testMoveNodeExistingReplace() throws IOException {
- final String testPath = TEST_BASE_PATH + "/replace/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/replace/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
@@ -109,24 +157,28 @@
testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, testPath + "/dest");
props.put(SlingPostConstants.RP_REPLACE, "true");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
- String content = getContent(HTTP_BASE_URL + testPath + "/dest.json", CONTENT_TYPE_JSON);
+ String content = getContent(HTTP_BASE_URL + testPath + "/dest.json",
+ CONTENT_TYPE_JSON);
assertJavascript("Hello", content, "out.println(data.text)");
}
public void testMoveNodeDeepRelative() throws IOException {
- final String testPath = TEST_BASE_PATH + "/new/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/new/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, "deep/new");
-
+
try {
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
fail("Moving node to non existing parent location should fail.");
@@ -139,13 +191,15 @@
}
public void testMoveNodeDeepAbsolute() throws IOException {
- final String testPath = TEST_BASE_PATH + "/new_fail/" + System.currentTimeMillis();
+ final String testPath = TEST_BASE_PATH + "/new_fail/"
+ + System.currentTimeMillis();
Map<String, String> props = new HashMap<String, String>();
props.put("text", "Hello");
testClient.createNode(HTTP_BASE_URL + testPath + "/src", props);
props.clear();
- props.put(SlingPostConstants.RP_OPERATION, SlingPostConstants.OPERATION_MOVE);
+ props.put(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE);
props.put(SlingPostConstants.RP_DEST, "/some/not/existing/structure");
try {
testClient.createNode(HTTP_BASE_URL + testPath + "/*", props);
@@ -159,4 +213,264 @@
}
}
- }
\ No newline at end of file
+ public void testMoveNodeMultipleSourceValid() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/mvmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src4", props);
+
+ // move the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Move Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Move Success");
+
+ // assert existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_OK);
+
+ // assert non-existence of src?
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src1.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src2.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src3.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src4.html",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testMoveNodeMultipleSourceInValid() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/mvmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src4", props);
+
+ // move the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot,
+ HttpServletResponse.SC_INTERNAL_SERVER_ERROR, nvPairs,
+ "Expecting Move Failure (dest must have trailing slash)");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // retest after creating test
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Move Failure (dest already exists)");
+
+ // assert non-existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ // assert non-existence of src?
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src1.html",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src2.html",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src3.html",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src4.html",
+ HttpServletResponse.SC_OK);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testMoveNodeMultipleSourcePartial() throws IOException {
+ final String testPath = TEST_BASE_PATH + "/mvmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src3", props);
+
+ // move the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src3"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src4"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Move Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", props);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Move Success");
+
+ // assert partial existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ // assert non-existence of src?
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src1.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src2.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src3.html",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/src4.html",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ testClient.delete(testRoot);
+ }
+
+ public void testMoveNodeMultipleSourceReplace() throws Exception {
+ final String testPath = TEST_BASE_PATH + "/mvmult/"
+ + System.currentTimeMillis();
+ final String testRoot = testClient.createNode(HTTP_BASE_URL + testPath,
+ null);
+
+ // create multiple source nodes
+ Map<String, String> props = new HashMap<String, String>();
+ props.put("text", "Hello");
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src1", props);
+ testClient.createNode(HTTP_BASE_URL + testPath + "/src2", props);
+
+ // move the src? nodes
+ List<NameValuePair> nvPairs = new ArrayList<NameValuePair>();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_PRECONDITION_FAILED,
+ nvPairs, "Expecting Move Failure: dest parent does not exist");
+
+ // create destination parent
+ testClient.createNode(HTTP_BASE_URL + testPath + "/dest", null);
+
+ // now dest exists, so we expect success
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Move Success");
+
+ // assert partial existence of the src?/text properties
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src1/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src2/text",
+ HttpServletResponse.SC_OK);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src3/text",
+ HttpServletResponse.SC_NOT_FOUND);
+ assertHttpStatus(HTTP_BASE_URL + testPath + "/dest/src4/text",
+ HttpServletResponse.SC_NOT_FOUND);
+
+ // assert content test
+ String content = getContent(HTTP_BASE_URL + testPath
+ + "/dest/src1.json", CONTENT_TYPE_JSON);
+ JSONObject json = new JSONObject(content);
+ assertEquals("Hello", json.get("text"));
+
+ // modify src1 content
+ nvPairs.clear();
+ nvPairs.add(new NameValuePair("text", "Modified Hello"));
+ assertPostStatus(HTTP_BASE_URL + testPath + "/src1",
+ HttpServletResponse.SC_CREATED, nvPairs,
+ "Expect Content Create Success");
+
+ // move the src? nodes
+ nvPairs.clear();
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_OPERATION,
+ SlingPostConstants.OPERATION_MOVE));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_DEST, testPath
+ + "/dest/"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src1"));
+ nvPairs.add(new NameValuePair(SlingPostConstants.RP_APPLY_TO, testPath
+ + "/src2"));
+ assertPostStatus(testRoot, HttpServletResponse.SC_OK, nvPairs,
+ "Expecting Move Success");
+
+ // assert content test
+ String content2 = getContent(HTTP_BASE_URL + testPath
+ + "/dest/src1.json", CONTENT_TYPE_JSON);
+ JSONObject json2 = new JSONObject(content2);
+ assertEquals("Modified Hello", json2.get("text"));
+
+ // clean up
+ testClient.delete(testRoot);
+ }
+
+}
\ No newline at end of file
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/AbstractSlingPostOperation.java Tue May 20 03:25:05 2008
@@ -17,6 +17,8 @@
package org.apache.sling.servlets.post;
import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
import javax.jcr.Item;
import javax.jcr.Node;
@@ -25,6 +27,8 @@
import javax.jcr.Session;
import org.apache.sling.api.SlingHttpServletRequest;
+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.api.wrappers.SlingRequestPaths;
@@ -110,6 +114,30 @@
HtmlResponse response) throws RepositoryException;
/**
+ * Returns an iterator on <code>Resource</code> instances addressed in the
+ * {@link SlingPostConstants#RP_APPLY_TO} request parameter. If the request
+ * parameter is not set, <code>null</code> is returned. If the parameter
+ * is set with valid resources an empty iterator is returned. Any resources
+ * addressed in the {@link SlingPostConstants#RP_APPLY_TO} parameter is
+ * ignored.
+ *
+ * @param request The <code>SlingHttpServletRequest</code> object used to
+ * get the {@link SlingPostConstants#RP_APPLY_TO} parameter.
+ * @return The iterator of resources listed in the parameter or
+ * <code>null</code> if the parameter is not set in the request.
+ */
+ protected Iterator<Resource> getApplyToResources(
+ SlingHttpServletRequest request) {
+
+ String[] applyTo = request.getParameterValues(SlingPostConstants.RP_APPLY_TO);
+ if (applyTo == null) {
+ return null;
+ }
+
+ return new ApplyToIterator(request, applyTo);
+ }
+
+ /**
* Returns an external form of the given path prepending the context path
* and appending a display extension.
*
@@ -282,4 +310,57 @@
}
}
+ private static class ApplyToIterator implements Iterator<Resource> {
+
+ private final ResourceResolver resolver;
+ private final Resource baseResource;
+ private final String[] paths;
+
+ private int pathIndex;
+
+ private Resource nextResource;
+
+ ApplyToIterator(SlingHttpServletRequest request, String[] paths) {
+ this.resolver = request.getResourceResolver();
+ this.baseResource = request.getResource();
+ this.paths = paths;
+ this.pathIndex = 0;
+
+ nextResource = seek();
+ }
+
+ public boolean hasNext() {
+ return nextResource != null;
+ }
+
+ public Resource next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ Resource result = nextResource;
+ nextResource = seek();
+
+ return result;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private Resource seek() {
+ while (pathIndex < paths.length) {
+ String path = paths[pathIndex];
+ pathIndex++;
+
+ Resource res = resolver.getResource(baseResource, path);
+ if (res != null) {
+ return res;
+ }
+ }
+
+ // no more elements in the array
+ return null;
+ }
+ }
}
\ No newline at end of file
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/SlingPostConstants.java Tue May 20 03:25:05 2008
@@ -62,6 +62,9 @@
* <p>
* The delete operation requires no further request parameters and just
* deletes the content addressed by the request.
+ * <p>
+ * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
+ * parameter are deleted instead of the request resource.
*/
public static final String OPERATION_DELETE = "delete";
@@ -74,6 +77,9 @@
* order of the destination node. Finally the {@link #RP_REPLACE} parameter
* may be set to indicate whether an existing item at the destination should
* be replaced or not.
+ * <p>
+ * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
+ * parameter are copied instead of the request resource.
*/
public static final String OPERATION_COPY = "copy";
@@ -86,12 +92,26 @@
* order of the destination node. Finally the {@link #RP_REPLACE} parameter
* may be set to indicate whether an existing item at the destination should
* be replaced or not.
+ * <p>
+ * If the {@link #RP_APPLY_TO} parameter is set the resources listed in that
+ * parameter are moved instead of the request resource.
*/
public static final String OPERATION_MOVE = "move";
/**
+ * Name of the request parameter used to indicate the resource to apply the
+ * operation to (value is ":applyTo").
+ * <p>
+ * This property is used by certain opertaions - namely
+ * {@link #OPERATION_COPY}, {@link #OPERATION_DELETE} and
+ * {@link #OPERATION_MOVE} - to apply the operation to multiple resources
+ * instead of the request resource.
+ */
+ public static final String RP_APPLY_TO = RP_PREFIX + "applyTo";
+
+ /**
* Name of the request parameter used to indicate the destination for the
- * copy and move operations (value is "dest"). This request parameter is
+ * copy and move operations (value is ":dest"). This request parameter is
* required by the copy and move operations.
*/
public static final String RP_DEST = RP_PREFIX + "dest";
@@ -99,7 +119,7 @@
/**
* Name of the request parameter indicating whether the destination for a
* copy or move operation is to be replaced if existing (value is
- * "replace"). Copy or move is only possible if the destination exists if
+ * ":replace"). Copy or move is only possible if the destination exists if
* the replace parameter is set to the case-insignificant value true.
*/
public static final String RP_REPLACE = RP_PREFIX + "replace";
@@ -254,7 +274,7 @@
* applying any new content (value is "@Delete").
*/
public static final String SUFFIX_DELETE = "@Delete";
-
+
/**
* Suffix indicating that the named item is to be set from an item whose
* absolute or relative path is given in the parameter's value (value is
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java Tue May 20 03:25:05 2008
@@ -16,6 +16,8 @@
*/
package org.apache.sling.servlets.post.impl.operations;
+import java.util.Iterator;
+
import javax.jcr.Item;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -43,40 +45,40 @@
Resource resource = request.getResource();
String source = resource.getPath();
- // ensure we have an item underlying the request's resource
- Item item = resource.adaptTo(Item.class);
- if (item == null) {
- throw new ResourceNotFoundException("Missing source " + resource
- + " for " + getOperationName());
- }
-
// ensure dest is not empty/null and is absolute
String dest = request.getParameter(SlingPostConstants.RP_DEST);
if (dest == null || dest.length() == 0) {
throw new IllegalArgumentException("Unable to process "
+ getOperationName() + ". Missing destination");
}
+
+ // register whether the path ends with a trailing slash
+ boolean trailingSlash = dest.endsWith("/");
+
+ // ensure destination is an absolute and normalized path
if (!dest.startsWith("/")) {
dest = ResourceUtil.getParent(source) + "/" + dest;
- dest = ResourceUtil.normalize(dest);
}
+ dest = ResourceUtil.normalize(dest);
- Session session = item.getSession();
+ // destination parent and name
+ String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);
// delete destination if already exists
- String dstParent = ResourceUtil.getParent(dest);
- if (session.itemExists(dest)) {
+ Session session = request.getResourceResolver().adaptTo(Session.class);
+ if (!trailingSlash && session.itemExists(dest)) {
+
final String replaceString = request.getParameter(SlingPostConstants.RP_REPLACE);
final boolean isReplace = "true".equalsIgnoreCase(replaceString);
- if (isReplace) {
- session.getItem(dest).remove();
- } else {
+ if (!isReplace) {
response.setStatus(HttpServletResponse.SC_PRECONDITION_FAILED,
"Cannot " + getOperationName() + " " + resource + " to "
+ dest + ": destination exists");
return;
}
+
} 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)) {
@@ -90,7 +92,43 @@
response.setCreateRequest(true);
}
- execute(response, session, source, dest);
+ Iterator<Resource> resources = getApplyToResources(request);
+ if (resources == null) {
+
+ // ensure we have an item underlying the request's resource
+ Item item = resource.adaptTo(Item.class);
+ if (item == null) {
+ throw new ResourceNotFoundException("Missing source "
+ + resource + " for " + getOperationName());
+ }
+
+ String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
+ execute(response, item, dstParent, dstName);
+
+ } else {
+
+ // multiple applyTo requires trailing slash on destination
+ if (!trailingSlash) {
+ throw new IllegalArgumentException(
+ "Applying "
+ + getOperationName()
+ + " to multiple resources requires a trailing slash on the destination");
+ }
+
+ // multiple copy will never return 201/CREATED
+ response.setCreateRequest(false);
+
+ while (resources.hasNext()) {
+ Resource applyTo = resources.next();
+ Item item = applyTo.adaptTo(Item.class);
+ if (item != null) {
+ execute(response, item, dstParent, null);
+ }
+ }
+
+ }
+
+ // finally apply the ordering parameter
orderNode(request, session.getItem(dest));
}
@@ -104,14 +142,15 @@
*
* @param response The <code>HtmlResponse</code> used to record success of
* the operation.
- * @param session The JCR <code>Session</code> used to execute the
- * operation.
- * @param source The absolute path of the source item act upon.
- * @param dest The absolute path of the target item.
+ * @param source The source item to act upon.
+ * @param destParent The absolute path of the parent of the target item.
+ * @param destName The name of the target item inside the
+ * <code>destParent</code>. If <code>null</code> the name of
+ * the <code>source</code> is used as the target item name.
* @throws RepositoryException May be thrown if an error occurrs executing
* the operation.
*/
- protected abstract void execute(HtmlResponse response, Session session,
- String source, String dest) throws RepositoryException;
+ protected abstract void execute(HtmlResponse response, Item source,
+ String destParent, String destName) throws RepositoryException;
}
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/CopyOperation.java Tue May 20 03:25:05 2008
@@ -16,6 +16,7 @@
*/
package org.apache.sling.servlets.post.impl.operations;
+import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
@@ -47,16 +48,41 @@
}
@Override
- protected void execute(HtmlResponse response, Session session,
- String source, String dest) throws RepositoryException {
- copy((Node) session.getItem(source),
- (Node) session.getItem(ResourceUtil.getParent(dest)),
- ResourceUtil.getName(dest));
- response.onCopied(source, dest);
+ protected void execute(HtmlResponse response, Item source,
+ String destParent, String destName) throws RepositoryException {
+
+ copy(source, (Node) source.getSession().getItem(destParent), destName);
+
+ String dest = destParent + "/" + destName;
+ response.onCopied(source.getPath(), dest);
log.debug("copy {} to {}", source, dest);
}
/**
+ * Copy the <code>src</code> item into the <code>dstParent</code> node.
+ * The name of the newly created item is set to <code>name</code>.
+ *
+ * @param src The item to copy to the new location
+ * @param dstParent The node into which the <code>src</code> node is to be
+ * copied
+ * @param name The name of the newly created item. If this is
+ * <code>null</code> the new item gets the same name as the
+ * <code>src</code> item.
+ * @throws RepositoryException May be thrown in case of any problem copying
+ * the content.
+ * @see #copy(Node, Node, String)
+ * @see #copy(Property, Node, String)
+ */
+ static void copy(Item src, Node dstParent, String name)
+ throws RepositoryException {
+ if (src.isNode()) {
+ copy((Node) src, dstParent, name);
+ } else {
+ copy((Property) src, dstParent, name);
+ }
+ }
+
+ /**
* Copy the <code>src</code> node into the <code>dstParent</code> node.
* The name of the newly created node is set to <code>name</code>.
* <p>
@@ -76,10 +102,16 @@
static void copy(Node src, Node dstParent, String name)
throws RepositoryException {
+ // ensure destination name
if (name == null) {
name = src.getName();
}
+ // ensure new node creation
+ if (dstParent.hasNode(name)) {
+ dstParent.getNode(name).remove();
+ }
+
// create new node
Node dst = dstParent.addNode(name, src.getPrimaryNodeType().getName());
for (NodeType mix : src.getMixinNodeTypes()) {
@@ -122,6 +154,11 @@
name = src.getName();
}
+ // ensure new property creation
+ if (dstParent.hasProperty(name)) {
+ dstParent.getProperty(name).remove();
+ }
+
if (src.getDefinition().isMultiple()) {
dstParent.setProperty(name, src.getValues());
} else {
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/DeleteOperation.java Tue May 20 03:25:05 2008
@@ -16,6 +16,8 @@
*/
package org.apache.sling.servlets.post.impl.operations;
+import java.util.Iterator;
+
import javax.jcr.Item;
import javax.jcr.RepositoryException;
@@ -36,14 +38,31 @@
protected void doRun(SlingHttpServletRequest request, HtmlResponse response)
throws RepositoryException {
- Resource resource = request.getResource();
- Item item = resource.adaptTo(Item.class);
- if (item == null) {
- throw new ResourceNotFoundException("Missing source " + resource
- + " for delete");
+ Iterator<Resource> res = getApplyToResources(request);
+ if (res == null) {
+
+ Resource resource = request.getResource();
+ Item item = resource.adaptTo(Item.class);
+ if (item == null) {
+ throw new ResourceNotFoundException("Missing source "
+ + resource + " for delete");
+ }
+
+ item.remove();
+ response.onDeleted(resource.getPath());
+
+ } else {
+
+ while (res.hasNext()) {
+ Resource resource = res.next();
+ Item item = resource.adaptTo(Item.class);
+ if (item != null) {
+ item.remove();
+ response.onDeleted(resource.getPath());
+ }
+ }
+
}
- item.remove();
- response.onDeleted(resource.getPath());
}
}
\ No newline at end of file
Modified: incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java?rev=658190&r1=658189&r2=658190&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java (original)
+++ incubator/sling/trunk/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/operations/MoveOperation.java Tue May 20 03:25:05 2008
@@ -16,6 +16,7 @@
*/
package org.apache.sling.servlets.post.impl.operations;
+import javax.jcr.Item;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -30,22 +31,29 @@
*/
public class MoveOperation extends AbstractCopyMoveOperation {
- /**
- * default log
- */
- private static final Logger log = LoggerFactory.getLogger(MoveOperation.class);
-
@Override
protected String getOperationName() {
return "move";
}
@Override
- protected void execute(HtmlResponse response, Session session,
- String source, String dest) throws RepositoryException {
+ protected void execute(HtmlResponse response, Item source,
+ String destParent, String destName) throws RepositoryException {
+
+ if (destName == null) {
+ destName = source.getName();
+ }
+
+ String sourcePath = source.getPath();
+ String destPath = destParent + "/" + destName;
+ Session session = source.getSession();
+
+ if (session.itemExists(destPath)) {
+ session.getItem(destPath).remove();
+ }
- session.move(source, dest);
- response.onMoved(source, dest);
- log.debug("moved {} to {}", source, dest);
+ session.move(sourcePath, destPath);
+ response.onMoved(sourcePath, destPath);
}
+
}