jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r740749 [2/2] - in /jackrabbit/trunk/jackrabbit-jcr-server/src: main/java/org/apache/jackrabbit/server/remoting/ main/java/org/apache/jackrabbit/server/remoting/davex/ main/java/org/apache/jackrabbit/server/util/ test/java/org/apache/jackra...
Date Wed, 04 Feb 2009 14:13:25 GMT
Added: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java?rev=740749&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
(added)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
Wed Feb  4 14:13:24 2009
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.server.util;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <code>HttpMultipartPost</code>...
+ */
+class HttpMultipartPost {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(HttpMultipartPost.class);
+
+    private final Map nameToItems = new LinkedHashMap();
+    private final Set fileParamNames = new HashSet();
+
+    private boolean initialized;
+
+    HttpMultipartPost(HttpServletRequest request, File tmpDir) throws IOException {
+        extractMultipart(request, tmpDir);
+        initialized = true;
+    }
+
+    /**
+     *
+     * @param tmpDir
+     * @return
+     */
+    private static FileItemFactory getFileItemFactory(File tmpDir) {
+        DiskFileItemFactory fiFactory = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD,
tmpDir);
+        return fiFactory;
+    }
+
+    /**
+     * 
+     * @param request
+     * @param tmpDir
+     * @throws IOException
+     */
+    private void extractMultipart(HttpServletRequest request, File tmpDir)
+            throws IOException {
+        if (!ServletFileUpload.isMultipartContent(request)) {
+            log.warn("Request does not contain multipart content -> ignoring.");
+            return;
+        }
+
+        ServletFileUpload upload = new ServletFileUpload(getFileItemFactory(tmpDir));
+        try {
+            List fileItems = upload.parseRequest(request);
+            for (Iterator it = fileItems.iterator(); it.hasNext();) {
+                FileItem item = (FileItem) it.next();
+                addItem(item);
+            }
+        } catch (FileUploadException e) {
+            log.error("Error while processing multipart.", e);
+            throw new IOException(e.toString());
+        }
+    }
+
+    /**
+     * Add the given file item to the list defined for its name and make the
+     * list is present in the map. If the item does not represent a simple
+     * form field its name is also added to the <code>fileParamNames</code> set.
+     *
+     * @param item The {@link FileItem} to add.
+     */
+    private void addItem(FileItem item) {
+        String name = item.getFieldName();
+        ArrayList l = (ArrayList) nameToItems.get(item.getFieldName());
+        if (l == null) {
+            l = new ArrayList();
+            nameToItems.put(name, l);
+        }
+        l.add(item);
+
+        // if file parameter, add name to the set of file params in order to
+        // be able to extract the file param values later on without iterating
+        // over all keys.
+        if (!item.isFormField()) {
+            fileParamNames.add(name);
+        }
+    }
+
+    private void checkInitialized() {
+        if (!initialized) {
+            throw new IllegalStateException("HttpMultipartPost not initialized (or already
disposed).");
+        }
+    }
+
+    /**
+     * Release all file items hold with the name-to-items map. specially those
+     * having a tmp-file associated with.
+     * 
+     * @see FileItem#delete()
+     */
+    synchronized void dispose() {
+        checkInitialized();
+
+        for (Iterator it = nameToItems.values().iterator(); it.hasNext();) {
+            List fileItems = (List) it.next();
+            for (int i = 0; i < fileItems.size(); i++) {
+                FileItem item = (FileItem) fileItems.get(i);
+                item.delete();
+            }
+        }
+
+        nameToItems.clear();
+        fileParamNames.clear();
+        initialized = false;
+    }
+
+    /**
+     * Returns an iterator over all file item names.
+     *
+     * @return a set of strings.
+     */
+    Set getParameterNames() {
+        checkInitialized();
+        return nameToItems.keySet();
+    }
+
+
+    /**
+     * Returns the content types of the paramaters with the given name. If
+     * the parameter does not exist <code>null</code> is returned. If the content
+     * type of any of the parameter values is not known, the corresponding entry
+     * in the array returned is <code>null</code>.
+     * <p>
+     * The content type of a paramater is only known here if the information
+     * has been sent by the client browser. This is generally only the case
+     * for file upload fields of HTML forms which have been posted using the
+     * HTTP <em>POST</em> with <em>multipart/form-data</em> encoding.
+     * <p>
+     * Example : For the form
+     * <pre>
+         <form name="Upload" method="POST" ENCTYPE="multipart/form-data">
+            <input type="file" name="Upload"><br>
+            <input type="text" name="Upload"><br>
+            <input type="submit">
+         </form>
+     * </pre>
+     * this method will return an array of two entries when called for the
+     * <em>Upload</em> parameter. The first entry will contain the content
+     * type (if transmitted by the client) of the file uploaded. The second
+     * entry will be <code>null</code> because the content type of the text
+     * input field will generally not be sent by the client.
+     *
+     * @param name The name of the paramater whose content type is to be
+     * returned.
+     * @return The content types of the file items with the specified name.
+     */
+    String[] getParameterTypes(String name) {
+        checkInitialized();
+        String[] cts = null;
+        List l = (List) nameToItems.get(name);
+        if (l != null && !l.isEmpty()) {
+            cts = new String[l.size()];
+            for (int i = 0; i < cts.length; i++) {
+                cts[i] = ((FileItem) l.get(i)).getContentType();
+            }
+        }
+        return cts;
+    }
+    
+    /**
+     * Returns the first value of the file items with the given <code>name</code>.
+     * The byte to string converstion is done using either the contenttype of
+     * the file items or the <code>formEncoding</code>.
+     * <p/>
+     * Please note that if the addressed parameter is an uploaded file rather
+     * than a simple form entry, the name of the original file is returned    
+     * instead of the content.
+     *
+     * @param name the name of the parameter
+     * @return the string of the first value or <code>null</code> if the
+     *         parameter does not exist
+     */
+    String getParameter(String name) {
+        checkInitialized();
+        List l = (List) nameToItems.get(name);
+        if (l == null || l.isEmpty()) {
+            return null;
+        } else {
+            FileItem item = ((FileItem) l.get(0));
+            if (item.isFormField()) {
+                return item.getString();
+            } else {
+                return item.getName();
+            }
+        }
+    }
+
+    /**
+     * Returns an array of Strings with all values of the parameter addressed
+     * by <code>name</code>. the byte to string conversion is done using either
+     * the content type of the multipart body or the <code>formEncoding</code>.
+     * <p/>
+     * Please note that if the addressed parameter is an uploaded file rather
+     * than a simple form entry, the name of the original file is returned
+     * instead of the content.
+     *
+     * @param name the name of the parameter
+     * @return a string array of values or <code>null</code> if no entry with
the
+     * given name exists.
+     */
+    String[] getParameterValues(String name) {
+        checkInitialized();
+        List l = (List) nameToItems.get(name);
+        if (l == null || l.isEmpty()) {
+            return null;
+        } else {
+            String[] values = new String[l.size()];
+            for (int i = 0; i < values.length; i++) {
+                FileItem item = ((FileItem) l.get(i));
+                if (item.isFormField()) {
+                    values[i] = item.getString();
+                } else {
+                    values[i] = item.getName();
+                }
+            }
+            return values;
+        }
+    }
+
+    /**
+     * Returns a set of the file parameter names. An empty set if
+     * no file parameters were present in the request.
+     *
+     * @return an set of file item names representing the file
+     * parameters available with the request.
+     */
+    Set getFileParameterNames() {
+        checkInitialized();
+        return fileParamNames;
+    }
+    
+    /**
+     * Returns an array of input streams for uploaded file parameters.
+     *
+     * @param name the name of the file parameter(s)
+     * @return an array of input streams or <code>null</code> if no file params
+     * with the given name exist.
+     * @throws IOException if an I/O error occurs
+     */
+    InputStream[] getFileParameterValues(String name) throws IOException {
+        checkInitialized();
+        InputStream[] values = null;
+        if (fileParamNames.contains(name)) {
+            List l = (List) nameToItems.get(name);
+            if (l != null && !l.isEmpty()) {
+                List ins = new ArrayList(l.size());
+                for (Iterator it = l.iterator(); it.hasNext();) {
+                    FileItem item = (FileItem) it.next();
+                    if (!item.isFormField()) {
+                        ins.add(item.getInputStream());
+                    }
+                }
+                values = (InputStream[]) ins.toArray(new InputStream[ins.size()]);
+            }
+        }
+        return values;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/HttpMultipartPost.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/RequestData.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/RequestData.java?rev=740749&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/RequestData.java
(added)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/RequestData.java
Wed Feb  4 14:13:24 2009
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.server.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.File;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * <code>RequestData</code>...
+ */
+public class RequestData {
+
+    /**
+     * logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(RequestData.class);
+
+    private final HttpServletRequest request;
+    private final HttpMultipartPost mpReq;
+
+    public RequestData(HttpServletRequest request, File tmpDir) throws IOException {
+        this.request = request;
+        this.mpReq = new HttpMultipartPost(request, tmpDir);
+    }
+
+    /**
+     * Dispose resources used.
+     */
+    public void dispose() {
+        mpReq.dispose();
+    }
+    
+    /**
+     * Returns an iterator over all parameter names.
+     * 
+     * @return an iterator over strings.
+     */
+    public Iterator getParameterNames() {
+        
+        HashSet names = new HashSet(request.getParameterMap().keySet());
+        names.addAll(mpReq.getParameterNames());
+        
+        return names.iterator();
+    }
+
+    /**
+     * Returns the first value of the parameter with the given <code>name</code>.
+     * The byte to string converstion is done using either the contenttype of
+     * the parameter or the <code>formEncoding</code>.
+     * <p/>
+     * Please note that if the addressed parameter is a file parameter, the
+     * name of the original file is returned, and not its content.
+     *
+     * @param name the name of the parameter
+     * @return the string of the first value or <code>null</code> if the
+     *         parameter does not exist
+     */
+    public String getParameter(String name) {
+        String ret = mpReq.getParameter(name);
+        return (ret == null) ? request.getParameter(name) : ret;
+    }
+
+    /**
+     * Returns the content types retrieved for parameters with the specified
+     * name from the multipart or <code>null</code> if the multipart does not
+     * contain parameter(s) with the given name.
+     *
+     * @param name parameter name
+     * @return the parameter types retrieved for the specified parameter
+     * name from the multipart or <code>null</code>.
+     */
+    public String[] getParameterTypes(String name) {
+        String[] types = mpReq.getParameterTypes(name);
+        return types == null ? null : types;
+    }
+    
+    /**
+     * Returns an array of Strings with all values of the parameter addressed
+     * by <code>name</code>. the byte to string conversion is done using either
+     * the content type of the multipart body or the <code>formEncoding</code>.
+     * <p/>
+     * Please note that if the addressed parameter is a file parameter, the
+     * name of the original file is returned, and not its content.
+     *
+     * @param name the name of the parameter
+     * @return a string array of values or <code>null</code> if the parameter
+     *         does not exist.
+     */
+    public String[] getParameterValues(String name) {
+        String[] ret = mpReq.getParameterValues(name);
+        return ret == null ? request.getParameterValues(name) : ret;
+    }
+
+    /**
+     * Returns an array of input streams for uploaded file parameters.
+     *
+     * @param name the name of the file parameter(s)
+     * @return an array of input streams or an empty array if no file params
+     * with the given name exist.
+     * @throws IOException if an I/O error occurs
+     */
+    public InputStream[] getFileParameters(String name) throws IOException {
+        return mpReq.getFileParameterValues(name);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/util/RequestData.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Added: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java?rev=740749&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java
Wed Feb  4 14:13:24 2009
@@ -0,0 +1,378 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.server.remoting.davex;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/** <code>DiffParserTest</code>... */
+public class DiffParserTest extends TestCase {
+
+    public void testSetProperty() throws IOException, DiffException {
+        ArrayList l = new ArrayList();
+        l.add("\"simple string\"");
+        l.add("2345");
+        l.add("true");
+        l.add("false");
+        l.add("234.3455");
+        l.add("null");
+
+        for (int i = 0; i < l.size(); i++) {
+            final String value = l.get(i).toString();
+            String diff = "^/a/prop : " + value;
+
+            DummyDiffHandler handler = new DummyDiffHandler() {
+                public void setProperty(String targetPath, String diffValue) {
+                    assertEquals(targetPath, "/a/prop");
+                    assertEquals(value, diffValue);
+                }
+            };
+            DiffParser parser = new DiffParser(handler);
+            parser.parse(diff);
+        }
+    }
+
+    public void testSetPropertyMissing() throws IOException,
+            DiffException {
+        ArrayList l = new ArrayList();
+        l.add("");
+        l.add(null);
+
+        for (int i = 0; i < l.size(); i++) {
+            Object obj = l.get(i);
+            String value = (obj == null) ? "" : obj.toString();
+            String diff = "^/a/prop : " + value;
+
+            DummyDiffHandler handler = new DummyDiffHandler() {
+                public void setProperty(String targetPath, String diffValue) {
+                    assertEquals(targetPath, "/a/prop");
+                    assertTrue(diffValue == null || "".equals(diffValue));
+                }
+            };
+            DiffParser parser = new DiffParser(handler);
+            parser.parse(diff);
+        }
+    }
+
+    public void testSetPropertyWithUnicodeChars() throws IOException,
+            DiffException {
+        final String value = "\"String value containing \u2355\u8723 unicode chars.\"";
+        String diff = "^/a/prop : " + value;
+
+        DiffHandler handler = new DummyDiffHandler() {
+            public void setProperty(String targetPath, String diffValue) {
+                assertEquals(targetPath, "/a/prop");
+                assertEquals(value, diffValue);
+            }
+        };
+
+        DiffParser parser = new DiffParser(handler);
+        parser.parse(diff);
+    }
+
+    public void testSetPropertyWithTrailingLineSep() throws IOException,
+            DiffException {
+        final String value = "\"String value ending with \r\r\n\n\r\n.\"";
+        String diff = "^/a/prop : " + value;
+
+        DiffHandler handler = new DummyDiffHandler() {
+            public void setProperty(String targetPath, String diffValue) {
+                assertEquals(targetPath, "/a/prop");
+                assertEquals(value, diffValue);
+            }
+        };
+
+        DiffParser parser = new DiffParser(handler);
+        parser.parse(diff);
+    }
+
+    public void testSetPropertyWithSpecialChar() throws IOException, DiffException {
+        final String value = "+abc \\r+ \\n-ab >c \r\\r\\n+";
+        String diff = "^/a/prop : " + value;
+
+        DiffHandler handler = new DummyDiffHandler() {
+            public void setProperty(String targetPath, String diffValue) {
+                assertEquals(targetPath, "/a/prop");
+                assertEquals(value, diffValue);
+            }
+        };
+
+        DiffParser parser = new DiffParser(handler);
+        parser.parse(diff);
+    }
+
+    public void testSetPropertyUnterminatedString() throws IOException,
+            DiffException {
+        final String value = "\"String value ending with \r\r\n\n\r\n.";
+        String diff = "^/a/prop : " + value;
+
+        DiffHandler handler = new DummyDiffHandler() {
+            public void setProperty(String targetPath, String diffValue) {
+                assertEquals(targetPath, "/a/prop");
+                assertEquals(value, diffValue);
+            }
+        };
+        DiffParser parser = new DiffParser(handler);
+        parser.parse(diff);
+    }
+
+    public void testSetPropertyWithUnescapedAction() throws IOException,
+            DiffException {
+        String diff = "^abc : \r+def : \n-ghi : \r\n^jkl : \n\r>mno : \n";
+
+        DiffHandler handler = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue)
+                    throws DiffException {
+                assertEquals("def", targetPath);
+                assertEquals("", diffValue);
+            }
+            public void setProperty(String targetPath, String diffValue) {
+                assertTrue("abc".equals(targetPath) || "jkl".equals(targetPath));
+                assertEquals("", diffValue);
+            }
+            public void remove(String targetPath, String diffValue)
+                    throws DiffException {
+                assertEquals("ghi", targetPath);
+                assertEquals("", diffValue);
+            }
+
+            public void move(String targetPath, String diffValue) throws DiffException {
+                assertEquals("mno", targetPath);
+                assertEquals("\n", diffValue);
+            }
+        };
+
+        DiffParser parser = new DiffParser(handler);
+        parser.parse(diff);
+    }
+
+    public void testValidDiffs() throws IOException, DiffException {
+        List l = new ArrayList();
+        // unquoted string value
+        l.add(new String[] {"+/a/b : 134", "/a/b","134"});
+        l.add(new String[] {"+/a/b : 2.3", "/a/b","2.3"});
+        l.add(new String[] {"+/a/b : true", "/a/b","true"});
+        // quoted string value
+        l.add(new String[] {"+/a/b : \"true\"", "/a/b","\"true\""});
+        l.add(new String[] {"+/a/b : \"string value containing \u3456 unicode char.\"", "/a/b","\"string
value containing \u3456unicode char.\""});
+        // value consisting of quotes
+        l.add(new String[] {"+/a/b : \"", "/a/b","\""});
+        l.add(new String[] {"+/a/b : \"\"", "/a/b","\"\""});
+        // value consisting of single
+        l.add(new String[] {"+/a/b : '", "/a/b","'"});
+        l.add(new String[] {"+/a/b : ''''", "/a/b","''''"});
+        // value consisting of space(s) only
+        l.add(new String[] {"+/a/b :  ", "/a/b"," "});
+        l.add(new String[] {"+/a/b :     ", "/a/b","   "});
+        // value consisting of line separators only
+        l.add(new String[] {"+/a/b : \n", "/a/b","\n"});
+        l.add(new String[] {"+/a/b : \r", "/a/b","\r"});
+        l.add(new String[] {"+/a/b : \r\n", "/a/b","\r\n"});
+        l.add(new String[] {"+/a/b : \r\n\n\r", "/a/b","\r\n\n\r"});
+        // path containing whilespace
+        l.add(new String[] {"+/a   /b : 123", "/a   /b","123"});
+        l.add(new String[] {"+/a\r\t/b : 123", "/a\r\t/b","123"});
+        // path having trailing whitespace
+        l.add(new String[] {"+/a/b  : 123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\r : 123", "/a/b\r","123"});
+        l.add(new String[] {"+/a/b\r\n\n\r\n: 123", "/a/b\r\n\n\r\n","123"});
+        // path containing reserved characters
+        l.add(new String[] {"++abc+ : val", "+abc+","val"});
+        l.add(new String[] {"++++++ : val", "+++++","val"});
+        // value containing reserver characters
+        l.add(new String[] {"+/a/b : +", "/a/b","+"});
+        l.add(new String[] {"+/a/b : +->+-", "/a/b","+->+-"});
+        l.add(new String[] {"+/a/b : \"+->+-\"", "/a/b","\"+->+-\""});
+        // other whitespace than ' ' used as key-value separator
+        l.add(new String[] {"+/a/b :\r123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\r: 123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\r:\r123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\r:\n123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\t:\r123", "/a/b","123"});
+        l.add(new String[] {"+/a/b\t:\t123", "/a/b","123"});
+        // path containing colon
+        l.add(new String[] {"+/a:b/c:d : 123", "/a:b/c:d","123"});
+        // value starting with colon -> ok
+        l.add(new String[] {"+/a/b : : val", "/a/b",": val"});
+        // missing value
+        l.add(new String[] {"+/a/b : ", "/a/b", ""});
+        l.add(new String[] {"+/a/b :\n", "/a/b", ""});
+
+        for (Iterator it = l.iterator(); it.hasNext();) {
+            final String[] strs = (String[]) it.next();
+            DiffHandler hndl = new DummyDiffHandler() {
+                public void setProperty(String targetPath, String diffValue)
+                        throws DiffException {
+                    assertEquals(strs[1], targetPath);
+                    assertEquals(strs[2], diffValue);
+                }
+            };
+            DiffParser parser = new DiffParser(hndl);
+            parser.parse(strs[0]);
+        }
+
+        l = new ArrayList();
+        // multiple commands
+        l.add("+abc :\n\n+def : val");
+        l.add("+abc :\n\n+def : val\n");
+        l.add("+abc : \r+def : val");
+        l.add("+/a/b : val\r+abc : \r ");
+        l.add("+/a/b : val\r+abc :\n\n ");
+        // missing value in the last action.
+        l.add("+/a/b : \r+abc :\n");
+        l.add("+/a/b : \\r+abc : abc\r\r+abc :\r");
+        l.add("+abc :\n\n+def : val\r\r>abc : ");
+
+        for (Iterator it = l.iterator(); it.hasNext();) {
+            final List li = new ArrayList();
+            DiffHandler dh = new DummyDiffHandler() {
+                public void addNode(String targetPath, String diffValue) throws DiffException
{
+                    li.add(diffValue);
+                }
+            };
+
+            String diff = it.next().toString();
+            DiffParser parser = new DiffParser(dh);
+            parser.parse(diff);
+            assertEquals(2, li.size());
+        }
+    }
+
+    public void testSeparatorLines() throws IOException, DiffException {
+        String diff = "+abc :\n\n+val : val";
+        DiffHandler dh = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue) throws DiffException
{
+                if ("abc".equals(targetPath)) {
+                    assertEquals("", diffValue);
+                } else {
+                    assertEquals("val", diffValue);
+                }
+            }
+        };
+        new DiffParser(dh).parse(diff);
+
+        diff = "+abc :\n+val : val";
+        dh = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue) throws DiffException
{
+                assertEquals("+val : val", diffValue);
+            }
+        };
+        new DiffParser(dh).parse(diff);
+
+        // TODO: check again: currently all line-sep. chars before an diff-char are ignored
unless they are escaped in way the handler understands (e.g. JSON does: \\r for \r).
+        diff = "+abc :\r\r\r+def : val";
+        dh = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue) throws DiffException
{
+                if ("abc".equals(targetPath)) {
+                    assertEquals("", diffValue);
+                } else {
+                    assertEquals("val", diffValue);
+                }
+            }
+        };
+        new DiffParser(dh).parse(diff);
+
+        diff = "+abc : val\r+def :\n\n ";
+        dh = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue) throws DiffException
{
+                if ("abc".equals(targetPath)) {
+                    assertEquals("val", diffValue);
+                } else {
+                    assertEquals("\n ", diffValue);
+                }
+            }
+        };
+        new DiffParser(dh).parse(diff);
+    }
+
+    public void testUnicodeLineSep() throws IOException, DiffException {
+        String diff = "+abc : val" + new String(new byte[] {Character.LINE_SEPARATOR}, "utf-8")
+ "+abc : val";
+        DiffHandler dh = new DummyDiffHandler() {
+            public void addNode(String targetPath, String diffValue) throws DiffException
{
+                assertEquals("abc", targetPath);
+                assertEquals("val", diffValue);
+            }
+        };
+        new DiffParser(dh).parse(diff);
+    }
+
+    public void testInvalidDiff() throws IOException, DiffException {
+        List l = new ArrayList();
+        l.add("");
+        // path, separator and value missing
+        l.add("+");
+        l.add("+/a/b : val\r+");
+        // path starting with whitespace, separator and value missing
+        l.add("+\n");
+        // separator and value missing
+        l.add("+/a/b");
+        l.add("+/a/b : val\r+abc\n");
+        l.add("+/a/b :");
+        // invalid for separator and value are missing (all : and whitespace
+        // is interpreted as part of the path.
+        l.add("+/a/b:");
+        l.add("+/a/b:val");
+        l.add("+/a/b: val");
+        l.add("+/a/b:\rval");
+        l.add("+/a/b :: val");
+        // diff starting with whitespace
+        l.add(" +/a/b: val");
+        l.add("\r\r\r\r\r\r+/a/b: val");
+        // key starting with whitespace
+        l.add("+\r/a/b : 123");
+        l.add("+ /a/b : 123");
+        // key starting with colon
+        l.add("+:/a/b : 123");
+
+        for (Iterator it = l.iterator(); it.hasNext();) {
+            String diff = it.next().toString();
+            try {
+                DiffParser parser = new DiffParser(new DummyDiffHandler());
+                parser.parse(diff);
+                fail(diff + " is not a valid diff string -> should throw DiffException.");
+            } catch (DiffException e) {
+                // ok
+            }
+        }
+    }
+
+    private class DummyDiffHandler implements DiffHandler {
+
+        public void addNode(String targetPath, String diffValue)
+                throws DiffException {
+            // does nothing
+        }
+
+        public void setProperty(String targetPath, String diffValue)
+                throws DiffException {
+            // does nothing
+        }
+
+        public void remove(String targetPath, String diffValue)
+                throws DiffException {
+            // does nothing
+        }
+
+        public void move(String targetPath, String diffValue) throws DiffException {
+            // does nothing
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/DiffParserTest.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java?rev=740749&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
(added)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
Wed Feb  4 14:13:24 2009
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.server.remoting.davex;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that includes all testcases for package org.apache.jackrabbit.server.remoting.davex.
+ */
+public class TestAll extends TestCase {
+
+    /**
+     * Returns a <code>Test</code> suite that executes all tests inside this
+     * package.
+     */
+    public static Test suite() {
+        TestSuite suite = new TestSuite("org.apache.jackrabbit.server.remoting.davex tests");
+
+        suite.addTestSuite(DiffParserTest.class);
+
+        return suite;
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-jcr-server/src/test/java/org/apache/jackrabbit/server/remoting/davex/TestAll.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url



Mime
View raw message