You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2010/06/22 20:39:51 UTC
svn commit: r956972 - in /sling/trunk:
bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/
launchpad/integration-tests/
launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/
Author: justin
Date: Tue Jun 22 18:39:51 2010
New Revision: 956972
URL: http://svn.apache.org/viewvc?rev=956972&view=rev
Log:
SLING-1569 - fixing the handling of the WeakReference hint. Uses reflection to avoid dependency upon JCR 2. If reflection fails to find the method (i.e. this is running on JCR 1), a Reference property is created instead.
Modified:
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
sling/trunk/launchpad/integration-tests/pom.xml
sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/ReferenceTypeHintTest.java
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java?rev=956972&r1=956971&r2=956972&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/ReferenceParser.java Tue Jun 22 18:39:51 2010
@@ -16,12 +16,18 @@
*/
package org.apache.sling.servlets.post.impl.helper;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Takes a string representation of a node (either a path or a uuid) and tries for parse it.
*/
@@ -29,56 +35,86 @@ public class ReferenceParser {
private final Session session;
+ private static final Logger logger = LoggerFactory.getLogger(ReferenceParser.class);
+
public ReferenceParser(Session session) {
this.session = session;
}
/**
- * Parses the given source string and returns the corresponding node.
+ * Parses the given source string and returns the correct Value object.
* If no node matches returns <code>null</code>.
* <p/>
*
* @param value a path or UUID
- * @return the node or <code>null</code>
+ * @param factory the value factory
+ * @param weak true to create a WeakReference value
+ * @return the value or <code>null</code>
* @throws RepositoryException
*/
- public Node parse(String value) throws RepositoryException {
- try {
- if (session.itemExists(value)) {
- return (Node) session.getItem(value);
- }
- } catch (RepositoryException ignore) {
- // we ignore this
+ public Value parse(String value, ValueFactory factory, boolean weak) throws RepositoryException {
+ Node n = parse(value);
+ if (n == null) {
+ return null;
}
- try {
- return session.getNodeByUUID(value);
- } catch (RepositoryException ignore) {
- // we ignore this
- }
- return null;
+ return createReferenceValue(n, factory, weak);
}
/**
- * Parses the given source strings and returns the respective jcr Node value
+ * Parses the given source strings and returns the respective reference value
* instances. If no node matches for any of the sources
* returns <code>null</code>.
* <p/>
*
* @param values path or UUID strings
* @param factory the value factory
- * @return the nodes or <code>null</code>
+ * @param weak true to create a WeakReference value
+ * @return the values or <code>null</code>
* @throws RepositoryException
*/
- public Value[] parse(String[] values, ValueFactory factory) throws RepositoryException {
+ public Value[] parse(String[] values, ValueFactory factory, boolean weak) throws RepositoryException {
Value ret[] = new Value[values.length];
for (int i=0; i< values.length; i++) {
Node n = parse(values[i]);
if (n == null) {
return null;
}
- ret[i] = factory.createValue(n);
+ ret[i] = createReferenceValue(n, factory, weak);
}
return ret;
}
+ private Value createReferenceValue(Node node, ValueFactory factory, boolean weak) throws RepositoryException {
+ if (weak) {
+ try {
+ final Method m = factory.getClass().getMethod("createValue", new Class[] { Node.class, Boolean.TYPE });
+ return (Value) m.invoke(factory, node, true);
+ } catch (NoSuchMethodException e) {
+ logger.warn("A WeakReference type hint was received, but JCR 2 isn't available. Falling back to Reference type.");
+ return factory.createValue(node);
+ } catch (Exception e) {
+ logger.error("Unable to create WeakReference Value.", e);
+ return null;
+ }
+ } else {
+ return factory.createValue(node);
+ }
+ }
+
+ private Node parse(String value) throws RepositoryException {
+ try {
+ if (session.itemExists(value)) {
+ return (Node) session.getItem(value);
+ }
+ } catch (RepositoryException ignore) {
+ // we ignore this
+ }
+ try {
+ return session.getNodeByUUID(value);
+ } catch (RepositoryException ignore) {
+ // we ignore this
+ }
+ return null;
+ }
+
}
Modified: sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java?rev=956972&r1=956971&r2=956972&view=diff
==============================================================================
--- sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java (original)
+++ sling/trunk/bundles/servlets/post/src/main/java/org/apache/sling/servlets/post/impl/helper/SlingPropertyValueHandler.java Tue Jun 22 18:39:51 2010
@@ -191,6 +191,7 @@ public class SlingPropertyValueHandler {
*/
private void setPropertyAsIs(Node parent, RequestProperty prop)
throws RepositoryException {
+ final ValueFactory valFac = parent.getSession().getValueFactory();
// no explicit typehint
int type = PropertyType.UNDEFINED;
@@ -248,17 +249,16 @@ public class SlingPropertyValueHandler {
return;
}
} else if (isReferencePropertyType(type)) {
- Node n = referenceParser.parse(values[0]);
- if (n != null) {
+ Value v = referenceParser.parse(values[0], valFac, isWeakReference(type));
+ if (v != null) {
if ( prop.hasMultiValueTypeHint() ) {
- final Value[] array = new Value[1];
- array[0] = parent.getSession().getValueFactory().createValue(n);
+ final Value[] array = new Value[] { v };
changes.add(Modification.onModified(
parent.setProperty(prop.getName(), array).getPath()
));
} else {
changes.add(Modification.onModified(
- parent.setProperty(prop.getName(), n).getPath()
+ parent.setProperty(prop.getName(), v).getPath()
));
}
return;
@@ -287,7 +287,6 @@ public class SlingPropertyValueHandler {
if (type == PropertyType.DATE) {
// try conversion
- ValueFactory valFac = parent.getSession().getValueFactory();
Value[] c = dateParser.parse(values, valFac);
if (c != null) {
changes.add(Modification.onModified(
@@ -297,8 +296,7 @@ public class SlingPropertyValueHandler {
}
} else if (isReferencePropertyType(type)) {
// try conversion
- ValueFactory valFac = parent.getSession().getValueFactory();
- Value[] n = referenceParser.parse(values, valFac);
+ Value[] n = referenceParser.parse(values, valFac, isWeakReference(type));
if (n != null) {
changes.add(Modification.onModified(
parent.setProperty(prop.getName(), n).getPath()
@@ -321,6 +319,10 @@ public class SlingPropertyValueHandler {
return propertyType == PropertyType.REFERENCE || propertyType == PROPERTY_TYPE_WEAKREFERENCE;
}
+ private boolean isWeakReference(int propertyType) {
+ return propertyType == PROPERTY_TYPE_WEAKREFERENCE;
+ }
+
/**
* Defines an auto property behavior
*/
Modified: sling/trunk/launchpad/integration-tests/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/pom.xml?rev=956972&r1=956971&r2=956972&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/pom.xml (original)
+++ sling/trunk/launchpad/integration-tests/pom.xml Tue Jun 22 18:39:51 2010
@@ -152,5 +152,11 @@
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
Modified: sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/ReferenceTypeHintTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/ReferenceTypeHintTest.java?rev=956972&r1=956971&r2=956972&view=diff
==============================================================================
--- sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/ReferenceTypeHintTest.java (original)
+++ sling/trunk/launchpad/integration-tests/src/main/java/org/apache/sling/launchpad/webapp/integrationtest/servlets/post/ReferenceTypeHintTest.java Tue Jun 22 18:39:51 2010
@@ -16,6 +16,7 @@
*/
package org.apache.sling.launchpad.webapp.integrationtest.servlets.post;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@@ -24,6 +25,13 @@ import org.apache.sling.commons.json.JSO
import org.apache.sling.commons.testing.integration.HttpTestBase;
import org.apache.sling.commons.testing.integration.NameValuePairList;
import org.apache.sling.servlets.post.SlingPostConstants;
+import org.custommonkey.xmlunit.NamespaceContext;
+import org.custommonkey.xmlunit.SimpleNamespaceContext;
+import org.custommonkey.xmlunit.XMLAssert;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.custommonkey.xmlunit.exceptions.XpathException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
/**
* Integration test of reference type hints in the post servlet.
@@ -31,27 +39,59 @@ import org.apache.sling.servlets.post.Sl
public class ReferenceTypeHintTest extends HttpTestBase {
public static final String TEST_BASE_PATH = "/sling-tests";
private String postUrl;
+ private String firstCreatedNodeUrl;
+ private String firstUuid;
+ private String firstPath;
+ private String secondCreatedNodeUrl;
+ private String secondUuid;
+ private String secondPath;
@Override
protected void setUp() throws Exception {
super.setUp();
postUrl = HTTP_BASE_URL + TEST_BASE_PATH + "/" + System.currentTimeMillis();
- }
- public void testReferenceTypes() throws Exception {
+
+ Map<String,String> m = new HashMap<String,String>();
+ m.put("sv", "http://www.jcp.org/jcr/sv/1.0");
+
+ NamespaceContext ctx = new SimpleNamespaceContext(m);
+ XMLUnit.setXpathNamespaceContext(ctx);
+
+
final NameValuePairList props = new NameValuePairList();
props.add("a", "");
props.add("jcr:mixinTypes", "mix:referenceable");
- final String firstCreatedNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, props, null, false);
- final String firstUuid = getProperty(firstCreatedNodeUrl, "jcr:uuid");
- final String firstPath = getPath(firstCreatedNodeUrl);
-
- final String secondCreatedNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, props, null, false);
- final String secondUuid = getProperty(secondCreatedNodeUrl, "jcr:uuid");
- final String secondPath = getPath(secondCreatedNodeUrl);
+ firstCreatedNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, props, null, false);
+ firstUuid = getProperty(firstCreatedNodeUrl, "jcr:uuid");
+ firstPath = getPath(firstCreatedNodeUrl);
+
+ secondCreatedNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX, props, null, false);
+ secondUuid = getProperty(secondCreatedNodeUrl, "jcr:uuid");
+ secondPath = getPath(secondCreatedNodeUrl);
+ }
- props.clear();
+ public void testReferenceTypesCreatedFromUuids() throws Exception {
+ final NameValuePairList props = new NameValuePairList();
+ props.add("r", firstUuid);
+ props.add("r@TypeHint", "Reference");
+ props.add("w", firstUuid);
+ props.add("w@TypeHint", "WeakReference");
+ props.add("rs", firstUuid);
+ props.add("rs", secondUuid);
+ props.add("rs@TypeHint", "Reference[]");
+ props.add("ws", firstUuid);
+ props.add("ws", secondUuid);
+ props.add("ws@TypeHint", "WeakReference[]");
+ final String referencingNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX,
+ props, null, false);
+
+ verifyReferences(referencingNodeUrl);
+ }
+
+ public void testReferenceTypesCreatedFromPath() throws Exception {
+ final NameValuePairList props = new NameValuePairList();
props.add("r", firstPath);
props.add("r@TypeHint", "Reference");
props.add("w", firstPath);
@@ -65,11 +105,15 @@ public class ReferenceTypeHintTest exten
final String referencingNodeUrl = testClient.createNode(postUrl + SlingPostConstants.DEFAULT_CREATE_SUFFIX,
props, null, false);
- String refCreatedValue = getProperty(referencingNodeUrl, "r");
- String weakrefCreatedValue = getProperty(referencingNodeUrl, "w");
+ verifyReferences(referencingNodeUrl);
+ }
- String[] refCreatedValues = getPropertyArray(referencingNodeUrl, "rs");
- String[] weakrefCreatedValues = getPropertyArray(referencingNodeUrl, "ws");
+ private void verifyReferences(final String referencingNodeUrl) throws Exception {
+ final String refCreatedValue = getProperty(referencingNodeUrl, "r");
+ final String weakrefCreatedValue = getProperty(referencingNodeUrl, "w");
+
+ final String[] refCreatedValues = getPropertyArray(referencingNodeUrl, "rs");
+ final String[] weakrefCreatedValues = getPropertyArray(referencingNodeUrl, "ws");
assertEquals(firstUuid, refCreatedValue);
assertEquals(firstUuid, weakrefCreatedValue);
@@ -77,6 +121,17 @@ public class ReferenceTypeHintTest exten
assertEquals(firstUuid, weakrefCreatedValues[0]);
assertEquals(secondUuid, refCreatedValues[1]);
assertEquals(secondUuid, weakrefCreatedValues[1]);
+
+ final String sysView = getSystemView(referencingNodeUrl);
+
+ XMLAssert.assertXpathEvaluatesTo("Reference", "//sv:property[@sv:name='r']/@sv:type", sysView);
+ XMLAssert.assertXpathEvaluatesTo("WeakReference", "//sv:property[@sv:name='w']/@sv:type", sysView);
+ XMLAssert.assertXpathEvaluatesTo("Reference", "//sv:property[@sv:name='rs']/@sv:type", sysView);
+ XMLAssert.assertXpathEvaluatesTo("WeakReference", "//sv:property[@sv:name='ws']/@sv:type", sysView);
+ }
+
+ private String getSystemView(String url) throws IOException, SAXException {
+ return getContent(url + ".sysview.xml", CONTENT_TYPE_XML);
}
private String getPath(String url) {