Search in sources :

Example 71 with Event

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

the class EventJournalResourceImpl method spool.

@Override
public void spool(OutputContext outputContext) throws IOException {
    Calendar cal = Calendar.getInstance(Locale.ENGLISH);
    try {
        outputContext.setContentType("application/atom+xml; charset=UTF-8");
        outputContext.setProperty("Vary", "If-None-Match");
        // TODO: Content-Encoding: gzip
        // find out where to start
        long prevts = -1;
        String inm = request.getHeader("If-None-Match");
        if (inm != null) {
            // TODO: proper parsing when comma-delimited
            inm = inm.trim();
            if (inm.startsWith("\"") && inm.endsWith("\"")) {
                String tmp = inm.substring(1, inm.length() - 1);
                try {
                    prevts = Long.parseLong(tmp, 16);
                    journal.skipTo(prevts);
                } catch (NumberFormatException ex) {
                // broken etag
                }
            }
        }
        boolean hasPersistEvents = false;
        if (outputContext.hasStream()) {
            long lastts = -1;
            long now = System.currentTimeMillis();
            boolean done = false;
            // collect events
            List<Event> events = new ArrayList<Event>(MAXEV);
            while (!done && journal.hasNext()) {
                Event e = journal.nextEvent();
                hasPersistEvents |= e.getType() == Event.PERSIST;
                if (e.getDate() != lastts) {
                    // consider stopping
                    if (events.size() > MAXEV) {
                        done = true;
                    }
                    if (e.getDate() > now + MAXWAIT) {
                        done = true;
                    }
                }
                if (!done && (prevts == -1 || e.getDate() >= prevts)) {
                    events.add(e);
                }
                lastts = e.getDate();
            }
            if (lastts >= 0) {
                // construct ETag from newest event
                outputContext.setETag("\"" + Long.toHexString(lastts) + "\"");
            }
            OutputStream os = outputContext.getOutputStream();
            StreamResult streamResult = new StreamResult(os);
            SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance();
            TransformerHandler th = tf.newTransformerHandler();
            Transformer s = th.getTransformer();
            s.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            s.setOutputProperty(OutputKeys.INDENT, "yes");
            s.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            th.setResult(streamResult);
            th.startDocument();
            th.startElement(ATOMNS, FEED, FEED, NOATTRS);
            writeAtomElement(th, TITLE, "EventJournal for " + getLocator().getWorkspaceName());
            th.startElement(ATOMNS, AUTHOR, AUTHOR, NOATTRS);
            writeAtomElement(th, NAME, "Jackrabbit Event Journal Feed Generator");
            th.endElement(ATOMNS, AUTHOR, AUTHOR);
            String id = getFullUri(request);
            writeAtomElement(th, ID, id);
            AttributesImpl linkattrs = new AttributesImpl();
            linkattrs.addAttribute(null, "self", "self", "CDATA", id);
            writeAtomElement(th, LINK, linkattrs, null);
            cal.setTimeInMillis(lastts >= 0 ? lastts : now);
            String upd = ISO8601.format(cal);
            writeAtomElement(th, UPDATED, upd);
            String lastDateString = "";
            long lastTimeStamp = 0;
            long index = 0;
            AttributesImpl contentatt = new AttributesImpl();
            contentatt.addAttribute(null, "type", "type", "CDATA", EVENTMEDIATYPE);
            while (!events.isEmpty()) {
                List<Event> bundle = null;
                String path = null;
                String op;
                if (hasPersistEvents) {
                    bundle = new ArrayList<Event>();
                    Event e = null;
                    op = "operations";
                    do {
                        e = events.remove(0);
                        bundle.add(e);
                        // compute common path
                        if (path == null) {
                            path = e.getPath();
                        } else {
                            if (e.getPath() != null && e.getPath().length() < path.length()) {
                                path = e.getPath();
                            }
                        }
                    } while (e.getType() != Event.PERSIST && !events.isEmpty());
                } else {
                    // no persist events
                    Event e = events.remove(0);
                    bundle = Collections.singletonList(e);
                    path = e.getPath();
                    op = EventUtil.getEventName(e.getType());
                }
                Event firstEvent = bundle.get(0);
                String entryupd = lastDateString;
                if (lastTimeStamp != firstEvent.getDate()) {
                    cal.setTimeInMillis(firstEvent.getDate());
                    entryupd = ISO8601.format(cal);
                    index = 0;
                } else {
                    index += 1;
                }
                th.startElement(ATOMNS, ENTRY, ENTRY, NOATTRS);
                String entrytitle = op + (path != null ? (": " + path) : "");
                writeAtomElement(th, TITLE, entrytitle);
                String entryid = id + "?type=journal&ts=" + Long.toHexString(firstEvent.getDate()) + "-" + index;
                writeAtomElement(th, ID, entryid);
                String author = firstEvent.getUserID() == null || firstEvent.getUserID().length() == 0 ? null : firstEvent.getUserID();
                if (author != null) {
                    th.startElement(ATOMNS, AUTHOR, AUTHOR, NOATTRS);
                    writeAtomElement(th, NAME, author);
                    th.endElement(ATOMNS, AUTHOR, AUTHOR);
                }
                writeAtomElement(th, UPDATED, entryupd);
                th.startElement(ATOMNS, CONTENT, CONTENT, contentatt);
                for (Event e : bundle) {
                    // serialize the event
                    th.startElement(EVNS, E_EVENT, E_EVENT, NOATTRS);
                    // DAV:href
                    if (e.getPath() != null) {
                        boolean isCollection = (e.getType() == Event.NODE_ADDED || e.getType() == Event.NODE_REMOVED);
                        String href = locator.getFactory().createResourceLocator(locator.getPrefix(), locator.getWorkspacePath(), e.getPath(), false).getHref(isCollection);
                        th.startElement(DavConstants.NAMESPACE.getURI(), DavConstants.XML_HREF, DavConstants.XML_HREF, NOATTRS);
                        th.characters(href.toCharArray(), 0, href.length());
                        th.endElement(DavConstants.NAMESPACE.getURI(), DavConstants.XML_HREF, DavConstants.XML_HREF);
                    }
                    // event type
                    String evname = EventUtil.getEventName(e.getType());
                    th.startElement(EVNS, E_EVENTTYPE, E_EVENTTYPE, NOATTRS);
                    th.startElement(EVNS, evname, evname, NOATTRS);
                    th.endElement(EVNS, evname, evname);
                    th.endElement(EVNS, E_EVENTTYPE, E_EVENTTYPE);
                    // date
                    writeObsElement(th, E_EVENTDATE, Long.toString(e.getDate()));
                    // user data
                    if (e.getUserData() != null && e.getUserData().length() > 0) {
                        writeObsElement(th, E_EVENTUSERDATA, firstEvent.getUserData());
                    }
                    // try to compute nodetype information
                    if (e instanceof AdditionalEventInfo) {
                        try {
                            Name pnt = ((AdditionalEventInfo) e).getPrimaryNodeTypeName();
                            if (pnt != null) {
                                writeObsElement(th, E_EVENTPRIMARNODETYPE, pnt.toString());
                            }
                            Set<Name> mixins = ((AdditionalEventInfo) e).getMixinTypeNames();
                            if (mixins != null) {
                                for (Name mixin : mixins) {
                                    writeObsElement(th, E_EVENTMIXINNODETYPE, mixin.toString());
                                }
                            }
                        } catch (UnsupportedRepositoryOperationException ex) {
                        // optional
                        }
                    }
                    // identifier
                    if (e.getIdentifier() != null) {
                        writeObsElement(th, E_EVENTIDENTIFIER, e.getIdentifier());
                    }
                    // info
                    if (!e.getInfo().isEmpty()) {
                        th.startElement(EVNS, E_EVENTINFO, E_EVENTINFO, NOATTRS);
                        Map<?, ?> m = e.getInfo();
                        for (Map.Entry<?, ?> entry : m.entrySet()) {
                            String key = entry.getKey().toString();
                            Object value = entry.getValue();
                            String t = value != null ? value.toString() : null;
                            writeElement(th, null, key, NOATTRS, t);
                        }
                        th.endElement(EVNS, E_EVENTINFO, E_EVENTINFO);
                    }
                    th.endElement(EVNS, E_EVENT, E_EVENT);
                    lastTimeStamp = e.getDate();
                    lastDateString = entryupd;
                }
                th.endElement(ATOMNS, CONTENT, CONTENT);
                th.endElement(ATOMNS, ENTRY, ENTRY);
            }
            th.endElement(ATOMNS, FEED, FEED);
            th.endDocument();
            os.flush();
        }
    } catch (Exception ex) {
        throw new IOException("error generating feed: " + ex.getMessage());
    }
}
Also used : UnsupportedRepositoryOperationException(javax.jcr.UnsupportedRepositoryOperationException) TransformerHandler(javax.xml.transform.sax.TransformerHandler) Transformer(javax.xml.transform.Transformer) OutputStream(java.io.OutputStream) AdditionalEventInfo(org.apache.jackrabbit.spi.commons.AdditionalEventInfo) ArrayList(java.util.ArrayList) Name(org.apache.jackrabbit.spi.Name) AttributesImpl(org.xml.sax.helpers.AttributesImpl) StreamResult(javax.xml.transform.stream.StreamResult) Calendar(java.util.Calendar) SAXTransformerFactory(javax.xml.transform.sax.SAXTransformerFactory) IOException(java.io.IOException) RepositoryException(javax.jcr.RepositoryException) IOException(java.io.IOException) UnsupportedRepositoryOperationException(javax.jcr.UnsupportedRepositoryOperationException) DavException(org.apache.jackrabbit.webdav.DavException) SAXException(org.xml.sax.SAXException) Event(javax.jcr.observation.Event) Map(java.util.Map)

Example 72 with Event

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

the class RetentionRegistryImpl method onEvent.

//-------------------------------------------< SynchronousEventListener >---
/**
     * @param events Events reporting hold/retention policy changes.
     */
public void onEvent(EventIterator events) {
    while (events.hasNext()) {
        Event ev = events.nextEvent();
        try {
            Path evPath = session.getQPath(ev.getPath());
            Path nodePath = evPath.getAncestor(1);
            Name propName = evPath.getName();
            if (RetentionManagerImpl.REP_HOLD.equals(propName)) {
                // hold changes
                switch(ev.getType()) {
                    case Event.PROPERTY_ADDED:
                    case Event.PROPERTY_CHANGED:
                        // build the Hold objects from the rep:hold property
                        // and put them into the hold map.
                        PropertyImpl p = (PropertyImpl) session.getProperty(ev.getPath());
                        addHolds(nodePath, p);
                        break;
                    case Event.PROPERTY_REMOVED:
                        // all holds present on this node were remove
                        // -> remove the corresponding entry in the holdMap.
                        removeHolds(nodePath);
                        break;
                }
            } else if (RetentionManagerImpl.REP_RETENTION_POLICY.equals(propName)) {
                // retention policy changes
                switch(ev.getType()) {
                    case Event.PROPERTY_ADDED:
                    case Event.PROPERTY_CHANGED:
                        // build the RetentionPolicy objects from the rep:retentionPolicy property
                        // and put it into the retentionMap.
                        PropertyImpl p = (PropertyImpl) session.getProperty(ev.getPath());
                        addRetentionPolicy(nodePath, p);
                        break;
                    case Event.PROPERTY_REMOVED:
                        // retention policy present on this node was remove
                        // -> remove the corresponding entry in the retentionMap.
                        removeRetentionPolicy(nodePath);
                        break;
                }
            }
        // else: not interested in any other property -> ignore.
        } catch (RepositoryException e) {
            log.warn("Internal error while processing event. {}", e.getMessage());
        // ignore.
        }
    }
}
Also used : Path(org.apache.jackrabbit.spi.Path) Event(javax.jcr.observation.Event) PropertyImpl(org.apache.jackrabbit.core.PropertyImpl) RepositoryException(javax.jcr.RepositoryException) Name(org.apache.jackrabbit.spi.Name)

Example 73 with Event

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

the class VersionEventsTest method testRemoveVersion.

/**
     * Test if removing a version triggers two node removed events: one for the
     * version and one for the frozen node.
     */
public void testRemoveVersion() throws RepositoryException {
    // create versionable node
    Node n1 = testRootNode.addNode(nodeName1);
    n1.addMixin(mixVersionable);
    testRootNode.save();
    Version v = n1.checkin();
    String versionPath = v.getPath();
    n1.remove();
    testRootNode.save();
    EventResult listener = new EventResult(log);
    addEventListener(listener, Event.NODE_REMOVED);
    v.getContainingHistory().removeVersion(v.getName());
    removeEventListener(listener);
    Event[] events = listener.getEvents(1000);
    Set paths = new HashSet();
    for (int i = 0; i < events.length; i++) {
        paths.add(events[i].getPath());
    }
    assertTrue("missing 'node removed' event: " + versionPath, paths.contains(versionPath));
    String frozenPath = versionPath + "/" + jcrFrozenNode;
    assertTrue("missing 'node removed' event: " + frozenPath, paths.contains(frozenPath));
}
Also used : EventResult(org.apache.jackrabbit.test.api.observation.EventResult) HashSet(java.util.HashSet) Set(java.util.Set) Version(javax.jcr.version.Version) Node(javax.jcr.Node) Event(javax.jcr.observation.Event) HashSet(java.util.HashSet)

Example 74 with Event

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

the class VersionEventsTest method testXARemoveVersion.

/**
     * Test if removing a version in an XA transaction triggers two node removed
     * events: one for the version and one for the frozen node.
     */
public void testXARemoveVersion() throws Exception {
    // create versionable node
    Node n1 = testRootNode.addNode(nodeName1);
    n1.addMixin(mixVersionable);
    testRootNode.save();
    Version v = n1.checkin();
    String versionPath = v.getPath();
    n1.remove();
    testRootNode.save();
    EventResult listener = new EventResult(log);
    addEventListener(listener, Event.NODE_REMOVED);
    // use a transaction
    UserTransaction utx = new UserTransactionImpl(superuser);
    // start transaction
    utx.begin();
    v.getContainingHistory().removeVersion(v.getName());
    // commit transaction
    utx.commit();
    removeEventListener(listener);
    Event[] events = listener.getEvents(1000);
    Set paths = new HashSet();
    for (int i = 0; i < events.length; i++) {
        paths.add(events[i].getPath());
    }
    assertTrue("missing 'node removed' event: " + versionPath, paths.contains(versionPath));
    String frozenPath = versionPath + "/" + jcrFrozenNode;
    assertTrue("missing 'node removed' event: " + frozenPath, paths.contains(frozenPath));
}
Also used : UserTransaction(javax.transaction.UserTransaction) EventResult(org.apache.jackrabbit.test.api.observation.EventResult) HashSet(java.util.HashSet) Set(java.util.Set) Version(javax.jcr.version.Version) Node(javax.jcr.Node) UserTransactionImpl(org.apache.jackrabbit.core.UserTransactionImpl) Event(javax.jcr.observation.Event) HashSet(java.util.HashSet)

Example 75 with Event

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

the class MixinTest method testMultipleMixin.

/**
     * Tests event filtering with multiple mixin type name.
     */
public void testMultipleMixin() throws RepositoryException {
    testRootNode.addNode(nodeName1, testNodeType).addMixin(mixReferenceable);
    testRootNode.addNode(nodeName2, testNodeType).addMixin(mixLockable);
    testRootNode.addNode(nodeName3, testNodeType).addMixin(mixReferenceable);
    testRootNode.save();
    EventResult propertyAddedListener = new EventResult(log);
    addEventListener(propertyAddedListener, new String[] { mixReferenceable, mixLockable }, Event.PROPERTY_ADDED);
    try {
        testRootNode.getNode(nodeName1).setProperty(propertyName1, "test");
        testRootNode.getNode(nodeName2).setProperty(propertyName1, "test");
        testRootNode.getNode(nodeName3).setProperty(propertyName1, "test");
        testRootNode.save();
        Event[] added = propertyAddedListener.getEvents(DEFAULT_WAIT_TIMEOUT);
        checkPropertyAdded(added, new String[] { nodeName1 + "/" + propertyName1, nodeName2 + "/" + propertyName1, nodeName3 + "/" + propertyName1 });
    } finally {
        removeEventListener(propertyAddedListener);
    }
}
Also used : EventResult(org.apache.jackrabbit.test.api.observation.EventResult) Event(javax.jcr.observation.Event)

Aggregations

Event (javax.jcr.observation.Event)136 Node (javax.jcr.Node)103 Test (org.junit.Test)55 JackrabbitNode (org.apache.jackrabbit.api.JackrabbitNode)46 AbstractRepositoryTest (org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest)40 RepositoryException (javax.jcr.RepositoryException)29 Session (javax.jcr.Session)20 JackrabbitEventFilter (org.apache.jackrabbit.api.observation.JackrabbitEventFilter)19 EventResult (org.apache.jackrabbit.test.api.observation.EventResult)17 EventIterator (javax.jcr.observation.EventIterator)15 Property (javax.jcr.Property)13 ObservationManager (javax.jcr.observation.ObservationManager)13 SlingRepository (org.apache.sling.jcr.api.SlingRepository)10 ArrayList (java.util.ArrayList)9 Scheduler (org.apache.sling.commons.scheduler.Scheduler)9 DistributionRequest (org.apache.sling.distribution.DistributionRequest)9 ResourceResolverFactory (org.apache.sling.api.resource.ResourceResolverFactory)8 PathNotFoundException (javax.jcr.PathNotFoundException)7 EventListener (javax.jcr.observation.EventListener)7 JackrabbitObservationManager (org.apache.jackrabbit.api.observation.JackrabbitObservationManager)7