Author: cziegeler
Date: Fri Oct 14 11:14:17 2016
New Revision: 1764878

URL: http://svn.apache.org/viewvc?rev=1764878&view=rev
Log:
SLING-6148 : MapEntries get CHANGED event right after DELETE

Modified:
    
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java

Modified: 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java?rev=1764878&r1=1764877&r2=1764878&view=diff
==============================================================================
--- 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
 (original)
+++ 
sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
 Fri Oct 14 11:14:17 2016
@@ -73,6 +73,12 @@ import org.slf4j.LoggerFactory;
 
 public class MapEntries implements ResourceChangeListener, 
ExternalResourceChangeListener {
 
+    public static final String JCR_CONTENT = "jcr:content";
+
+    public static final String JCR_CONTENT_PREFIX = "jcr:content/";
+
+    public static final String JCR_CONTENT_SUFFIX = "/jcr:content";
+
     public static final MapEntries EMPTY = new MapEntries();
 
     private static final String PROP_REG_EXP = "sling:match";
@@ -327,6 +333,66 @@ public class MapEntries implements Resou
         return newRefreshed;
     }
 
+    /**
+     * Remove all aliases for the vanity path
+     * @param vanityPath The vanity path
+     * @param refreshed Flag if session needs refresh
+     * @param path Optional sub path of the vanity path
+     * @return
+     */
+    private boolean doRemoveAllAliases(final String vanityPath, boolean 
refreshed, final String path) {
+        // if path is specified we first need to find out if it is
+        // a direct child of vanity path but not jcr:content, or a jcr:content 
child of a direct child
+        // otherwise we can discard the event
+        boolean handle = true;
+        if ( path != null ) {
+            final String subPath = path.substring(vanityPath.length() + 1);
+            final int firstSlash = subPath.indexOf('/');
+            if ( firstSlash == -1 ) {
+                if ( subPath.equals(JCR_CONTENT) ) {
+                    handle = false;
+                }
+            } else if ( subPath.lastIndexOf('/') == firstSlash) {
+                if ( subPath.startsWith(JCR_CONTENT_PREFIX) || 
!subPath.endsWith(JCR_CONTENT_SUFFIX) ) {
+                    handle = false;
+                }
+            } else {
+                handle = false;
+            }
+        }
+        if ( !handle ) {
+            return false;
+        }
+        boolean newRefreshed = refreshed;
+        if (!newRefreshed) {
+            resolver.refresh();
+            newRefreshed = true;
+        }
+        this.initializing.lock();
+        try {
+            if (enableOptimizeAliasResolution) {
+                final Map<String, String> aliasMapEntry = 
aliasMap.remove(vanityPath);
+                if (aliasMapEntry != null && path != null && 
path.endsWith(JCR_CONTENT_SUFFIX) ) {
+                    // we need to re-add
+                    // from a potential parent
+                    doAddAlias(ResourceUtil.getParent(path));
+                }
+                if ( aliasMapEntry != null ) {
+                    sendChangeEvent();
+                }
+            }
+
+            // TODO we should not handle this here
+            if (vanityPath.startsWith(this.mapRoot)) {
+                doUpdateConfiguration();
+                sendChangeEvent();
+            }
+        } finally {
+            this.initializing.unlock();
+        }
+        return newRefreshed;
+    }
+
     private boolean doRemoveAttributes(String path, String removedAttribute, 
boolean refreshed) {
         boolean newRefreshed = refreshed;
         if (!newRefreshed) {
@@ -341,6 +407,8 @@ public class MapEntries implements Resou
                 if (enableOptimizeAliasResolution) {
                     doRemoveAlias(path, true);
                     if ( path.endsWith("/jcr:content") ) {
+                        // as doRemoveAlias removes all aliases we need to 
re-add
+                        // from a potential parent
                         doAddAlias(ResourceUtil.getParent(path));
                     }
                 }
@@ -662,7 +730,7 @@ public class MapEntries implements Resou
      * appropriate events.
      */
     @Override
-    public void onChange(List<ResourceChange> changes) {
+    public void onChange(final List<ResourceChange> changes) {
         boolean wasResolverRefreshed = false;
 
         for(final ResourceChange rc : changes) {
@@ -678,16 +746,18 @@ public class MapEntries implements Resou
             // removal of a resource is handled differently
             if (rc.getType() == ResourceChange.ChangeType.REMOVED) {
                 final String actualContentPath = getActualContentPath(path);
-                final String prefix = getActualContentPath(path) + "/";
+                final String actualContentPathPrefix = actualContentPath + "/";
 
                 for (final String target : this.vanityTargets.keySet()) {
-                    if (target.startsWith(prefix) || 
target.equals(actualContentPath)) {
+                    if (target.startsWith(actualContentPathPrefix) || 
target.equals(actualContentPath)) {
                         wasResolverRefreshed = doRemoveAttributes(target, 
PROP_VANITY_PATH, wasResolverRefreshed);
                     }
                 }
                 for (final String target : this.aliasMap.keySet()) {
-                    if (actualContentPath.startsWith(target + "/") || 
actualContentPath.equals(target)) {
-                        wasResolverRefreshed = 
doRemoveAttributes(actualContentPath, ResourceResolverImpl.PROP_ALIAS, 
wasResolverRefreshed);
+                    if (path.startsWith(target + "/") || path.equals(target)) {
+                        wasResolverRefreshed = doRemoveAllAliases(target, 
wasResolverRefreshed, null);
+                    } else if ( target.startsWith(actualContentPathPrefix) ) {
+                        wasResolverRefreshed = doRemoveAllAliases(target, 
wasResolverRefreshed, path);
                     }
                 }
                 if (path.startsWith(this.mapRoot)) {


Reply via email to