You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/03/03 11:06:56 UTC
svn commit: r633023 - in /incubator/sling/trunk:
launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/
sling/ujax/src/main/java/org/apache/sling/ujax/
Author: bdelacretaz
Date: Mon Mar 3 02:06:56 2008
New Revision: 633023
URL: http://svn.apache.org/viewvc?rev=633023&view=rev
Log:
SLING-280 - UjaxPostServlet supports first/last/before/after ordering of created nodes
Modified:
incubator/sling/trunk/launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/PostServletOrderTest.java
incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostProcessor.java
incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostServlet.java
Modified: incubator/sling/trunk/launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/PostServletOrderTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/PostServletOrderTest.java?rev=633023&r1=633022&r2=633023&view=diff
==============================================================================
--- incubator/sling/trunk/launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/PostServletOrderTest.java (original)
+++ incubator/sling/trunk/launchpad/launchpad-webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ujax/PostServletOrderTest.java Mon Mar 3 02:06:56 2008
@@ -20,75 +20,190 @@
import java.util.HashMap;
import java.util.Map;
-import javax.servlet.http.HttpServletResponse;
-
+import org.apache.sling.commons.json.JSONArray;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.launchpad.webapp.integrationtest.HttpTestBase;
-import org.apache.sling.ujax.UjaxPostServlet;
/** Test the order option for node creation via the MicrojaxPostServlet */
public class PostServletOrderTest extends HttpTestBase {
- public static final String TEST_BASE_PATH = "/ujax-tests";
- private String postUrl;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+
+ public static final String TEST_BASE_PATH = "/ujax-tests-order";
+
+ private static final String[] DEFAULT_ORDER = new String[]{"a","b","c","d"};
+
+ /*
+ does not work (yet) since rhino does not preserve order of
+ object elements.
+
+ private static final String TEST_SCRIPT =
+ "var s=''; " +
+ "for (var a in data) {" +
+ " var n = data[a];" +
+ " if (typeof(n) == 'object') s += a + ',';" +
+ "}" +
+ "out.println(s);";
+ */
+
+ /**
+ * Create nodes and check if they are in default order
+ */
+ public void testStandardOrder() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+ verifyOrder(postUrl, DEFAULT_ORDER);
}
- public void testPostPathIsUnique() throws IOException {
- assertHttpStatus(postUrl, HttpServletResponse.SC_NOT_FOUND,
- "Path must not exist before test: " + postUrl);
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="first" request
+ */
+ public void testOrderFirst() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","first");
+ testClient.createNode(postUrl + "/c", props);
+ verifyOrder(postUrl, new String[]{"c", "a", "b", "d"});
}
- /** Create several nodes without the order option, and check ordering */
- public void testStandardOrder() throws IOException {
- final String [] nodeUrl = new String[4];
- nodeUrl[0] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, null);
- nodeUrl[1] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, null);
- nodeUrl[2] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, null);
- nodeUrl[3] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, null);
-
- final String [] nodeName = new String[nodeUrl.length];
- for(int i = 0; i < nodeUrl.length; i++) {
- nodeName[i] = nodeUrl[i].substring(nodeUrl[i].lastIndexOf('/') + 1);
- }
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="last" request
+ */
+ public void testOrderLast() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
- // check that nodes appear in creation order in their parent's list of children
- final String json = getContent(postUrl + ".1.json", CONTENT_TYPE_JSON);
- for(int i = 0; i < nodeUrl.length - 1; i++) {
- final int posA = json.indexOf(nodeName[i]);
- final int posB = json.indexOf(nodeName[i + 1]);
- if(posB <= posA) {
- fail("Expected '" + nodeName[i] + "' to come before '" + nodeName[i + 1] + "' in JSON data '" + json + "'");
- }
- }
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","last");
+ testClient.createNode(postUrl + "/c", props);
+ verifyOrder(postUrl, new String[]{"a", "b", "d", "c"});
+ }
+
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="before" request
+ */
+ public void testOrderBefore() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","before b");
+ testClient.createNode(postUrl + "/c", props);
+ verifyOrder(postUrl, new String[]{"a", "c", "b", "d"});
+ }
+
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="after" request
+ */
+ public void testOrderAfter() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","after c");
+ testClient.createNode(postUrl + "/b", props);
+ verifyOrder(postUrl, new String[]{"a", "c", "b", "d"});
+ }
+
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="N" request, where new position is greater than old one.
+ */
+ public void testOrderIntToBack() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","2");
+ testClient.createNode(postUrl + "/a", props);
+ verifyOrder(postUrl, new String[]{"b", "c", "a", "d"});
}
- /** Create several nodes with the order option, and check ordering */
- public void testZeroOrder() throws IOException {
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="N" request, where new position is less than old one.
+ */
+ public void testOrderIntToFront() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","1");
+ testClient.createNode(postUrl + "/d", props);
+ verifyOrder(postUrl, new String[]{"a", "d", "b", "c"});
+ }
+
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="0" request
+ */
+ public void testOrderIntZero() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
final Map <String, String> props = new HashMap <String, String> ();
props.put("ujax:order","0");
-
- final String [] nodeUrl = new String[4];
- nodeUrl[0] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, props);
- nodeUrl[1] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, props);
- nodeUrl[2] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, props);
- nodeUrl[3] = testClient.createNode(postUrl + UjaxPostServlet.DEFAULT_CREATE_SUFFIX, props);
-
- final String [] nodeName = new String[nodeUrl.length];
- for(int i = 0; i < nodeUrl.length; i++) {
- nodeName[i] = nodeUrl[i].substring(nodeUrl[i].lastIndexOf('/') + 1);
+ testClient.createNode(postUrl + "/d", props);
+ verifyOrder(postUrl, new String[]{"d", "a", "b", "c"});
+ }
+
+ /**
+ * Create nodes and check if they are in correct order after a
+ * ujax:order="N" request, where new position is out of bounds
+ */
+ public void testOrderIntOOB() throws IOException {
+ final String postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
+ createNodes(postUrl, DEFAULT_ORDER);
+
+ final Map <String, String> props = new HashMap <String, String> ();
+ props.put("ujax:order","100");
+ testClient.createNode(postUrl + "/a", props);
+ verifyOrder(postUrl, new String[]{"b", "c", "d", "a"});
+ }
+
+ /**
+ * Create test nodes
+ */
+ private String[] createNodes(String parentUrl, String[] names)
+ throws IOException {
+ String[] urls = new String[names.length];
+ for (int i=0; i<names.length; i++) {
+ urls[i] = testClient.createNode(parentUrl + "/" + names[i], null);
}
+ return urls;
+ }
- // check that nodes appear in reverse creation order in their parent's list of children
- final String json = getContent(postUrl + ".1.json", CONTENT_TYPE_JSON);
- for(int i = 0; i < nodeUrl.length - 1; i++) {
- final int posA = json.indexOf(nodeName[i]);
- final int posB = json.indexOf(nodeName[i + 1]);
- if(posA <= posB) {
- fail("Expected '" + nodeName[i] + " to come after " + nodeName[i + 1] + " in JSON data '" + json + "'");
+ /**
+ * Verify node order
+ */
+ private void verifyOrder(String parentUrl, String[] names)
+ throws IOException {
+ // check that nodes appear in creation order in their parent's list of children
+ final String content = getContent(parentUrl + ".1.json", CONTENT_TYPE_JSON);
+ String expected = "";
+ for (String n: names) {
+ expected +=n + ",";
+ }
+ //assertJavascript(expected, content, TEST_SCRIPT);
+ try {
+ String actual = "";
+ JSONObject obj = new JSONObject(content);
+ JSONArray n = obj.names();
+ for (int i=0; i<n.length(); i++) {
+ String name = n.getString(i);
+ Object o = obj.get(name);
+ if (o instanceof JSONObject) {
+ actual += name + ",";
+ }
}
+ assertEquals(expected, actual);
+ } catch (JSONException e) {
+ throw new IOException(e.toString());
}
}
}
Modified: incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostProcessor.java?rev=633023&r1=633022&r2=633023&view=diff
==============================================================================
--- incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostProcessor.java (original)
+++ incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostProcessor.java Mon Mar 3 02:06:56 2008
@@ -16,11 +16,12 @@
*/
package org.apache.sling.ujax;
-import java.util.Map;
import java.util.LinkedHashMap;
+import java.util.Map;
import javax.jcr.NamespaceException;
import javax.jcr.Node;
+import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.ServletContext;
@@ -44,6 +45,11 @@
*/
private static final Logger log = LoggerFactory.getLogger(UjaxPostProcessor.class);
+ public static final String ORDER_FIRST = "first";
+ public static final String ORDER_BEFORE = "before ";
+ public static final String ORDER_AFTER = "after ";
+ public static final String ORDER_LAST = "last";
+
/**
* log that records the changes applied during the processing of the
* post request.
@@ -670,32 +676,91 @@
}
return savePrefix;
}
+
+ private void processOrder() throws RepositoryException {
+ final String orderCode = request.getParameter(UjaxPostServlet.RP_ORDER);
+ if (orderCode!=null) {
+ final Node n = deepGetOrCreateNode(currentPath);
+ orderNode(n, orderCode);
+ }
+ }
/**
- * If orderCode is ORDER_ZERO, move n so that it is the first child of its
- * parent
- * @throws RepositoryException if a repository error occurs
+ * Orders the given node according to the specified command.
+ *
+ * The following syntax is supported:
+ * <xmp>
+ * | first | before all child nodes
+ * | before A | before child node A
+ * | after A | after child node A
+ * | last | after all nodes
+ * | N | at a specific position, N being an integer
+ * </xmp>
+ *
+ * @param node node to order
+ * @param command spcifies the ordering type
+ * @throws RepositoryException if an error occurs
*/
- private void processOrder()
+ private void orderNode(Node node, String command)
throws RepositoryException {
- // process the "order" command if any
- final String orderCode = request.getParameter(UjaxPostServlet.RP_ORDER);
- if (orderCode!=null) {
- if (UjaxPostServlet.ORDER_ZERO.equals(orderCode)) {
- final Node n = deepGetOrCreateNode(currentPath);
- final Node parent = n.getParent();
- final String beforename=parent.getNodes().nextNode().getName();
- parent.orderBefore(n.getName(), beforename);
- if(log.isDebugEnabled()) {
- log.debug("Node {} moved to be first child of its parent, " +
- "due to orderCode=" + orderCode, n.getPath());
+ Node parent = node.getParent();
+ String next = null;
+ if (command.equals(ORDER_FIRST)) {
+ next = parent.getNodes().nextNode().getName();
+ } else if (command.equals(ORDER_LAST)) {
+ next = "";
+ } else if (command.startsWith(ORDER_BEFORE)) {
+ next = command.substring(ORDER_BEFORE.length());
+ } else if (command.startsWith(ORDER_AFTER)) {
+ String name = command.substring(ORDER_AFTER.length());
+ NodeIterator iter = parent.getNodes();
+ while (iter.hasNext()) {
+ Node n = iter.nextNode();
+ if (n.getName().equals(name)) {
+ if (iter.hasNext()) {
+ next = iter.nextNode().getName();
+ } else {
+ next = "";
+ }
}
- } else {
- if(log.isDebugEnabled()) {
- log.debug("orderCode '{}' invalid, ignored", orderCode);
+ }
+ } else {
+ // check for integer
+ try {
+ // 01234
+ // abcde move a -> 2 (above 3)
+ // bcade move a -> 1 (above 1)
+ // bacde
+ int newPos = Integer.parseInt(command);
+ next = "";
+ NodeIterator iter = parent.getNodes();
+ while (iter.hasNext() && newPos >= 0) {
+ Node n = iter.nextNode();
+ if (n.getName().equals(node.getName())) {
+ // if old node is found before index, need to
+ // inc index
+ newPos++;
+ }
+ if (newPos == 0) {
+ next = n.getName();
+ break;
+ }
+ newPos--;
}
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("provided node ordering command is invalid: " + command);
+ }
+ }
+ if (next != null) {
+ if (next.equals("")) {
+ next = null;
}
+ parent.orderBefore(node.getName(), next);
+ if(log.isDebugEnabled()) {
+ log.debug("Node {} moved '{}'", node.getPath(), command);
+ }
+ } else {
+ throw new IllegalArgumentException("provided node ordering command is invalid: " + command);
}
}
-
}
Modified: incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostServlet.java?rev=633023&r1=633022&r2=633023&view=diff
==============================================================================
--- incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostServlet.java (original)
+++ incubator/sling/trunk/sling/ujax/src/main/java/org/apache/sling/ujax/UjaxPostServlet.java Mon Mar 3 02:06:56 2008
@@ -119,11 +119,6 @@
public static final String RP_ORDER = RP_PREFIX + "order";
/**
- * Code value for RP_ORDER
- */
- public static final String ORDER_ZERO = "0";
-
- /**
* Optional request parameter: redirect to the specified URL after POST
*/
public static final String RP_REDIRECT_TO = RP_PREFIX + "redirect";