/*
* 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.jcr2spi.observation;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.observation.EventListener;
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ObservationTest extends AbstractJCRTest {
private static Logger log = LoggerFactory.getLogger(ObservationTest.class);
private Node testNode;
@Override
protected void setUp() throws Exception {
super.setUp();
testNode = testRootNode.addNode(nodeName1);
testRootNode.save();
}
@Override
protected void tearDown() throws Exception {
testNode = null;
super.tearDown();
}
interface WaitableEventListener extends EventListener {
public void waitForEvent(int timeout) throws InterruptedException, RepositoryException;
}
/**
* Check whether an item with the path of an add node event exists.
* Regression test for JCR-2293.
* @throws RepositoryException
* @throws InterruptedException
*/
public void testJCR_2293() throws RepositoryException, InterruptedException {
final String parentPath = testNode.getPath();
final String folderName = "folder_" + System.currentTimeMillis();
final Session session = getHelper().getReadWriteSession();
final Session session2 = getHelper().getReadOnlySession();
session2.getItem(parentPath); // Don't remove. See JCR-2293.
WaitableEventListener eventListener = new WaitableEventListener() {
private RepositoryException failure;
private boolean done;
public synchronized void onEvent(final EventIterator events) {
try {
while (events.hasNext()) {
Event event = events.nextEvent();
Item item2 = session2.getItem(event.getPath());
assertEquals(parentPath + "/" + folderName, item2.getPath());
}
}
catch (RepositoryException e) {
failure = e;
}
finally {
done = true;
notifyAll();
}
}
public synchronized void waitForEvent(int timeout) throws InterruptedException, RepositoryException {
if (!done) {
wait(timeout);
}
if (!done) {
fail("Event listener not called");
}
if (failure != null) {
throw failure;
}
}
};
session2.getWorkspace().getObservationManager()
.addEventListener(eventListener, Event.NODE_ADDED,
parentPath, true, null, null, false);
Node parent = (Node) session.getItem(parentPath);
Node toDelete = parent.addNode(folderName, "nt:folder");
parent.save();
try {
eventListener.waitForEvent(60000);
}
finally {
toDelete.remove();
parent.save();
assertFalse(parent.hasNode(folderName));
}
}
}