blob: 4b870af6eb3ddfef6154e1fc17c555c060215641 [file] [log] [blame]
/*
* 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.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.resource.api.JcrResourceConstants;
import org.apache.sling.jcr.resource.internal.HelperData;
public class JcrNodeResourceTest extends JcrItemResourceTestBase {
private HelperData getHelperData() {
return new HelperData(new AtomicReference<>(), new AtomicReference<>());
}
public void testLinkedFile() throws Exception {
String fileName = "file";
String linkedFileName = "linkedFile";
Session session = getSession();
Node file = rootNode.addNode(fileName, JcrConstants.NT_FILE);
Node res = file.addNode(JcrConstants.JCR_CONTENT, JcrConstants.NT_RESOURCE);
setupResource(res);
file.addMixin(JcrConstants.MIX_REFERENCEABLE);
session.save();
Node linkedFile = rootNode.addNode(linkedFileName, JcrConstants.NT_LINKEDFILE);
linkedFile.setProperty(JcrConstants.JCR_CONTENT, file);
session.save();
JcrNodeResource linkedFileResource = new JcrNodeResource(null, linkedFile.getPath(), null, linkedFile, getHelperData());
assertEquals(TEST_DATA, linkedFileResource.adaptTo(InputStream.class));
}
public void testNtFileNtResource() throws Exception {
String name = "file";
Node file = rootNode.addNode(name, JcrConstants.NT_FILE);
Node res = file.addNode(JcrConstants.JCR_CONTENT,
JcrConstants.NT_RESOURCE);
setupResource(res);
getSession().save();
file = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, file.getPath(), null, file, getHelperData());
assertEquals(file.getPath(), jnr.getPath());
assertResourceMetaData(jnr.getResourceMetadata());
assertEquals(TEST_DATA, jnr.adaptTo(InputStream.class));
}
public void testNtFileNtUnstructured() throws Exception {
String name = "fileunstructured";
Node file = rootNode.addNode(name, JcrConstants.NT_FILE);
Node res = file.addNode(JcrConstants.JCR_CONTENT,
JcrConstants.NT_UNSTRUCTURED);
setupResource(res);
getSession().save();
file = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, file.getPath(), null, file, getHelperData());
assertEquals(file.getPath(), jnr.getPath());
assertResourceMetaData(jnr.getResourceMetadata());
assertEquals(TEST_DATA, jnr.adaptTo(InputStream.class));
}
public void testNtResource() throws Exception {
String name = "resource";
Node res = rootNode.addNode(name, JcrConstants.NT_RESOURCE);
setupResource(res);
getSession().save();
res = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, res.getPath(), null, res, getHelperData());
assertEquals(res.getPath(), jnr.getPath());
assertResourceMetaData(jnr.getResourceMetadata());
assertEquals(TEST_DATA, jnr.adaptTo(InputStream.class));
}
public void testNtUnstructured() throws Exception {
String name = "unstructured";
Node res = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
setupResource(res);
getSession().save();
res = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, res.getPath(), null, res, getHelperData());
assertEquals(res.getPath(), jnr.getPath());
assertResourceMetaData(jnr.getResourceMetadata());
assertEquals(TEST_DATA, jnr.adaptTo(InputStream.class));
}
public void testResourceType() throws Exception {
String name = "resourceType";
Node node = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
getSession().save();
JcrNodeResource jnr = new JcrNodeResource(null, node.getPath(), null, node, getHelperData());
assertEquals(JcrConstants.NT_UNSTRUCTURED, jnr.getResourceType());
String typeName = "some/resource/type";
node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, typeName);
getSession().save();
jnr = new JcrNodeResource(null, node.getPath(), null, node, getHelperData());
assertEquals(typeName, jnr.getResourceType());
}
public void testResourceSuperType() throws Exception {
String name = "resourceSuperType";
String typeNodeName = "some_resource_type";
String typeName = rootPath + "/" + typeNodeName;
Node node = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
node.setProperty(JcrResourceConstants.SLING_RESOURCE_TYPE_PROPERTY, typeName);
getSession().save();
Resource jnr = new JcrNodeResource(null, node.getPath(), null, node, getHelperData());
assertEquals(typeName, jnr.getResourceType());
// default super type is null
assertNull(jnr.getResourceSuperType());
String superTypeName = "supertype";
Node typeNode = rootNode.addNode(typeNodeName, JcrConstants.NT_UNSTRUCTURED);
typeNode.setProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, superTypeName);
getSession().save();
jnr = new JcrNodeResource(null, typeNode.getPath(), null, typeNode, getHelperData());
assertEquals(JcrConstants.NT_UNSTRUCTURED, jnr.getResourceType());
assertEquals(superTypeName, jnr.getResourceSuperType());
// overwrite super type with direct property
String otherSuperTypeName = "othersupertype";
node.setProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY, otherSuperTypeName);
getSession().save();
jnr = new JcrNodeResource(null, node.getPath(), null, node, getHelperData());
assertEquals(typeName, jnr.getResourceType());
assertEquals(otherSuperTypeName, jnr.getResourceSuperType());
// remove direct property to get supertype again
node.getProperty(JcrResourceConstants.SLING_RESOURCE_SUPER_TYPE_PROPERTY).remove();
getSession().save();
jnr = new JcrNodeResource(null, node.getPath(), null, node, getHelperData());
assertEquals(typeName, jnr.getResourceType());
assertNull(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.getPath(), null, res, getHelperData());
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<>();
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<>(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<>(propsSecond.keySet());
crossCheck2.removeAll(existingKeys);
assertTrue(crossCheck2.isEmpty());
}
public void testCorrectUTF8ByteLength() throws Exception {
byte[] utf8bytes = "Übersättigung".getBytes(StandardCharsets.UTF_8);
String name = "utf8file";
Node file = rootNode.addNode(name, JcrConstants.NT_FILE);
Node res = file.addNode(JcrConstants.JCR_CONTENT,
JcrConstants.NT_RESOURCE);
res.setProperty(JcrConstants.JCR_LASTMODIFIED, TEST_MODIFIED);
res.setProperty(JcrConstants.JCR_MIMETYPE, TEST_TYPE);
res.setProperty(JcrConstants.JCR_ENCODING, "UTF-8");
res.setProperty(JcrConstants.JCR_DATA, new ByteArrayInputStream(utf8bytes));
getSession().save();
file = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, file.getPath(), null, file, getHelperData());
assertEquals(utf8bytes, jnr.adaptTo(InputStream.class));
assertEquals(utf8bytes.length, jnr.getResourceMetadata().getContentLength());
}
private void setupResource(Node res) throws RepositoryException {
res.setProperty(JcrConstants.JCR_LASTMODIFIED, TEST_MODIFIED);
res.setProperty(JcrConstants.JCR_MIMETYPE, TEST_TYPE);
res.setProperty(JcrConstants.JCR_ENCODING, TEST_ENCODING);
res.setProperty(JcrConstants.JCR_DATA, new ByteArrayInputStream(
TEST_DATA));
}
private void assertResourceMetaData(ResourceMetadata rm) {
assertNotNull(rm);
assertEquals(TEST_MODIFIED, rm.getModificationTime());
assertEquals(TEST_TYPE, rm.getContentType());
assertEquals(TEST_ENCODING, rm.getCharacterEncoding());
}
public void testAdaptToValueMap() throws Exception {
final String name = "adaptablevm";
Node res = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
setupResource(res);
getSession().save();
res = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, res.getPath(), null, res, getHelperData());
final ValueMap props = jnr.adaptTo(ValueMap.class);
assertFalse(props instanceof ModifiableValueMap);
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));
try {
props.remove(JcrConstants.JCR_MIMETYPE);
fail();
} catch (final UnsupportedOperationException uoe) {
// expected
}
try {
props.put(JcrConstants.JCR_MIMETYPE, "all");
fail();
} catch (final UnsupportedOperationException uoe) {
// expected
}
try {
props.putAll(Collections.singletonMap(JcrConstants.JCR_MIMETYPE, "value"));
fail();
} catch (final UnsupportedOperationException uoe) {
// expected
}
}
public void testAdaptToModifiableValueMap() throws Exception {
final String name = "adaptablemvm";
Node res = rootNode.addNode(name, JcrConstants.NT_UNSTRUCTURED);
setupResource(res);
getSession().save();
res = rootNode.getNode(name);
JcrNodeResource jnr = new JcrNodeResource(null, res.getPath(), null, res, getHelperData());
final ModifiableValueMap props = jnr.adaptTo(ModifiableValueMap.class);
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));
props.remove(JcrConstants.JCR_MIMETYPE);
props.put(JcrConstants.JCR_MIMETYPE, "all");
props.putAll(Collections.singletonMap(JcrConstants.JCR_MIMETYPE, "value"));
}
}