You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:20:18 UTC
[sling-org-apache-sling-testing-resourceresolver-mock] 10/15:
SLING-3889 Make compatible to JCR resource
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.testing.resourceresolver-mock-0.3.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-resourceresolver-mock.git
commit 1ad5976725f17c0dcd66a042ec1149cf63cb53f7
Author: sseifert <ss...@unknown>
AuthorDate: Tue Sep 9 12:47:37 2014 +0000
SLING-3889 Make compatible to JCR resource
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/testing/resourceresolver-mock@1623814 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 14 ++
...MockResource.java => MockPropertyResource.java} | 51 ++----
.../testing/resourceresolver/MockResource.java | 17 +-
.../resourceresolver/MockResourceResolver.java | 30 +++-
.../testing/resourceresolver/MockValueMap.java | 109 ++++++++++++
.../SlingCrudResourceResolverTest.java | 187 +++++++++++++++++++++
6 files changed, 365 insertions(+), 43 deletions(-)
diff --git a/pom.xml b/pom.xml
index 681b67d..a38f9d1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,10 +69,24 @@
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>4.3.0</version>
+ <scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
+
</project>
diff --git a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java b/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
similarity index 60%
copy from src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
copy to src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
index 7b80e2f..a6884f1 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockPropertyResource.java
@@ -18,31 +18,29 @@
*/
package org.apache.sling.testing.resourceresolver;
-import java.util.Map;
-
import org.apache.sling.api.resource.AbstractResource;
-import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ModifiableValueMapDecorator;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
-
-public class MockResource extends AbstractResource {
+/**
+ * Resource that wraps a property value.
+ */
+class MockPropertyResource extends AbstractResource {
+
private final String path;
-
- private final Map<String, Object> props;
-
- private final ResourceMetadata rm = new ResourceMetadata();
-
+ private final ValueMap props;
+ private final String key;
private final ResourceResolver resolver;
+ private final ResourceMetadata rm = new ResourceMetadata();
- public MockResource(final String path,
- final Map<String, Object> props,
+ public MockPropertyResource(final String path,
+ final ValueMap props,
final ResourceResolver resolver) {
this.path = path;
this.props = props;
+ this.key = ResourceUtil.getName(path);
this.resolver = resolver;
}
@@ -53,12 +51,12 @@ public class MockResource extends AbstractResource {
@Override
public String getResourceType() {
- return (String)this.props.get(ResourceResolver.PROPERTY_RESOURCE_TYPE);
+ return null;
}
@Override
public String getResourceSuperType() {
- return (String)this.props.get("sling:resourceSuperType");
+ return null;
}
@Override
@@ -71,26 +69,13 @@ public class MockResource extends AbstractResource {
return this.resolver;
}
- @SuppressWarnings("unchecked")
@Override
- public <AdapterType> AdapterType adaptTo(final Class<AdapterType> type) {
- if ( type == ValueMap.class ) {
- return (AdapterType)new ValueMapDecorator(this.props);
- } else if ( type == ModifiableValueMap.class ) {
- ((MockResourceResolver)this.resolver).addChanged(this.path, this.props);
- return (AdapterType)new ModifiableValueMapDecorator(this.props);
+ public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+ AdapterType value = props.get(key, type);
+ if (value!=null) {
+ return value;
}
return super.adaptTo(type);
}
- @Override
- public ValueMap getValueMap() {
- return new ValueMapDecorator(this.props);
- }
-
- @Override
- public String toString() {
- return "MockResource [path=" + path + ", props=" + props + "]";
- }
-
}
diff --git a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java b/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
index 7b80e2f..a8ed2f5 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockResource.java
@@ -32,17 +32,19 @@ public class MockResource extends AbstractResource {
private final String path;
- private final Map<String, Object> props;
+ private final ValueMap props;
private final ResourceMetadata rm = new ResourceMetadata();
private final ResourceResolver resolver;
+ static final String JCR_PRIMARYTYPE = "jcr:primaryType";
+
public MockResource(final String path,
final Map<String, Object> props,
final ResourceResolver resolver) {
this.path = path;
- this.props = props;
+ this.props = (props instanceof MockValueMap) ? (MockValueMap)props : new MockValueMap(props);
this.resolver = resolver;
}
@@ -53,12 +55,17 @@ public class MockResource extends AbstractResource {
@Override
public String getResourceType() {
- return (String)this.props.get(ResourceResolver.PROPERTY_RESOURCE_TYPE);
+ String resourceType = this.props.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class);
+ if (resourceType == null) {
+ // fallback to jcr:primaryType if not resouce type exists (to mimick JCR resource behavior)
+ resourceType = this.props.get(JCR_PRIMARYTYPE, String.class);
+ }
+ return resourceType;
}
@Override
public String getResourceSuperType() {
- return (String)this.props.get("sling:resourceSuperType");
+ return this.props.get("sling:resourceSuperType", String.class);
}
@Override
@@ -85,7 +92,7 @@ public class MockResource extends AbstractResource {
@Override
public ValueMap getValueMap() {
- return new ValueMapDecorator(this.props);
+ return this.props;
}
@Override
diff --git a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
index 05e41c4..b5c4682 100644
--- a/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockResourceResolver.java
@@ -36,6 +36,8 @@ import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
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.resource.ValueMap;
import org.osgi.service.event.Event;
public class MockResourceResolver extends SlingAdaptable implements ResourceResolver {
@@ -86,6 +88,25 @@ public class MockResourceResolver extends SlingAdaptable implements ResourceReso
@Override
public Resource getResource(final String path) {
+ Resource resource = getResourceInternal(path);
+
+ // if not resource found check if this is a reference to a property
+ if (resource == null) {
+ String name = ResourceUtil.getName(path);
+ String parentPath = ResourceUtil.getParent(path);
+ Resource parentResource = getResourceInternal(parentPath);
+ if (parentResource!=null) {
+ ValueMap props = parentResource.getValueMap();
+ if (props.containsKey(name)) {
+ return new MockPropertyResource(path, props, this);
+ }
+ }
+ }
+
+ return resource;
+ }
+
+ private Resource getResourceInternal(final String path) {
if ( path.startsWith("/") ) {
if ( this.deletedResources.contains(path) ) {
return null;
@@ -186,7 +207,6 @@ public class MockResourceResolver extends SlingAdaptable implements ResourceReso
@Override
public ResourceResolver clone(Map<String, Object> authenticationInfo)
throws LoginException {
- // TODO Auto-generated method stub
return null;
}
@@ -202,7 +222,6 @@ public class MockResourceResolver extends SlingAdaptable implements ResourceReso
@Override
public String getUserID() {
- // TODO Auto-generated method stub
return null;
}
@@ -254,9 +273,10 @@ public class MockResourceResolver extends SlingAdaptable implements ResourceReso
if ( properties == null ) {
properties = new HashMap<String, Object>();
}
- this.temporaryResources.put(path, properties);
-
- return new MockResource(path, properties, this);
+
+ Resource mockResource = new MockResource(path, properties, this);
+ this.temporaryResources.put(path, mockResource.getValueMap());
+ return mockResource;
}
@Override
diff --git a/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java b/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java
new file mode 100644
index 0000000..4fe009a
--- /dev/null
+++ b/src/main/java/org/apache/sling/testing/resourceresolver/MockValueMap.java
@@ -0,0 +1,109 @@
+/*
+ * 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.sling.testing.resourceresolver;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+
+/**
+ * ValueMap for mocked resources to mimick JCR-like behavior.
+ * <p>Implements the following conversions:</p>
+ * <ul>
+ * <li>Converts all Date values to Calendar objects internally and vice versa.</li>
+ * <li>Converts InputStream to byte array and vice versa.</li>
+ * <ul>
+ */
+public class MockValueMap extends ValueMapDecorator {
+
+ public MockValueMap() {
+ this(new HashMap<String, Object>());
+ }
+
+ public MockValueMap(Map<String,Object> map) {
+ super(convertForWrite(map));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> T get(String name, Class<T> type) {
+ if (type==Date.class) {
+ Calendar calendar = super.get(name, Calendar.class);
+ if (calendar != null) {
+ return (T)calendar.getTime();
+ }
+ else {
+ return null;
+ }
+ }
+ else if (type==InputStream.class) {
+ byte[] data = super.get(name, byte[].class);
+ if (data!=null) {
+ return (T)new ByteArrayInputStream(data);
+ }
+ else {
+ return null;
+ }
+ }
+ return super.get(name, type);
+ }
+
+ @Override
+ public Object put(String key, Object value) {
+ return super.put(key, convertForWrite(value));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void putAll(Map<? extends String, ?> map) {
+ super.putAll((Map<? extends String, ?>)convertForWrite(map));
+ }
+
+ private static Object convertForWrite(Object value) {
+ if (value instanceof Date) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime((Date)value);
+ value = calendar;
+ }
+ else if (value instanceof InputStream) {
+ try {
+ value = IOUtils.toByteArray((InputStream)value);
+ } catch (IOException ex) {
+ throw new RuntimeException("Unable to convert input stream to byte array.");
+ }
+ }
+ return value;
+ }
+
+ private static Map<String, Object> convertForWrite(Map<String, Object> map) {
+ Map<String,Object> newMap = new HashMap<String, Object>();
+ for (Map.Entry<String, Object> entry : map.entrySet()) {
+ newMap.put(entry.getKey(), convertForWrite(entry.getValue()));
+ }
+ return newMap;
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java b/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
new file mode 100644
index 0000000..617773f
--- /dev/null
+++ b/src/test/java/org/apache/sling/testing/resourceresolver/SlingCrudResourceResolverTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.sling.testing.resourceresolver;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Implements simple write and read resource and values test
+ * Sling CRUD API is used to create the test data.
+ */
+public class SlingCrudResourceResolverTest {
+
+ private static final String STRING_VALUE = "value1";
+ private static final String[] STRING_ARRAY_VALUE = new String[] { "value1", "value2" };
+ private static final int INTEGER_VALUE = 25;
+ private static final double DOUBLE_VALUE = 3.555d;
+ private static final boolean BOOLEAN_VALUE = true;
+ private static final Date DATE_VALUE = new Date(10000);
+ private static final Calendar CALENDAR_VALUE = Calendar.getInstance();
+ private static final byte[] BINARY_VALUE = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+
+ private static final String NT_UNSTRUCTURED = "nt:unstructured";
+
+ private ResourceResolver resourceResolver;
+ protected Resource testRoot;
+
+ @Before
+ public final void setUp() throws IOException, LoginException {
+ this.resourceResolver = new MockResourceResolverFactory().getResourceResolver(null);
+
+ // prepare some test data using Sling CRUD API
+ Resource rootNode = getTestRootResource();
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(MockResource.JCR_PRIMARYTYPE, NT_UNSTRUCTURED);
+ props.put("stringProp", STRING_VALUE);
+ props.put("stringArrayProp", STRING_ARRAY_VALUE);
+ props.put("integerProp", INTEGER_VALUE);
+ props.put("doubleProp", DOUBLE_VALUE);
+ props.put("booleanProp", BOOLEAN_VALUE);
+ props.put("dateProp", DATE_VALUE);
+ props.put("calendarProp", CALENDAR_VALUE);
+ props.put("binaryProp", new ByteArrayInputStream(BINARY_VALUE));
+ Resource node1 = this.resourceResolver.create(rootNode, "node1", props);
+
+ this.resourceResolver.create(node1, "node11", ValueMap.EMPTY);
+ this.resourceResolver.create(node1, "node12", ValueMap.EMPTY);
+
+ this.resourceResolver.commit();
+ }
+
+ @After
+ public final void tearDown() {
+ this.testRoot = null;
+ }
+
+ /**
+ * Return a test root resource, created on demand, with a unique path
+ * @throws PersistenceException
+ */
+ private Resource getTestRootResource() throws PersistenceException {
+ if (this.testRoot == null) {
+ final Resource root = this.resourceResolver.getResource("/");
+ this.testRoot = this.resourceResolver.create(root, "test", ValueMap.EMPTY);
+ }
+ return this.testRoot;
+ }
+
+ @Test
+ public void testSimpleProperties() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ assertNotNull(resource1);
+ assertEquals("node1", resource1.getName());
+
+ ValueMap props = resource1.getValueMap();
+ assertEquals(STRING_VALUE, props.get("stringProp", String.class));
+ assertArrayEquals(STRING_ARRAY_VALUE, props.get("stringArrayProp", String[].class));
+ assertEquals((Integer) INTEGER_VALUE, props.get("integerProp", Integer.class));
+ assertEquals(DOUBLE_VALUE, props.get("doubleProp", Double.class), 0.0001);
+ assertEquals(BOOLEAN_VALUE, props.get("booleanProp", Boolean.class));
+ }
+
+ @Test
+ public void testDateProperty() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ ValueMap props = resource1.getValueMap();
+ assertEquals(DATE_VALUE, props.get("dateProp", Date.class));
+ }
+
+ @Test
+ public void testDatePropertyToCalendar() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ ValueMap props = resource1.getValueMap();
+ Calendar calendarValue = props.get("dateProp", Calendar.class);
+ assertNotNull(calendarValue);
+ assertEquals(DATE_VALUE, calendarValue.getTime());
+ }
+
+ @Test
+ public void testCalendarProperty() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ ValueMap props = resource1.getValueMap();
+ assertEquals(CALENDAR_VALUE.getTime(), props.get("calendarProp", Calendar.class).getTime());
+ }
+
+ @Test
+ public void testCalendarPropertyToDate() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ ValueMap props = resource1.getValueMap();
+ Date dateValue = props.get("calendarProp", Date.class);
+ assertNotNull(dateValue);
+ assertEquals(CALENDAR_VALUE.getTime(), dateValue);
+ }
+
+ @Test
+ public void testListChildren() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+
+ Iterator<Resource> children = resource1.listChildren();
+ assertEquals("node11", children.next().getName());
+ assertEquals("node12", children.next().getName());
+ assertFalse(children.hasNext());
+ }
+
+ @Test
+ public void testBinaryData() throws IOException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+
+ Resource binaryPropResource = resource1.getChild("binaryProp");
+ InputStream is = binaryPropResource.adaptTo(InputStream.class);
+ byte[] dataFromResource = IOUtils.toByteArray(is);
+ is.close();
+ assertArrayEquals(BINARY_VALUE, dataFromResource);
+
+ // read second time to ensure not the original input stream was returned
+ // and this time using another syntax
+ InputStream is2 = resource1.getValueMap().get("binaryProp", InputStream.class);
+ byte[] dataFromResource2 = IOUtils.toByteArray(is2);
+ is2.close();
+ assertArrayEquals(BINARY_VALUE, dataFromResource2);
+ }
+
+ @Test
+ public void testPrimaryTypeResourceType() throws PersistenceException {
+ Resource resource1 = this.resourceResolver.getResource(getTestRootResource().getPath() + "/node1");
+ assertEquals(NT_UNSTRUCTURED, resource1.getResourceType());
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.