Author: cziegeler Date: Fri Oct 14 09:41:30 2016 New Revision: 1764847 URL: http://svn.apache.org/viewvc?rev=1764847&view=rev Log: SLING-6148 : MapEntries get CHANGED event right after DELETE
Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java?rev=1764847&r1=1764846&r2=1764847&view=diff ============================================================================== --- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java (original) +++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrResourceListener.java Fri Oct 14 09:41:30 2016 @@ -34,9 +34,9 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import javax.jcr.Node; -import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.observation.Event; @@ -138,6 +138,7 @@ public class JcrResourceListener impleme final Map<String, Builder> changedEvents = new HashMap<String, Builder>(); final Map<String, Builder> removedEvents = new HashMap<String, Builder>(); + AtomicBoolean refreshedSession = new AtomicBoolean(false); while ( events.hasNext() ) { final Event event = events.nextEvent(); if (isExternal(event) && !includeExternal) { @@ -147,51 +148,46 @@ public class JcrResourceListener impleme try { final String eventPath = event.getPath(); final int type = event.getType(); + if ( type == PROPERTY_ADDED || type == PROPERTY_REMOVED || type == PROPERTY_CHANGED ) { final int lastSlash = eventPath.lastIndexOf('/'); - final String nodePath = eventPath.substring(0, lastSlash); - Builder builder = changedEvents.get(nodePath); - if (builder == null) { - changedEvents.put(nodePath, createResourceChange(event, nodePath, ChangeType.CHANGED)); + final String rsrcPath = stripNtFilePath(eventPath.substring(0, lastSlash), refreshedSession); + if ( !addedEvents.containsKey(rsrcPath) + && !removedEvents.containsKey(rsrcPath) + && !changedEvents.containsKey(rsrcPath) + && ctx.getExcludedPaths().matches(rsrcPath) == null) { + + changedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.CHANGED)); + } + } else { + final String rsrcPath = (type == NODE_REMOVED ? eventPath : stripNtFilePath(eventPath, refreshedSession)); + + if ( ctx.getExcludedPaths().matches(rsrcPath) == null ) { + if ( type == NODE_ADDED ) { + // add is stronger than update + changedEvents.remove(rsrcPath); + addedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.ADDED)); + } else if ( type == NODE_REMOVED) { + // remove is stronger than add and change + addedEvents.remove(rsrcPath); + changedEvents.remove(rsrcPath); + removedEvents.put(rsrcPath, createResourceChange(event, rsrcPath, ChangeType.REMOVED)); + } } - } else if ( type == NODE_ADDED ) { - addedEvents.put(eventPath, createResourceChange(event, ChangeType.ADDED)); - } else if ( type == NODE_REMOVED) { - removedEvents.put(eventPath, createResourceChange(event, ChangeType.REMOVED)); } } catch (final RepositoryException e) { logger.error("Error during modification: {}", e); } } - // remove is the strongest operation, therefore remove all removed - // paths from added and changed - for(final String path : removedEvents.keySet()) { - addedEvents.remove(path); - changedEvents.remove(path); - } - // add is stronger than update - for(final String path : addedEvents.keySet()) { - changedEvents.remove(path); - } - final List<ResourceChange> changes = new ArrayList<ResourceChange>(); - for (Entry<String, Builder> e : addedEvents.entrySet()) { - String path = e.getKey(); - if (changedEvents.containsKey(path)) { - Builder builder = changedEvents.remove(path); - builder.setChangeType(ChangeType.ADDED); - changes.add(builder.build()); - } else { - changes.add(e.getValue().build()); - } - } + buildResourceChanges(changes, addedEvents); buildResourceChanges(changes, removedEvents); buildResourceChanges(changes, changedEvents); - filterChanges(changes); ctx.getObservationReporter().reportChanges(changes, false); + } private void buildResourceChanges(List<ResourceChange> result, Map<String, Builder> builders) { @@ -200,15 +196,11 @@ public class JcrResourceListener impleme } } - private Builder createResourceChange(final Event event, final String path, final ChangeType changeType) throws RepositoryException { + private Builder createResourceChange(final Event event, + final String path, + final ChangeType changeType) { Builder builder = new Builder(); - String strippedPath; - if (event.getType() == Event.NODE_REMOVED) { - strippedPath = path; - } else { - strippedPath = stripNtFilePath(path, session); - } - String pathWithPrefix = addMountPrefix(mountPrefix, strippedPath); + String pathWithPrefix = addMountPrefix(mountPrefix, path); builder.setPath(pathMapper.mapJCRPathToResourcePath(pathWithPrefix)); builder.setChangeType(changeType); boolean isExternal = this.isExternal(event); @@ -222,10 +214,6 @@ public class JcrResourceListener impleme return builder; } - private Builder createResourceChange(final Event event, final ChangeType changeType) throws RepositoryException { - return createResourceChange(event, event.getPath(), changeType); - } - private boolean isExternal(final Event event) { if ( this.hasJackrabbitEventClass && event instanceof JackrabbitEvent) { final JackrabbitEvent jEvent = (JackrabbitEvent)event; @@ -313,35 +301,25 @@ public class JcrResourceListener impleme return result; } - private void filterChanges(List<ResourceChange> changes) { - Iterator<ResourceChange> it = changes.iterator(); - while (it.hasNext()) { - String path = it.next().getPath(); - if (ctx.getExcludedPaths().matches(path) != null) { - it.remove(); - } - } - } + private static final String JCR_CONTENT_POSTFIX = "/" + JcrConstants.JCR_CONTENT; - static String stripNtFilePath(String path, Session session) { - if (!path.endsWith("/" + JcrConstants.JCR_CONTENT)) { + private String stripNtFilePath(final String path, final AtomicBoolean refreshedSession) { + if (!path.endsWith(JCR_CONTENT_POSTFIX)) { return path; } try { - Node node; - try { - node = session.getNode(path); - } catch(PathNotFoundException e) { + if ( !refreshedSession.get() ) { session.refresh(false); - node = session.getNode(path); + refreshedSession.set(true); } - Node parent = node.getParent(); + final Node node = session.getNode(path); + final Node parent = node.getParent(); if (parent.isNodeType(JcrConstants.NT_FILE)) { return parent.getPath(); } else { return path; } - } catch (RepositoryException e) { + } catch (final RepositoryException e) { return path; } }