Author: trang_vu
Date: 2011-08-19 03:10:16 -0400 (Fri, 19 Aug 2011)
New Revision: 4778
Added:
jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1652/readme.txt
Modified:
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/resources/conf/test/webdav-nodetypes.xml
Log:
JCR-1652: Empty multi-valued properties should be processed properly
How is the problem fixed?
* Before trying to get property value, we check whether the array is empty.
Modified:
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java 2011-08-18
15:15:47 UTC (rev 4777)
+++
jcr/branches/1.12.x/exo.jcr.component.webdav/src/main/java/org/exoplatform/services/jcr/webdav/resource/FileResource.java 2011-08-19
07:10:16 UTC (rev 4778)
@@ -315,7 +315,18 @@
String propertyValue;
if (property.getDefinition().isMultiple())
{
- propertyValue = property.getValues()[0].getString();
+ if (property.getValues().length >= 1)
+ {
+ propertyValue = property.getValues()[0].getString();
+ }
+ else
+ {
+ // this means that we return empty value, because according to WebDAV
spec:
+ // this is a property whose semantics and syntax are not enforced by
the server
+ // the server only records the value of a dead property;
+ // the client is responsible for maintaining the consistency of the
syntax and semantics of a dead property.
+ propertyValue = "";
+ }
}
else
{
@@ -323,7 +334,6 @@
}
return new HierarchicalProperty(name, propertyValue);
}
-
}
}
Modified:
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2011-08-18
15:15:47 UTC (rev 4777)
+++
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/java/org/exoplatform/services/jcr/webdav/command/TestPropFind.java 2011-08-19
07:10:16 UTC (rev 4778)
@@ -46,17 +46,27 @@
protected Node testPropFind;
- private final String author = "eXoPlatform";
+ private final static String AUTHOR = "eXoPlatform";
- private final String authorProp = "webdav:Author";
+ private final static String WEBDAV_AUTHOR_PROPERTY = "webdav:Author";
- private final String nt_webdave_file = "webdav:file";
+ private final static String WEBDAV_NT_FILE = "webdav:file";
+ private final static String WEBDAV_NT_RESOURCE = "exo:testResource";
+
+ private final static String WEBDAV_TEST_PROPERTY = "webdav:test-property";
+
+ private final static String CONTENT_TYPE = "text/xml";
+
private String propFindXML =
"<?xml version=\"1.0\" encoding=\"utf-8\"
?><D:propfind xmlns:D=\"DAV:\">"
+ "<D:prop
xmlns:webdav=\"http://www.exoplatform.org/jcr/webdav\">"
+
"<webdav:Author/><webdav:author/><webdave:DingALing/></D:prop></D:propfind>";
+ private String multiPropFindXML = "<?xml version=\"1.0\"
encoding=\"utf-8\" ?><D:propfind xmlns:D=\"DAV:\">"
+ + "<D:prop
xmlns:webdav=\"http://www.exoplatform.org/jcr/webdav\">" +
"<" + WEBDAV_TEST_PROPERTY
+ + "/></D:prop></D:propfind>";
+
private String propnameXML =
"<?xml version=\"1.0\" encoding=\"utf-8\"
?><propfind xmlns=\"DAV:\"><propname/></propfind>";
@@ -97,7 +107,7 @@
{
String content = TestUtils.getFileContent();
String file = TestUtils.getFileName();
- TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
nt_webdave_file, "");
+ TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
WEBDAV_NT_FILE, "");
ContainerResponse containerResponseFind = service(WebDAVMethods.PROPFIND,
getPathWS() + file, "", null, null);
assertEquals(HTTPStatus.MULTISTATUS, containerResponseFind.getStatus());
}
@@ -116,8 +126,8 @@
String encodedfileName =
"%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a";
String decodedfileName = URLDecoder.decode(encodedfileName, "UTF-8");
String content = TestUtils.getFileContent();
- TestUtils.addContent(session, decodedfileName, new
ByteArrayInputStream(content.getBytes()), nt_webdave_file, "");
- TestUtils.addNodeProperty(session, decodedfileName, authorProp, author);
+ TestUtils.addContent(session, decodedfileName, new
ByteArrayInputStream(content.getBytes()), WEBDAV_NT_FILE, "");
+ TestUtils.addNodeProperty(session, decodedfileName, WEBDAV_AUTHOR_PROPERTY,
AUTHOR);
ContainerResponse response =
service(WebDAVMethods.PROPFIND, getPathWS() + "/" + encodedfileName,
"", null, allPropsXML.getBytes());
@@ -142,8 +152,8 @@
{
String content = TestUtils.getFileContent();
String file = TestUtils.getFileName();
- TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
nt_webdave_file, "");
- TestUtils.addNodeProperty(session, file, authorProp, author);
+ TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
WEBDAV_NT_FILE, "");
+ TestUtils.addNodeProperty(session, file, WEBDAV_AUTHOR_PROPERTY, AUTHOR);
MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
headers.add(HttpHeaders.CONTENT_TYPE, "text/xml");
ContainerResponse responseFind =
@@ -153,16 +163,87 @@
PropFindResponseEntity entity = (PropFindResponseEntity)responseFind.getEntity();
entity.write(outputStream);
String find = outputStream.toString();
- assertTrue(find.contains(authorProp));
- assertTrue(find.contains(author));
+ assertTrue(find.contains(WEBDAV_AUTHOR_PROPERTY));
+ assertTrue(find.contains(AUTHOR));
}
+ /**
+ * Here we test WebDAV PROPFIND method implementation for correct response
+ * in case we are asking for a multi-valued property. It is expected
+ * to receive first value of a values list. That is basicly because WebDAV
+ * actually does not support multi-valued properties in the way JCR does,
+ * though it supports nested (hierarchical) properties.
+ * @throws Exception
+ */
+ public void testNonEmptyMultiPropFind() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String file = TestUtils.getFileName();
+ String[] propValues =
+ new String[]{"No sacrifice is too great in the service of freedom.",
+ "Freedom is the right of all sentient beings."};
+
+ Node node =
+ TestUtils.addContent(session, file, new
ByteArrayInputStream(content.getBytes()), WEBDAV_NT_FILE,
+ WEBDAV_NT_RESOURCE, CONTENT_TYPE);
+
+ // set multi-valued property
+ node.getNode("jcr:content").setProperty(WEBDAV_TEST_PROPERTY,
propValues);
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE);
+
+ ContainerResponse responseFind =
+ service(WebDAVMethods.PROPFIND, getPathWS() + file, "", headers,
multiPropFindXML.getBytes());
+ assertEquals(HTTPStatus.MULTISTATUS, responseFind.getStatus());
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ PropFindResponseEntity entity = (PropFindResponseEntity)responseFind.getEntity();
+ entity.write(outputStream);
+ String find = outputStream.toString();
+ assertTrue("Response should contain requested property element.",
find.contains(WEBDAV_TEST_PROPERTY));
+ assertTrue("Property element should contain value data.",
+ find.contains("No sacrifice is too great in the service of
freedom."));
+ }
+
+ /**
+ * Here we test WebDAV PROPFIND method implementation for correct response
+ * in case we are asking for an empty multi-valued property. It is expected
+ * to receive an empty value in response xml representation as it is 'dead'
+ * property and it is not a server responsibility to support its consistency.
+ * @throws Exception
+ */
+ public void testEmptyMultiPropFind() throws Exception
+ {
+ String content = TestUtils.getFileContent();
+ String file = TestUtils.getFileName();
+
+ Node node =
+ TestUtils.addContent(session, file, new
ByteArrayInputStream(content.getBytes()), WEBDAV_NT_FILE,
+ WEBDAV_NT_RESOURCE, CONTENT_TYPE);
+ // set empty multi-valued property
+ node.getNode("jcr:content").setProperty(WEBDAV_TEST_PROPERTY, new
String[]{});
+ session.save();
+
+ MultivaluedMap<String, String> headers = new MultivaluedMapImpl();
+ headers.add(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE);
+
+ ContainerResponse responseFind =
+ service(WebDAVMethods.PROPFIND, getPathWS() + file, "", headers,
multiPropFindXML.getBytes());
+ assertEquals(HTTPStatus.MULTISTATUS, responseFind.getStatus());
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ PropFindResponseEntity entity = (PropFindResponseEntity)responseFind.getEntity();
+ entity.write(outputStream);
+ String find = outputStream.toString();
+ assertTrue("Response should contain requested property element.",
find.contains(WEBDAV_TEST_PROPERTY));
+ }
+
public void testPropNames() throws Exception
{
String content = TestUtils.getFileContent();
String file = TestUtils.getFileName();
- TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
nt_webdave_file, "");
- TestUtils.addNodeProperty(session, file, authorProp, author);
+ TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
WEBDAV_NT_FILE, "");
+ TestUtils.addNodeProperty(session, file, WEBDAV_AUTHOR_PROPERTY, AUTHOR);
ContainerResponse responseFind =
service(WebDAVMethods.PROPFIND, getPathWS() + file, "", null,
propnameXML.getBytes());
assertEquals(HTTPStatus.MULTISTATUS, responseFind.getStatus());
@@ -170,7 +251,7 @@
PropFindResponseEntity entity = (PropFindResponseEntity)responseFind.getEntity();
entity.write(outputStream);
String find = outputStream.toString();
- assertTrue(find.contains(authorProp));
+ assertTrue(find.contains(WEBDAV_AUTHOR_PROPERTY));
assertTrue(find.contains("D:getlastmodified"));
}
@@ -178,8 +259,8 @@
{
String content = TestUtils.getFileContent();
String file = TestUtils.getFileName();
- TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
nt_webdave_file, "");
- TestUtils.addNodeProperty(session, file, authorProp, author);
+ TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
WEBDAV_NT_FILE, "");
+ TestUtils.addNodeProperty(session, file, WEBDAV_AUTHOR_PROPERTY, AUTHOR);
ContainerResponse responseFind =
service(WebDAVMethods.PROPFIND, getPathWS() + file, "", null,
allPropsXML.getBytes());
assertEquals(HTTPStatus.MULTISTATUS, responseFind.getStatus());
@@ -188,21 +269,17 @@
entity.write(outputStream);
String find = outputStream.toString();
assertTrue(find.contains("D:getlastmodified"));
- assertTrue(find.contains(authorProp));
- assertTrue(find.contains(author));
+ assertTrue(find.contains(WEBDAV_AUTHOR_PROPERTY));
+ assertTrue(find.contains(AUTHOR));
}
-
-
-
-
-
+
public void testPropWithPercent() throws Exception
{
String content = TestUtils.getFileContent();
String file = TestUtils.getFileName();
- TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
nt_webdave_file, "");
+ TestUtils.addContent(session, file, new ByteArrayInputStream(content.getBytes()),
WEBDAV_NT_FILE, "");
String authorValue = "bla % bla";
- TestUtils.addNodeProperty(session, file, authorProp, authorValue);
+ TestUtils.addNodeProperty(session, file, WEBDAV_AUTHOR_PROPERTY, authorValue);
ContainerResponse responseFind =
service(WebDAVMethods.PROPFIND, getPathWS() + file, "", null,
allPropsXML.getBytes());
assertEquals(HTTPStatus.MULTISTATUS, responseFind.getStatus());
@@ -211,7 +288,7 @@
entity.write(outputStream);
String find = outputStream.toString();
assertTrue(find.contains("D:getlastmodified"));
- assertTrue(find.contains(authorProp));
+ assertTrue(find.contains(WEBDAV_AUTHOR_PROPERTY));
assertTrue(find.contains(authorValue));
}
Modified:
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/resources/conf/test/webdav-nodetypes.xml
===================================================================
---
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/resources/conf/test/webdav-nodetypes.xml 2011-08-18
15:15:47 UTC (rev 4777)
+++
jcr/branches/1.12.x/exo.jcr.component.webdav/src/test/resources/conf/test/webdav-nodetypes.xml 2011-08-19
07:10:16 UTC (rev 4778)
@@ -113,6 +113,18 @@
<supertype>nt:unstructured</supertype>
</supertypes>
+ <propertyDefinitions>
+ <propertyDefinition name="*" requiredType="undefined"
autoCreated="false" mandatory="false" onParentVersion="COPY"
protected="false"
+
+ multiple="false">
+ <valueConstraints />
+ </propertyDefinition>
+ <propertyDefinition name="webdav:test-property"
requiredType="String" autoCreated="false" mandatory="false"
onParentVersion="COPY" protected="false"
+ multiple="true">
+ <valueConstraints />
+ </propertyDefinition>
+ </propertyDefinitions>
+
</nodeType>
<nodeType name="exo:testContentResource" isMixin="false"
hasOrderableChildNodes="true" primaryItemName="">
Added: jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1652/readme.txt
===================================================================
--- jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1652/readme.txt (rev
0)
+++ jcr/branches/1.12.x/patch/1.12.10-GA/JCR-1652/readme.txt 2011-08-19 07:10:16 UTC (rev
4778)
@@ -0,0 +1,91 @@
+Summary
+
+ * Status: Empty multi-valued properties should be processed properly
+ * CCP Issue: N/A, Product Jira Issue: JCR-1652.
+ * Complexity: low
+
+The Proposal
+Problem description
+
+What is the problem to fix?
+
+ * When we have empty multi-valued property we receive exception, trying to get it via
WebDAV, becuase of trying to get first element of array of property values which is
empty.
+
+Fix description
+
+How is the problem fixed?
+
+ * Before trying to get property value we check if array containing it is empty.
+
+Patch file: JCR-1652.patch
+
+Tests to perform
+
+Reproduction test
+
+ * Steps to reproduce:
+
+ 1. Upload a CSS file in the content explorer
+ 1. Login as root in the file explorer
+ 2. Go in Collaboration/Documents
+ 3. Create a new folder "TEST"
+ 4. Upload a new CSS file into this folder
+ 5. view it
+ 2. Edit the file in the IDE
+ 1. Go to Collaboration workspace
+ 2. Go to /Documents/TEST. You can see your CSS
+ 3. Modify and save the file
+ 4. The file is updated, you can modify and save it if you want.
+ 3. Use the Content Explorer to modify this file
+ 1. Go back to the file explorer
+ 2. Go on your file
+ 3. As you can see the file is updated
+ 4. You must Check Out the file (yes we are using DAV on the IDE)
+ 5. Edit it using the File Explorer
+ 6. Save it
+ 7. Close it
+ 4. Go back to the IDE. You cannot get back to the folder/file
+
+Tests performed at DevLevel
+
+ * Unit test were created to cover this issue. It tests for correct response if
we're trying to get property value of multi-valued property
+
+Tests performed at QA/Support Level
+*
+Documentation changes
+
+Documentation changes:
+
+ * None
+
+Configuration changes
+
+Configuration changes:
+
+ * None
+
+Will previous configuration continue to work?
+
+ * Yes
+
+Risks and impacts
+
+Can this bug fix have any side effects on current client projects?
+
+ * No
+
+Is there a performance risk/cost?
+
+ * No
+
+Validation (PM/Support/QA)
+
+PM Comment
+* Patch approved.
+
+Support Comment
+* Patch validated.
+
+QA Feedbacks
+*
+