diff --git a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilter.java b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilter.java index 92524def2de..064de9d6f49 100644 --- a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilter.java +++ b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilter.java @@ -91,6 +91,7 @@ public FilterPolicy filterEvent(Event event, DocumentReference user, switch (state.getState()) { case BLOCKED: case BLOCKED_BY_ANCESTOR: + case BLOCKED_WITH_CHILDREN: if (state.getStartingDate().before(event.getDate())) { result = FilterPolicy.FILTER; } @@ -98,6 +99,7 @@ public FilterPolicy filterEvent(Event event, DocumentReference user, case WATCHED: case WATCHED_BY_ANCESTOR: + case WATCHED_WITH_CHILDREN: if (state.getStartingDate().after(event.getDate())) { result = FilterPolicy.FILTER; } diff --git a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterLocationStateComputer.java b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterLocationStateComputer.java index 9234b7e8ed7..e2b8df8bd53 100644 --- a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterLocationStateComputer.java +++ b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/ScopeNotificationFilterLocationStateComputer.java @@ -28,7 +28,10 @@ import javax.inject.Singleton; import org.xwiki.component.annotation.Component; +import org.xwiki.model.EntityType; +import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.EntityReference; +import org.xwiki.model.reference.SpaceReference; import org.xwiki.notifications.NotificationFormat; import org.xwiki.notifications.filters.NotificationFilterPreference; @@ -145,32 +148,49 @@ private Optional handleInclusiveFilters(EntityReference lo preferencesHierarchy.getInclusiveFiltersThatHasNoParents(); boolean exactMatch = false; + boolean spaceMatch = false; while (inclusiveFiltersIterator.hasNext()) { ScopeNotificationFilterPreference pref = inclusiveFiltersIterator.next(); boolean isExactMatch = isExactMatch(pref, location); boolean isParentMatch = isParentMatch(pref, location); + boolean isSpaceMatch = isSpaceMatch(pref, location); // If the inclusive filter match the event location... if (isExactMatch || isParentMatch) { // Then it means we watch this location match = true; exactMatch = isExactMatch; + spaceMatch = isSpaceMatch; startingDate = pref.getStartingDate(); } } if (match) { - WatchedLocationState.WatchedState watchedState; - if (allEventsAllFormats) { - watchedState = (exactMatch) ? WatchedLocationState.WatchedState.WATCHED - : WatchedLocationState.WatchedState.WATCHED_BY_ANCESTOR; - } else { - watchedState = WatchedLocationState.WatchedState.CUSTOM; - } + WatchedLocationState.WatchedState watchedState = + getWatchedState(allEventsAllFormats, exactMatch, spaceMatch, true); result = Optional.of(new WatchedLocationState(watchedState, startingDate)); } return result; } + private static WatchedLocationState.WatchedState getWatchedState(boolean allEventsAllFormats, boolean exactMatch, + boolean spaceMatch, boolean isInclusive) + { + WatchedLocationState.WatchedState watchedState; + if (!allEventsAllFormats) { + watchedState = WatchedLocationState.WatchedState.CUSTOM; + } else if (exactMatch) { + watchedState = (isInclusive) ? WatchedLocationState.WatchedState.WATCHED + : WatchedLocationState.WatchedState.BLOCKED; + } else if (spaceMatch) { + watchedState = (isInclusive) ? WatchedLocationState.WatchedState.WATCHED_WITH_CHILDREN + : WatchedLocationState.WatchedState.BLOCKED_WITH_CHILDREN; + } else { + watchedState = (isInclusive) ? WatchedLocationState.WatchedState.WATCHED_BY_ANCESTOR + : WatchedLocationState.WatchedState.BLOCKED_BY_ANCESTOR; + } + return watchedState; + } + private Optional handleExclusiveFilters(EntityReference location, ScopeNotificationFilterPreferencesHierarchy preferences, boolean allTypesAndEvents) { @@ -185,15 +205,11 @@ private Optional handleExclusiveFilters(EntityReference lo int deepLevel = pref.getScopeReference().size(); boolean isExactMatch = isExactMatch(pref, location); boolean isParentMatch = isParentMatch(pref, location); + boolean isSpaceMatch = isSpaceMatch(pref, location); // If the exclusive filter match the event location... if ((isExactMatch || isParentMatch) && deepLevel > deepestLevel) { - if (allTypesAndEvents) { - state = (isExactMatch) ? WatchedLocationState.WatchedState.BLOCKED - : WatchedLocationState.WatchedState.BLOCKED_BY_ANCESTOR; - } else { - state = WatchedLocationState.WatchedState.CUSTOM; - } + state = getWatchedState(allTypesAndEvents, isExactMatch, isSpaceMatch, false); startingDate = pref.getStartingDate(); deepestLevel = deepLevel; @@ -202,13 +218,9 @@ private Optional handleExclusiveFilters(EntityReference lo int childDeepLevel = child.getScopeReference().size(); boolean isChildExactMatch = isExactMatch(child, location); boolean isChildParentMatch = isParentMatch(child, location); + boolean isChildSpaceMatch = isSpaceMatch(child, location); if ((isChildExactMatch || isChildParentMatch) && childDeepLevel > deepestLevel) { - if (allTypesAndEvents) { - state = (isChildExactMatch) ? WatchedLocationState.WatchedState.WATCHED - : WatchedLocationState.WatchedState.WATCHED_BY_ANCESTOR; - } else { - state = WatchedLocationState.WatchedState.CUSTOM; - } + state = getWatchedState(allTypesAndEvents, isChildExactMatch, isChildSpaceMatch, true); deepestLevel = childDeepLevel; startingDate = child.getStartingDate(); } @@ -223,6 +235,16 @@ private Optional handleExclusiveFilters(EntityReference lo } } + private boolean isSpaceMatch(ScopeNotificationFilterPreference pref, EntityReference location) + { + boolean result = false; + EntityReference scopeReference = pref.getScopeReference(); + if (scopeReference.getType() == EntityType.SPACE) { + result = new DocumentReference("WebHome", new SpaceReference(scopeReference)).equals(location); + } + return result; + } + private boolean isExactMatch(ScopeNotificationFilterPreference pref, EntityReference location) { return location.equals(pref.getScopeReference()); diff --git a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/WatchedLocationState.java b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/WatchedLocationState.java index 36cf48f6ad0..1032314dbd4 100644 --- a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/WatchedLocationState.java +++ b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-api/src/main/java/org/xwiki/notifications/filters/internal/scope/WatchedLocationState.java @@ -33,8 +33,10 @@ public class WatchedLocationState public enum WatchedState { WATCHED, + WATCHED_WITH_CHILDREN, WATCHED_BY_ANCESTOR, BLOCKED, + BLOCKED_WITH_CHILDREN, BLOCKED_BY_ANCESTOR, CUSTOM, NOT_SET diff --git a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedEntityReference.java b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedEntityReference.java index 17a91d35f1e..d6f3ede1a3a 100644 --- a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedEntityReference.java +++ b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedEntityReference.java @@ -34,6 +34,7 @@ public interface WatchedEntityReference { /** * Define more precisely the watched status given the event types and the formats. + * * @since 15.5RC1 */ @Unstable @@ -44,9 +45,11 @@ enum WatchedStatus */ WATCHED_FOR_ALL_EVENTS_AND_FORMATS, WATCHED_BY_ANCESTOR_FOR_ALL_EVENTS_AND_FORMATS, + WATCHED_WITH_CHILDREN_FOR_ALL_EVENTS_AND_FORMATS, /** * The entity does not have a watched status: by default it means it's not watched, but it's not blocked. + * * @since 15.9RC1 */ NOT_SET, @@ -56,7 +59,7 @@ enum WatchedStatus */ BLOCKED_FOR_ALL_EVENTS_AND_FORMATS, BLOCKED_BY_ANCESTOR_FOR_ALL_EVENTS_AND_FORMATS, - + BLOCKED_WITH_CHILDREN_FOR_ALL_EVENTS_AND_FORMATS, CUSTOM } diff --git a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedLocationReference.java b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedLocationReference.java index 1c684afe3e1..6582e9bc9f6 100644 --- a/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedLocationReference.java +++ b/xwiki-platform-core/xwiki-platform-notifications/xwiki-platform-notifications-filters/xwiki-platform-notifications-filters-watch/src/main/java/org/xwiki/notifications/filters/watch/WatchedLocationReference.java @@ -104,8 +104,10 @@ public WatchedStatus getWatchedStatus(DocumentReference userReference) throws No case CUSTOM -> WatchedStatus.CUSTOM; case WATCHED -> WatchedStatus.WATCHED_FOR_ALL_EVENTS_AND_FORMATS; case WATCHED_BY_ANCESTOR -> WatchedStatus.WATCHED_BY_ANCESTOR_FOR_ALL_EVENTS_AND_FORMATS; + case WATCHED_WITH_CHILDREN -> WatchedStatus.WATCHED_WITH_CHILDREN_FOR_ALL_EVENTS_AND_FORMATS; case BLOCKED -> WatchedStatus.BLOCKED_FOR_ALL_EVENTS_AND_FORMATS; case BLOCKED_BY_ANCESTOR -> WatchedStatus.BLOCKED_BY_ANCESTOR_FOR_ALL_EVENTS_AND_FORMATS; + case BLOCKED_WITH_CHILDREN -> WatchedStatus.BLOCKED_WITH_CHILDREN_FOR_ALL_EVENTS_AND_FORMATS; default -> WatchedStatus.NOT_SET; }; }