Search in sources :

Example 6 with EventListener

use of javax.jcr.observation.EventListener 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 7 with EventListener

use of javax.jcr.observation.EventListener in project jackrabbit by apache.

the class EventListenerIteratorImpl method nextEventListener.

/**
     * {@inheritDoc}
     */
public EventListener nextEventListener() {
    if (next == null) {
        throw new NoSuchElementException();
    }
    EventListener l = next;
    fetchNext();
    pos++;
    return l;
}
Also used : EventListener(javax.jcr.observation.EventListener) NoSuchElementException(java.util.NoSuchElementException)

Example 8 with EventListener

use of javax.jcr.observation.EventListener in project jackrabbit by apache.

the class ListenerTracker method getTrackedListener.

public EventListener getTrackedListener() {
    return new EventListener() {

        @Override
        public void onEvent(EventIterator events) {
            eventDeliveries.incrementAndGet();
            final long start = nanoTime();
            try {
                beforeEventDelivery();
                listener.onEvent(new EventIteratorAdapter(events) {

                    long t0 = start;

                    private void recordTime(TimeSeriesRecorder recorder) {
                        recorder.getCounter().addAndGet(-(t0 - (t0 = nanoTime())));
                    }

                    @Override
                    public Object next() {
                        recordTime(eventConsumerTime);
                        eventsDelivered.incrementAndGet();
                        eventCount.getCounter().incrementAndGet();
                        Object object = super.next();
                        if (object instanceof JackrabbitEvent) {
                            object = new JackrabbitEventTracker(ListenerTracker.this, (JackrabbitEvent) object);
                        } else if (object instanceof Event) {
                            object = new EventTracker(ListenerTracker.this, (Event) object);
                        }
                        recordTime(eventProducerTime);
                        return object;
                    }

                    @Override
                    public boolean hasNext() {
                        recordTime(eventConsumerTime);
                        boolean result = super.hasNext();
                        recordTime(eventProducerTime);
                        return result;
                    }
                });
            } finally {
                afterEventDelivery();
                eventDeliveryTime.addAndGet(nanoTime() - start);
            }
        }

        @Override
        public String toString() {
            return ListenerTracker.this.toString();
        }
    };
}
Also used : EventIteratorAdapter(org.apache.jackrabbit.commons.iterator.EventIteratorAdapter) JackrabbitEvent(org.apache.jackrabbit.api.observation.JackrabbitEvent) Event(javax.jcr.observation.Event) JackrabbitEvent(org.apache.jackrabbit.api.observation.JackrabbitEvent) TimeSeriesRecorder(org.apache.jackrabbit.stats.TimeSeriesRecorder) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator)

Example 9 with EventListener

use of javax.jcr.observation.EventListener in project jackrabbit by apache.

the class VersionControlledItemCollection method update.

/**
     * Perform an update on this resource. Depending on the format of the <code>updateInfo</code>
     * this is translated to one of the following methods defined by the JCR API:
     * <ul>
     * <li>{@link Node#restore(javax.jcr.version.Version, boolean)}</li>
     * <li>{@link Node#restore(javax.jcr.version.Version, String, boolean)}</li>
     * <li>{@link Node#restoreByLabel(String, boolean)}</li>
     * <li>{@link Node#update(String)}</li>
     * </ul>
     * <p>
     * Limitation: note that the <code>MultiStatus</code> returned by this method
     * will not list any nodes that have been removed due to an Uuid conflict.
     *
     * @param updateInfo
     * @return
     * @throws org.apache.jackrabbit.webdav.DavException
     * @see org.apache.jackrabbit.webdav.version.VersionControlledResource#update(org.apache.jackrabbit.webdav.version.UpdateInfo)
     */
//TODO: with jcr the node must not be versionable in order to perform Node.update.
@Override
public MultiStatus update(UpdateInfo updateInfo) throws DavException {
    if (updateInfo == null) {
        throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Valid update request body required.");
    }
    if (!exists()) {
        throw new DavException(DavServletResponse.SC_NOT_FOUND);
    }
    MultiStatus ms = new MultiStatus();
    try {
        Node node = (Node) item;
        Element udElem = updateInfo.getUpdateElement();
        boolean removeExisting = DomUtil.hasChildElement(udElem, XML_REMOVEEXISTING, NAMESPACE);
        // register eventListener in order to be able to report the modified resources.
        EventListener el = new EListener(updateInfo.getPropertyNameSet(), ms);
        registerEventListener(el, node.getPath());
        // perform the update/restore according to the update info
        if (updateInfo.getVersionHref() != null) {
            String[] hrefs = updateInfo.getVersionHref();
            if (hrefs.length != 1) {
                throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Invalid update request body missing version href or containing multiple version hrefs.");
            }
            String versionPath = getLocatorFromHref(hrefs[0]).getRepositoryPath();
            String versionName = getItemName(versionPath);
            String relPath = DomUtil.getChildText(udElem, XML_RELPATH, NAMESPACE);
            if (relPath == null) {
                // restore version by name
                node.restore(versionName, removeExisting);
            } else if (node.hasNode(relPath)) {
                Version v = node.getNode(relPath).getVersionHistory().getVersion(versionName);
                node.restore(v, relPath, removeExisting);
            } else {
                Version v = (Version) getRepositorySession().getNode(versionPath);
                node.restore(v, relPath, removeExisting);
            }
        } else if (updateInfo.getLabelName() != null) {
            String[] labels = updateInfo.getLabelName();
            if (labels.length != 1) {
                throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Invalid update request body: Multiple labels specified.");
            }
            node.restoreByLabel(labels[0], removeExisting);
        } else if (updateInfo.getWorkspaceHref() != null) {
            String href = obtainAbsolutePathFromUri(updateInfo.getWorkspaceHref());
            String workspaceName = getLocatorFromHref(href).getWorkspaceName();
            node.update(workspaceName);
        } else {
            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Invalid update request body.");
        }
        // unregister the event listener again
        unregisterEventListener(el);
    } catch (RepositoryException e) {
        throw new JcrDavException(e);
    }
    return ms;
}
Also used : DavException(org.apache.jackrabbit.webdav.DavException) Version(javax.jcr.version.Version) Node(javax.jcr.Node) Element(org.w3c.dom.Element) MultiStatus(org.apache.jackrabbit.webdav.MultiStatus) RepositoryException(javax.jcr.RepositoryException) EventListener(javax.jcr.observation.EventListener)

Example 10 with EventListener

use of javax.jcr.observation.EventListener in project jackrabbit-oak by apache.

the class ObservationTest method doIncludeAncestorsRemove.

private FilterProvider doIncludeAncestorsRemove(JackrabbitEventFilter filter) throws Exception {
    assumeTrue(observationManager instanceof ObservationManagerImpl);
    Node testNode = getNode(TEST_PATH);
    testNode.addNode("a").addNode("b").addNode("c").addNode("d").setProperty("e", 42);
    testNode.getSession().save();
    ObservationManagerImpl oManager = (ObservationManagerImpl) observationManager;
    ExpectationListener listener = new ExpectationListener();
    oManager.addEventListener(listener, filter);
    Node d = testNode.getNode("a").getNode("b").getNode("c").getNode("d");
    Property e = d.getProperty("e");
    listener.expectRemove(e);
    //        listener.expectRemove(d.getProperty("jcr:primaryType"));
    //        d.remove();
    listener.expectRemove(d).remove();
    testNode.getSession().save();
    Thread.sleep(1000);
    List<Expectation> missing = listener.getMissing(TIME_OUT, TimeUnit.SECONDS);
    List<Event> unexpected = listener.getUnexpected();
    assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
    assertTrue("Missing events: " + missing, missing.isEmpty());
    oManager.addEventListener(new EventListener() {

        @Override
        public void onEvent(EventIterator events) {
            while (events.hasNext()) {
                System.out.println("/a-listener GOT: " + events.next());
            }
        }
    }, NODE_REMOVED, TEST_PATH + "/a", false, null, null, false);
    System.out.println("REGISTERED");
    testNode = getNode(TEST_PATH);
    Node b = testNode.getNode("a").getNode("b");
    listener.expect(b.getPath(), NODE_REMOVED);
    listener.optional(new Expectation("/a/b/c is optionally sent depending on filter") {

        @Override
        public boolean onEvent(Event event) throws Exception {
            if (event.getPath().equals(TEST_PATH + "/a/b/c") && event.getType() == NODE_REMOVED) {
                return true;
            }
            return false;
        }
    });
    b.remove();
    // but not the jcr:primaryType
    testNode.getSession().save();
    Thread.sleep(1000);
    missing = listener.getMissing(TIME_OUT, TimeUnit.SECONDS);
    unexpected = listener.getUnexpected();
    assertTrue("Missing events: " + missing, missing.isEmpty());
    assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
    Node a = testNode.getNode("a");
    listener.expect(a.getPath(), NODE_REMOVED);
    a.remove();
    // but not the jcr:primaryType
    testNode.getSession().save();
    missing = listener.getMissing(TIME_OUT, TimeUnit.SECONDS);
    unexpected = listener.getUnexpected();
    assertTrue("Unexpected events: " + unexpected, unexpected.isEmpty());
    assertTrue("Missing events: " + missing, missing.isEmpty());
    ChangeProcessor cp = oManager.getChangeProcessor(listener);
    assertNotNull(cp);
    FilterProvider filterProvider = cp.getFilterProvider();
    assertNotNull(filterProvider);
    return filterProvider;
}
Also used : JackrabbitNode(org.apache.jackrabbit.api.JackrabbitNode) Node(javax.jcr.Node) ItemExistsException(javax.jcr.ItemExistsException) ConstraintViolationException(javax.jcr.nodetype.ConstraintViolationException) TimeoutException(java.util.concurrent.TimeoutException) VersionException(javax.jcr.version.VersionException) InvalidItemStateException(javax.jcr.InvalidItemStateException) ReferentialIntegrityException(javax.jcr.ReferentialIntegrityException) AccessDeniedException(javax.jcr.AccessDeniedException) PathNotFoundException(javax.jcr.PathNotFoundException) RepositoryException(javax.jcr.RepositoryException) LockException(javax.jcr.lock.LockException) NoSuchNodeTypeException(javax.jcr.nodetype.NoSuchNodeTypeException) ExecutionException(java.util.concurrent.ExecutionException) FilterProvider(org.apache.jackrabbit.oak.plugins.observation.filter.FilterProvider) Event(javax.jcr.observation.Event) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Property(javax.jcr.Property)

Aggregations

EventListener (javax.jcr.observation.EventListener)26 EventIterator (javax.jcr.observation.EventIterator)12 RepositoryException (javax.jcr.RepositoryException)11 Session (javax.jcr.Session)10 ObservationManager (javax.jcr.observation.ObservationManager)10 Event (javax.jcr.observation.Event)8 Node (javax.jcr.Node)6 ArrayList (java.util.ArrayList)3 JackrabbitNode (org.apache.jackrabbit.api.JackrabbitNode)3 JackrabbitEvent (org.apache.jackrabbit.api.observation.JackrabbitEvent)3 HashMap (java.util.HashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 Future (java.util.concurrent.Future)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 PathNotFoundException (javax.jcr.PathNotFoundException)2 Lock (javax.jcr.lock.Lock)2 Version (javax.jcr.version.Version)2 Test (org.junit.Test)2 RemoteException (java.rmi.RemoteException)1 HashSet (java.util.HashSet)1