blob: ebd290c5fdada33dd110ac3156a44c68a4e77a33 [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.jackrabbit.oak.jcr;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import javax.jcr.observation.ObservationManager;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.api.JackrabbitNode;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.test.AbstractJCRTest;
/**
* JackrabbitNodeTest: Copied and slightly adjusted from org.apache.jackrabbit.api.JackrabbitNodeTest,
* which used to create SNS for this test.
*/
public class JackrabbitNodeTest extends AbstractJCRTest {
static final String SEQ_BEFORE = "abcdefghij";
static final String SEQ_AFTER = "abcdefGhij";
static final int RELPOS = 6;
static final String TEST_NODETYPES = "org/apache/jackrabbit/oak/jcr/test_mixin_nodetypes.cnd";
@Override
protected void setUp() throws Exception {
super.setUp();
assertTrue(testRootNode.getPrimaryNodeType().hasOrderableChildNodes());
for (char c : SEQ_BEFORE.toCharArray()) {
testRootNode.addNode(new String(new char[]{c}));
}
superuser.save();
Reader cnd = new InputStreamReader(getClass().getClassLoader().getResourceAsStream(TEST_NODETYPES));
CndImporter.registerNodeTypes(cnd, superuser);
cnd.close();
}
//Ignore("OAK-3658")
public void _testRename() throws RepositoryException {
Node renamedNode = null;
NodeIterator it = testRootNode.getNodes();
int pos = 0;
while (it.hasNext()) {
Node n = it.nextNode();
String name = n.getName();
assertEquals(new String(new char[]{SEQ_BEFORE.charAt(pos)}), name);
if (pos == RELPOS) {
JackrabbitNode node = (JackrabbitNode) n;
node.rename(name.toUpperCase());
renamedNode = n;
}
pos++;
}
it = testRootNode.getNodes();
pos = 0;
while (it.hasNext()) {
Node n = it.nextNode();
String name = n.getName();
assertEquals(new String(new char[]{SEQ_AFTER.charAt(pos)}), name);
if (pos == RELPOS) {
assertTrue(n.isSame(renamedNode));
}
pos++;
}
}
//Ignore("OAK-3658")
public void _testRenameEventHandling() throws RepositoryException, InterruptedException {
Session s = getHelper().getSuperuserSession();
ObservationManager mgr = s.getWorkspace().getObservationManager();
final List<Event> events = newArrayList();
final CountDownLatch latch1 = new CountDownLatch(1);
final CountDownLatch latch2 = new CountDownLatch(1);
try {
mgr.addEventListener(new EventListener() {
CountDownLatch latch = latch1;
@Override
public void onEvent(EventIterator eventIterator) {
synchronized (events) {
while (eventIterator.hasNext()) {
events.add(eventIterator.nextEvent());
}
latch.countDown();
latch = latch2;
}
}
}, Event.PERSIST|Event.NODE_ADDED|Event.NODE_MOVED|Event.NODE_REMOVED, testRootNode.getPath(), true, null, null, false);
NodeIterator it = testRootNode.getNodes();
Node n = it.nextNode();
String name = n.getName();
JackrabbitNode node = (JackrabbitNode) n;
node.rename(name + 'X');
superuser.save();
StringBuilder diags = new StringBuilder();
if (!latch1.await(60, SECONDS)) {
diags.append("latch1 timed out ");
}
boolean foundMove = false;
synchronized (events) {
for (Event event : events) {
if (diags.length() != 0) {
diags.append(", ");
}
diags.append("type " + event.getType() + " " + event.getDate() + "ms " + event.getPath());
if (Event.NODE_MOVED == event.getType()) {
foundMove = true;
break;
}
}
if (events.isEmpty()) {
diags.append("none");
}
}
if (!foundMove) {
// force another event, wait some more
testRootNode.addNode(name + "XYZ");
superuser.save();
StringBuffer addDiags = new StringBuffer();
if (!latch2.await(60, SECONDS)) {
addDiags.append("latch2 timed out ");
}
synchronized (events) {
for (Event event : events) {
if (addDiags.length() != 0) {
addDiags.append(", ");
}
addDiags.append("type " + event.getType() + " " + event.getDate() + "ms " + event.getPath());
}
}
if (addDiags.length() > 0) {
diags.append("; next event after additional addNode/save operation: " + addDiags);
}
}
if (!foundMove) {
fail("Expected NODE_MOVED event upon renaming a node (received: " + diags + ")");
}
} finally {
s.logout();
}
}
/**
* @since oak 1.0
*/
public void testSetNewMixins() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
((JackrabbitNode) n).setMixins(new String[]{"test:AA", "test:A"});
superuser.save();
assertTrue(n.isNodeType("test:AA"));
assertTrue(n.isNodeType("test:A"));
assertTrue(n.hasProperty(JcrConstants.JCR_MIXINTYPES));
}
/**
* @since oak 1.0
*/
public void testSetNewMixins2() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
((JackrabbitNode) n).setMixins(new String[]{"test:A", "test:AA"});
superuser.save();
assertTrue(n.isNodeType("test:A"));
assertTrue(n.isNodeType("test:AA"));
assertTrue(n.hasProperty(JcrConstants.JCR_MIXINTYPES));
}
/**
* @since oak 1.0
*/
public void testSetEmptyMixins() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
n.addMixin("test:AA");
superuser.save();
((JackrabbitNode) n).setMixins(new String[0]);
superuser.save();
assertFalse(n.isNodeType("test:AA"));
assertTrue(n.hasProperty(JcrConstants.JCR_MIXINTYPES));
assertEquals(0, n.getProperty(JcrConstants.JCR_MIXINTYPES).getValues().length);
}
/**
* @since oak 1.0
*/
public void testSetRemoveMixins() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
((JackrabbitNode) n).setMixins(new String[]{"test:A", "test:AA"});
superuser.save();
((JackrabbitNode) n).setMixins(new String[]{"test:A"});
superuser.save();
assertTrue(n.isNodeType("test:A"));
assertFalse(n.isNodeType("test:AA"));
}
/**
* @since oak 1.0
*/
public void testUpdateMixins() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
((JackrabbitNode) n).setMixins(new String[]{"test:A", "test:AA"});
superuser.save();
assertTrue(n.isNodeType("test:AA"));
assertTrue(n.isNodeType("test:A"));
((JackrabbitNode) n).setMixins(new String[]{"test:A", "test:AA", JcrConstants.MIX_REFERENCEABLE});
superuser.save();
assertTrue(n.isNodeType("test:AA"));
assertTrue(n.isNodeType("test:A"));
assertTrue(n.isNodeType(JcrConstants.MIX_REFERENCEABLE));
assertTrue(n.hasProperty(JcrConstants.JCR_UUID));
((JackrabbitNode) n).setMixins(new String[]{JcrConstants.MIX_REFERENCEABLE});
superuser.save();
assertFalse(n.isNodeType("test:AA"));
assertFalse(n.isNodeType("test:A"));
assertTrue(n.isNodeType(JcrConstants.MIX_REFERENCEABLE));
assertTrue(n.hasProperty(JcrConstants.JCR_UUID));
}
public void testSetMixins() throws RepositoryException {
// create node with mixin test:AA
Node n = testRootNode.addNode("foo", "nt:folder");
n.addMixin("test:AA");
n.setProperty("test:propAA", "AA");
n.setProperty("test:propA", "A");
superuser.save();
// 'downgrade' from test:AA to test:A
((JackrabbitNode) n).setMixins(new String[]{"test:A"});
superuser.save();
assertTrue(n.hasProperty("test:propA"));
assertFalse(n.hasProperty("test:propAA"));
// 'upgrade' from test:A to test:AA
((JackrabbitNode) n).setMixins(new String[]{"test:AA"});
n.setProperty("test:propAA", "AA");
superuser.save();
assertTrue(n.hasProperty("test:propA"));
assertTrue(n.hasProperty("test:propAA"));
// replace test:AA with mix:title
((JackrabbitNode) n).setMixins(new String[]{"mix:title"});
n.setProperty("jcr:title", "...");
n.setProperty("jcr:description", "blah blah");
superuser.save();
assertTrue(n.hasProperty("jcr:title"));
assertTrue(n.hasProperty("jcr:description"));
assertFalse(n.hasProperty("test:propA"));
assertFalse(n.hasProperty("test:propAA"));
// clean up
n.remove();
superuser.save();
}
}