use of javax.jcr.observation.ObservationManager in project jackrabbit-oak by apache.
the class ObservationTest method addRootListener.
private void addRootListener(Repository repository, List<Session> sessions, List<EventListener> listeners) throws RepositoryException {
Session s = createSession(repository);
sessions.add(s);
Listener listener = new Listener(new AtomicInteger());
ObservationManager obsMgr = s.getWorkspace().getObservationManager();
obsMgr.addEventListener(listener, EVENT_TYPES, "/", true, null, null, false);
listeners.add(listener);
}
use of javax.jcr.observation.ObservationManager in project jackrabbit by apache.
the class Locked method with.
/**
* Executes the method {@link #run} within the scope of a lock held on
* <code>lockable</code>.
*
* @param lockable the node where the lock is obtained from.
* @param isDeep <code>true</code> if <code>lockable</code> will be locked
* deep.
* @param timeout time in milliseconds to wait at most to acquire the lock.
* @param isSessionScoped <code>true</code> if the lock is session scoped.
* @return the object returned by {@link #run} or {@link #TIMED_OUT} if the
* lock on <code>lockable</code> could not be acquired within the
* specified timeout.
* @throws IllegalArgumentException if <code>timeout</code> is negative or
* <code>lockable</code> is not
* <i>mix:lockable</i>.
* @throws RepositoryException if {@link #run} throws an exception.
* @throws UnsupportedRepositoryOperationException
* if this repository does not support
* locking.
* @throws InterruptedException if this thread is interrupted while
* waiting for the lock on node
* <code>lockable</code>.
*/
public Object with(Node lockable, boolean isDeep, long timeout, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be >= 0");
}
Session session = lockable.getSession();
EventListener listener = null;
try {
// check whether the lockable can be locked at all
String mix = session.getNamespacePrefix(MIX);
if (!lockable.isNodeType(mix + ":lockable")) {
throw new IllegalArgumentException("Node is not lockable");
}
Lock lock = tryLock(lockable, isDeep, timeout, isSessionScoped);
if (lock != null) {
return runAndUnlock(lock);
}
if (timeout == 0) {
return TIMED_OUT;
}
long timelimit;
if (timeout == Long.MAX_VALUE) {
timelimit = Long.MAX_VALUE;
} else {
timelimit = System.currentTimeMillis() + timeout;
}
// node is locked by other session -> register event listener if possible
if (isObservationSupported(session)) {
ObservationManager om = session.getWorkspace().getObservationManager();
listener = new EventListener() {
public void onEvent(EventIterator events) {
synchronized (Locked.this) {
Locked.this.notify();
}
}
};
om.addEventListener(listener, Event.PROPERTY_REMOVED, lockable.getPath(), false, null, null, true);
}
// the current thread when the lockable node is possibly unlocked
for (; ; ) {
synchronized (this) {
lock = tryLock(lockable, isDeep, timeout, isSessionScoped);
if (lock != null) {
return runAndUnlock(lock);
} else {
// check timeout
if (System.currentTimeMillis() > timelimit) {
return TIMED_OUT;
}
if (listener != null) {
// event listener *should* wake us up, however
// there is a chance that removal of the lockOwner
// property is notified before the node is acutally
// unlocked. therefore we use a safety net to wait
// at most 1000 millis.
this.wait(Math.min(1000, timeout));
} else {
// repository does not support observation
// wait at most 50 millis then retry
this.wait(Math.min(50, timeout));
}
}
}
}
} finally {
if (listener != null) {
session.getWorkspace().getObservationManager().removeEventListener(listener);
}
}
}
use of javax.jcr.observation.ObservationManager in project jackrabbit by apache.
the class Locked method with.
/**
* Executes the method {@link #run} within the scope of a lock held on
* <code>lockable</code>.
*
* @param lockable the node where the lock is obtained from.
* @param isDeep <code>true</code> if <code>lockable</code> will be locked
* deep.
* @param timeout time in milliseconds to wait at most to aquire the lock.
* @return the object returned by {@link #run} or {@link #TIMED_OUT} if the
* lock on <code>lockable</code> could not be aquired within the
* specified timeout.
* @throws IllegalArgumentException if <code>timeout</code> is negative or
* <code>lockable</code> is not
* <i>mix:lockable</i>.
* @throws RepositoryException if {@link #run} throws an exception.
* @throws UnsupportedRepositoryOperationException
* if this repository does not support
* locking.
* @throws InterruptedException if this thread is interrupted while
* waiting for the lock on node
* <code>lockable</code>.
*/
public Object with(Node lockable, boolean isDeep, long timeout) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must be >= 0");
}
Session session = lockable.getSession();
NamePathResolver resolver = new DefaultNamePathResolver(session);
Lock lock;
EventListener listener = null;
try {
// check whether the lockable can be locked at all
if (!lockable.isNodeType(resolver.getJCRName(NameConstants.MIX_LOCKABLE))) {
throw new IllegalArgumentException("Node is not lockable");
}
lock = tryLock(lockable, isDeep);
if (lock != null) {
return runAndUnlock(lock);
}
if (timeout == 0) {
return TIMED_OUT;
}
long timelimit;
if (timeout == Long.MAX_VALUE) {
timelimit = Long.MAX_VALUE;
} else {
timelimit = System.currentTimeMillis() + timeout;
}
// node is locked by other session -> register event listener if possible
if (isObservationSupported(session)) {
ObservationManager om = session.getWorkspace().getObservationManager();
listener = new EventListener() {
public void onEvent(EventIterator events) {
synchronized (this) {
this.notify();
}
}
};
om.addEventListener(listener, Event.PROPERTY_REMOVED, lockable.getPath(), false, null, null, true);
}
// the current thread when the lockable node is possibly unlocked
for (; ; ) {
synchronized (this) {
lock = tryLock(lockable, isDeep);
if (lock != null) {
return runAndUnlock(lock);
} else {
// check timeout
if (System.currentTimeMillis() > timelimit) {
return TIMED_OUT;
}
if (listener != null) {
// event listener *should* wake us up, however
// there is a chance that removal of the lockOwner
// property is notified before the node is acutally
// unlocked. therefore we use a safety net to wait
// at most 1000 millis.
this.wait(Math.min(1000, timeout));
} else {
// repository does not support observation
// wait at most 50 millis then retry
this.wait(Math.min(50, timeout));
}
}
}
}
} catch (NameException e) {
throw new RepositoryException(e);
} finally {
if (listener != null) {
session.getWorkspace().getObservationManager().removeEventListener(listener);
}
}
}
use of javax.jcr.observation.ObservationManager in project jackrabbit by apache.
the class EntryCollector method close.
/**
* Release all resources contained by this instance. It will no longer be
* used. This implementation only stops listening to ac modification events.
*/
@Override
protected void close() {
super.close();
try {
ObservationManager observationMgr = systemSession.getWorkspace().getObservationManager();
observationMgr.removeEventListener(this);
observationMgr.removeEventListener(moveListener);
} catch (RepositoryException e) {
log.error("Unexpected error while closing CachingEntryCollector", e);
}
}
use of javax.jcr.observation.ObservationManager in project jackrabbit-oak by apache.
the class JackrabbitNodeTest method _testRenameEventHandling.
//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();
}
}
Aggregations