You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/04/30 16:15:29 UTC
svn commit: r652385 - in /incubator/sling/trunk/jcr/resource/src:
main/java/org/apache/sling/jcr/resource/
main/java/org/apache/sling/jcr/resource/internal/helper/jcr/
test/java/org/apache/sling/jcr/resource/internal/helper/jcr/
Author: fmeschbe
Date: Wed Apr 30 07:15:28 2008
New Revision: 652385
URL: http://svn.apache.org/viewvc?rev=652385&view=rev
Log:
SLING-395 Implement JcrNodeResource.adaptTo(Map.class) returning a map of
the node's properties converted to Java Objects.
Added:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyMap.java
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java
incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java?rev=652385&r1=652384&r2=652385&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrResourceUtil.java Wed Apr 30 07:15:28 2008
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.resource;
+import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -76,6 +77,30 @@
}
/**
+ * Converts the value(s) of a JCR Property to a corresponding Java Object.
+ * If the property has multiple values the result is an array of Java
+ * Objects representing the converted values of the property.
+ */
+ public static Object toJavaObject(Property property)
+ throws RepositoryException {
+ // multi-value property: return an array of values
+ if (property.getDefinition().isMultiple()) {
+ Value[] values = property.getValues();
+ Object[] result = new Object[values.length];
+ for (int i = 0; i < values.length; i++) {
+ Value value = values[i];
+ if (value != null) {
+ result[i] = toJavaObject(value);
+ }
+ }
+ return result;
+ }
+
+ // single value property
+ return toJavaObject(property.getValue());
+ }
+
+ /**
* Resolves relative path segments '.' and '..' in the absolute path.
* Returns null if not possible (.. points above root) or if path is not
* absolute.
Modified: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java?rev=652385&r1=652384&r2=652385&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java (original)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.java Wed Apr 30 07:15:28 2008
@@ -28,6 +28,7 @@
import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Map;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
@@ -53,9 +54,8 @@
private final String resourceType;
- JcrNodeResource(ResourceResolver resourceResolver,
- Node node,
- JcrResourceTypeProvider[] resourceTypeProviders)
+ JcrNodeResource(ResourceResolver resourceResolver, Node node,
+ JcrResourceTypeProvider[] resourceTypeProviders)
throws RepositoryException {
super(resourceResolver, node.getPath(), resourceTypeProviders);
this.node = node;
@@ -77,6 +77,8 @@
return (Type) getInputStream(); // unchecked cast
} else if (type == URL.class) {
return (Type) getURL(); // unchecked cast
+ } else if (type == Map.class) {
+ return (Type) new JcrPropertyMap(getNode()); // unchecked cast
}
// fall back to default implementation
@@ -97,9 +99,8 @@
/**
* Returns a stream to the <em>jcr:data</em> property if the
* {@link #getNode() node} is an <em>nt:file</em> or <em>nt:resource</em>
- * node. Otherwise returns <code>null</code>.
- * If a valid stream can be returned, this method also sets the
- * content length resource metadata.
+ * node. Otherwise returns <code>null</code>. If a valid stream can be
+ * returned, this method also sets the content length resource metadata.
*/
private InputStream getInputStream() {
// implement this for nt:file only
@@ -140,7 +141,7 @@
// binary property which could cause performance loss
// for all resources that do need to provide the stream
long length = data.getLength();
- InputStream stream = data.getStream();
+ InputStream stream = data.getStream();
getResourceMetadata().setContentLength(length);
return stream;
Added: incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyMap.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyMap.java?rev=652385&view=auto
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyMap.java (added)
+++ incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrPropertyMap.java Wed Apr 30 07:15:28 2008
@@ -0,0 +1,154 @@
+/*
+ * 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.jcr.resource.internal.helper.jcr;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.jcr.resource.JcrResourceUtil;
+
+class JcrPropertyMap implements Map<String, Object> {
+
+ private final Node node;
+
+ private final Map<String, Object> cache;
+
+ private boolean fullyRead;
+
+ JcrPropertyMap(Node node) {
+ this.node = node;
+ this.cache = new HashMap<String, Object>();
+ this.fullyRead = false;
+ }
+
+ public Object get(Object key) {
+ Object value = cache.get(key);
+ if (value == null) {
+ value = read((String) key);
+ }
+
+ return value;
+ }
+
+ public boolean containsKey(Object key) {
+ return get(key) != null;
+ }
+
+ public boolean containsValue(Object value) {
+ readFully();
+ return cache.containsValue(value);
+ }
+
+ public boolean isEmpty() {
+ if (cache.isEmpty()) {
+ readFully();
+ }
+
+ return cache.isEmpty();
+ }
+
+ public int size() {
+ readFully();
+ return cache.size();
+ }
+
+ public Set<java.util.Map.Entry<String, Object>> entrySet() {
+ readFully();
+ return cache.entrySet();
+ }
+
+ public Set<String> keySet() {
+ readFully();
+ return cache.keySet();
+ }
+
+ public Collection<Object> values() {
+ readFully();
+ return cache.values();
+ }
+
+ // ---------- Helpers to access the node's property ------------------------
+
+ private Object read(String key) {
+
+ // if the node has been completely read, we need not check
+ // again, as we certainly will not find the key
+ if (fullyRead) {
+ return null;
+ }
+
+ try {
+ if (node.hasProperty(key)) {
+ Property prop = node.getProperty(key);
+ Object value = JcrResourceUtil.toJavaObject(prop);
+ cache.put(key, value);
+ return value;
+ }
+ } catch (RepositoryException re) {
+ // TODO: log !!
+ }
+
+ // property not found or some error accessing it
+ return null;
+ }
+
+ private void readFully() {
+ if (!fullyRead) {
+ try {
+ PropertyIterator pi = node.getProperties();
+ while (pi.hasNext()) {
+ Property prop = pi.nextProperty();
+ String key = prop.getName();
+ if (!cache.containsKey(key)) {
+ cache.put(key, JcrResourceUtil.toJavaObject(prop));
+ }
+ }
+ fullyRead = true;
+ } catch (RepositoryException re) {
+ // TODO: log !!
+ }
+ }
+ }
+
+ // ---------- Unsupported Modification methods -----------------------------
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object put(String key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void putAll(Map<? extends String, ? extends Object> t) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+}
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java?rev=652385&r1=652384&r2=652385&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResourceTestBase.java Wed Apr 30 07:15:28 2008
@@ -76,7 +76,7 @@
protected void assertEquals(byte[] expected, InputStream actual)
throws IOException {
if (actual == null) {
- fail("Rsource stream is null");
+ fail("Resource stream is null");
} else {
try {
for (byte b : expected) {
Modified: incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java?rev=652385&r1=652384&r2=652385&view=diff
==============================================================================
--- incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java (original)
+++ incubator/sling/trunk/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResourceTest.java Wed Apr 30 07:15:28 2008
@@ -20,6 +20,9 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
@@ -156,6 +159,66 @@
assertEquals(superTypeName, jnr.getResourceSuperType());
}
+ public void testAdaptToMap() throws Exception {
+
+ String name = "adaptable";
+ Node res = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
+ setupResource(res);
+ getSession().save();
+
+ res = rootNode.getNode(name);
+ JcrNodeResource jnr = new JcrNodeResource(null, res, null);
+
+ final Map<?, ?> props = jnr.adaptTo(Map.class);
+
+ // assert we have properties at all, only fails if property
+ // retrieval fails for any reason
+ assertNotNull(props);
+ assertFalse(props.isEmpty());
+
+ // assert all properties set up
+ assertEquals(TEST_MODIFIED, props.get(JcrConstants.JCR_LASTMODIFIED));
+ assertEquals(TEST_TYPE, props.get(JcrConstants.JCR_MIMETYPE));
+ assertEquals(TEST_ENCODING, props.get(JcrConstants.JCR_ENCODING));
+ assertEquals(TEST_DATA, (InputStream) props.get(JcrConstants.JCR_DATA));
+
+ // assert JCR managed properties
+ assertEquals(JcrConstants.NT_UNSTRUCTURED, props.get(JcrConstants.JCR_PRIMARYTYPE));
+
+ // assert we have nothing else left
+ final Set<String> existingKeys = new HashSet<String>();
+ existingKeys.add(JcrConstants.JCR_LASTMODIFIED);
+ existingKeys.add(JcrConstants.JCR_MIMETYPE);
+ existingKeys.add(JcrConstants.JCR_ENCODING);
+ existingKeys.add(JcrConstants.JCR_DATA);
+ existingKeys.add(JcrConstants.JCR_PRIMARYTYPE);
+ final Set<Object> crossCheck = new HashSet<Object>(props.keySet());
+ crossCheck.removeAll(existingKeys);
+ assertTrue(crossCheck.isEmpty());
+
+ // call a second time, ensure the map contains the same data again
+ final Map<?, ?> propsSecond = jnr.adaptTo(Map.class);
+
+ // assert we have properties at all, only fails if property
+ // retrieval fails for any reason
+ assertNotNull(propsSecond);
+ assertFalse(propsSecond.isEmpty());
+
+ // assert all properties set up
+ assertEquals(TEST_MODIFIED, propsSecond.get(JcrConstants.JCR_LASTMODIFIED));
+ assertEquals(TEST_TYPE, propsSecond.get(JcrConstants.JCR_MIMETYPE));
+ assertEquals(TEST_ENCODING, propsSecond.get(JcrConstants.JCR_ENCODING));
+ assertEquals(TEST_DATA, (InputStream) propsSecond.get(JcrConstants.JCR_DATA));
+
+ // assert JCR managed properties
+ assertEquals(JcrConstants.NT_UNSTRUCTURED, propsSecond.get(JcrConstants.JCR_PRIMARYTYPE));
+
+ // assert we have nothing else left
+ final Set<Object> crossCheck2 = new HashSet<Object>(propsSecond.keySet());
+ crossCheck2.removeAll(existingKeys);
+ assertTrue(crossCheck2.isEmpty());
+ }
+
private void setupResource(Node res) throws RepositoryException {
res.setProperty(JcrConstants.JCR_LASTMODIFIED, TEST_MODIFIED);
res.setProperty(JcrConstants.JCR_MIMETYPE, TEST_TYPE);
@@ -172,4 +235,13 @@
assertEquals(TEST_ENCODING, rm.getCharacterEncoding());
}
+ private void assertProperty(Object expected, Object actual) {
+ if (expected != null) {
+ assertNotNull(actual);
+
+ assertEquals(expected, actual);
+ } else {
+ assertNull(actual);
+ }
+ }
}