Search in sources :

Example 1 with TargetableNotificationPreference

use of org.xwiki.notifications.preferences.TargetableNotificationPreference in project xwiki-platform by xwiki.

the class NotificationPreferenceScriptService method saveNotificationPreferences.

private void saveNotificationPreferences(String json, String providerHint, EntityReference target, NotificationPreferenceCategory category) throws NotificationException {
    /*
            The JSON we get is a "snapshot" of the states of the buttons the user has in front of her eyes when she is
            managing her preferences.

            We did that so we can save several preferences in the same time without making too much requests (for
            example when the user enable an application, it actually enable all the app's event types).

            However, this snapshot also "freeze" the default preferences, ie the preferences set at the wiki level and
            that the user has not changed.

            Example:
            1. Wiki Administrator enables the application A by default, and doesn't touch the settings for the
               application B.
            2. John Doe disables the application A on HIS profile. He doesn't touch the setting for the application B.
               A "snapshot" of his preferences is saved.
            3. Wiki Administrator enables the application B by default.
            4. On the John Doe's preferences, application B is still disabled, because of the snapshot done on step 2.

            I don't think this situation is good. If a user did not EXPLICITLY change a setting, the default settings
            should be applied.

            For this reason, this code will only save the settings THAT ARE DIFFERENT FROM THE DEFAULT (INHERITED).

            Since this logic is totally related to the way the UI is built, I think it does not deserve its own
            component or API. In a way, it should even be internal.
        */
    List<NotificationPreference> existingPreferences = Collections.emptyList();
    if (target instanceof DocumentReference) {
        existingPreferences = notificationPreferenceManager.getAllPreferences((DocumentReference) target);
    } else if (target instanceof WikiReference) {
        existingPreferences = notificationPreferenceManager.getAllPreferences((WikiReference) target);
    }
    // Instantiate a new copy of TargetableNotificationPreferenceBuilder because this component is not thread-safe.
    TargetableNotificationPreferenceBuilder targetableNotificationPreferenceBuilder = targetableNotificationPreferenceBuilderProvider.get();
    List<NotificationPreference> toSave = new ArrayList<>();
    try {
        ObjectMapper objectMapper = new ObjectMapper();
        List<Map<String, Object>> preferences = objectMapper.reader().forType(List.class).readValue(json);
        for (Map<String, Object> item : preferences) {
            String eventType = (String) item.get("eventType");
            NotificationFormat format = NotificationFormat.valueOf(((String) item.get("format")).toUpperCase());
            boolean enabled = (Boolean) item.get("enabled");
            targetableNotificationPreferenceBuilder.prepare();
            targetableNotificationPreferenceBuilder.setEnabled(enabled);
            targetableNotificationPreferenceBuilder.setFormat(format);
            targetableNotificationPreferenceBuilder.setProviderHint(providerHint);
            targetableNotificationPreferenceBuilder.setProperties(Collections.singletonMap(NotificationPreferenceProperty.EVENT_TYPE, eventType));
            targetableNotificationPreferenceBuilder.setTarget(target);
            targetableNotificationPreferenceBuilder.setCategory(category);
            TargetableNotificationPreference newPreference = targetableNotificationPreferenceBuilder.build();
            // This part is explained by the long comment below
            NotificationPreference correspondingPreference = getCorrespondingPreference(existingPreferences, newPreference);
            if (correspondingPreference == null || correspondingPreference.isNotificationEnabled() != newPreference.isNotificationEnabled()) {
                toSave.add(newPreference);
            }
        }
        notificationPreferenceManager.savePreferences(toSave);
    } catch (Exception e) {
        throw new NotificationException("Failed to save preferences for notifications given as JSON.", e);
    }
}
Also used : TargetableNotificationPreferenceBuilder(org.xwiki.notifications.preferences.TargetableNotificationPreferenceBuilder) ArrayList(java.util.ArrayList) NotificationException(org.xwiki.notifications.NotificationException) NotificationException(org.xwiki.notifications.NotificationException) AccessDeniedException(org.xwiki.security.authorization.AccessDeniedException) NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) TargetableNotificationPreference(org.xwiki.notifications.preferences.TargetableNotificationPreference) NotificationFormat(org.xwiki.notifications.NotificationFormat) ArrayList(java.util.ArrayList) List(java.util.List) WikiReference(org.xwiki.model.reference.WikiReference) TargetableNotificationPreference(org.xwiki.notifications.preferences.TargetableNotificationPreference) Map(java.util.Map) DocumentReference(org.xwiki.model.reference.DocumentReference) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 2 with TargetableNotificationPreference

use of org.xwiki.notifications.preferences.TargetableNotificationPreference in project xwiki-platform by xwiki.

the class UserProfileNotificationPreferenceProviderTest method savePreferencesWithTargetable.

@Test
public void savePreferencesWithTargetable() throws Exception {
    DocumentReference userReference = new DocumentReference("wiki", "space", "user");
    DocumentReference userReference2 = new DocumentReference("wiki", "space", "user2");
    TargetableNotificationPreference pref1 = mock(TargetableNotificationPreference.class);
    when(pref1.getTarget()).thenReturn(userReference);
    TargetableNotificationPreference pref2 = mock(TargetableNotificationPreference.class);
    when(pref2.getTarget()).thenReturn(userReference);
    TargetableNotificationPreference pref3 = mock(TargetableNotificationPreference.class);
    when(pref3.getTarget()).thenReturn(userReference2);
    mocker.getComponentUnderTest().savePreferences(Arrays.asList(pref1, pref2, pref3));
    verify(cachedModelBridge, times(1)).saveNotificationsPreferences(eq(userReference), any(List.class));
    verify(cachedModelBridge, times(1)).saveNotificationsPreferences(eq(userReference2), any(List.class));
}
Also used : List(java.util.List) TargetableNotificationPreference(org.xwiki.notifications.preferences.TargetableNotificationPreference) DocumentReference(org.xwiki.model.reference.DocumentReference) Test(org.junit.Test)

Example 3 with TargetableNotificationPreference

use of org.xwiki.notifications.preferences.TargetableNotificationPreference in project xwiki-platform by xwiki.

the class AbstractDocumentNotificationPreferenceProvider method savePreferences.

@Override
public void savePreferences(List<NotificationPreference> preferences) throws NotificationException {
    // Create a map of preferences per target, so we can save the target's document only once for all preferences
    Map<EntityReference, List<NotificationPreference>> preferencesPerTarget = new HashMap<>();
    for (NotificationPreference preference : preferences) {
        if (preference instanceof TargetableNotificationPreference) {
            TargetableNotificationPreference targetablePreference = (TargetableNotificationPreference) preference;
            List<NotificationPreference> list = preferencesPerTarget.get(targetablePreference.getTarget());
            if (list == null) {
                list = new ArrayList<>();
                preferencesPerTarget.put(targetablePreference.getTarget(), list);
            }
            list.add(targetablePreference);
        } else {
            logger.warn("Unsupported NotificationPreference class: [{}]. This preference will not be saved.", preference.getClass().getName());
        }
    }
    for (Map.Entry<EntityReference, List<NotificationPreference>> entry : preferencesPerTarget.entrySet()) {
        savePreferences(entry.getValue(), entry.getKey());
    }
}
Also used : NotificationPreference(org.xwiki.notifications.preferences.NotificationPreference) TargetableNotificationPreference(org.xwiki.notifications.preferences.TargetableNotificationPreference) HashMap(java.util.HashMap) EntityReference(org.xwiki.model.reference.EntityReference) ArrayList(java.util.ArrayList) List(java.util.List) TargetableNotificationPreference(org.xwiki.notifications.preferences.TargetableNotificationPreference) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

List (java.util.List)3 TargetableNotificationPreference (org.xwiki.notifications.preferences.TargetableNotificationPreference)3 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 DocumentReference (org.xwiki.model.reference.DocumentReference)2 NotificationPreference (org.xwiki.notifications.preferences.NotificationPreference)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1 EntityReference (org.xwiki.model.reference.EntityReference)1 WikiReference (org.xwiki.model.reference.WikiReference)1 NotificationException (org.xwiki.notifications.NotificationException)1 NotificationFormat (org.xwiki.notifications.NotificationFormat)1 TargetableNotificationPreferenceBuilder (org.xwiki.notifications.preferences.TargetableNotificationPreferenceBuilder)1 AccessDeniedException (org.xwiki.security.authorization.AccessDeniedException)1