Search in sources :

Example 1 with ObservationManager

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);
}
Also used : EventListener(javax.jcr.observation.EventListener) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ObservationManager(javax.jcr.observation.ObservationManager) Session(javax.jcr.Session)

Example 2 with ObservationManager

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);
        }
    }
}
Also used : ObservationManager(javax.jcr.observation.ObservationManager) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 3 with ObservationManager

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);
        }
    }
}
Also used : NamePathResolver(org.apache.jackrabbit.spi.commons.conversion.NamePathResolver) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) ObservationManager(javax.jcr.observation.ObservationManager) RepositoryException(javax.jcr.RepositoryException) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 4 with ObservationManager

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);
    }
}
Also used : ObservationManager(javax.jcr.observation.ObservationManager) RepositoryException(javax.jcr.RepositoryException)

Example 5 with ObservationManager

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();
    }
}
Also used : NodeIterator(javax.jcr.NodeIterator) JackrabbitNode(org.apache.jackrabbit.api.JackrabbitNode) JackrabbitNode(org.apache.jackrabbit.api.JackrabbitNode) Node(javax.jcr.Node) ObservationManager(javax.jcr.observation.ObservationManager) CountDownLatch(java.util.concurrent.CountDownLatch) Event(javax.jcr.observation.Event) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session)

Aggregations

ObservationManager (javax.jcr.observation.ObservationManager)29 Session (javax.jcr.Session)16 Event (javax.jcr.observation.Event)13 Test (org.junit.Test)11 EventListener (javax.jcr.observation.EventListener)10 Node (javax.jcr.Node)8 RepositoryException (javax.jcr.RepositoryException)8 EventIterator (javax.jcr.observation.EventIterator)8 Workspace (javax.jcr.Workspace)6 EventResult (org.apache.jackrabbit.test.api.observation.EventResult)6 ArrayList (java.util.ArrayList)4 DistributionRequest (org.apache.sling.distribution.DistributionRequest)3 HashSet (java.util.HashSet)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Future (java.util.concurrent.Future)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 NodeIterator (javax.jcr.NodeIterator)2 Lock (javax.jcr.lock.Lock)2 JackrabbitEvent (org.apache.jackrabbit.api.observation.JackrabbitEvent)2 ImportMode (org.apache.jackrabbit.vault.fs.api.ImportMode)2