001/*
002 *  Copyright 2025 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.pagesubscription.observation;
017
018import java.util.Map;
019
020import org.apache.avalon.framework.service.ServiceException;
021import org.apache.avalon.framework.service.ServiceManager;
022import org.apache.avalon.framework.service.Serviceable;
023
024import org.ametys.core.ObservationConstants;
025import org.ametys.core.group.GroupIdentity;
026import org.ametys.core.observation.AsyncObserver;
027import org.ametys.core.observation.Event;
028import org.ametys.core.user.UserIdentity;
029import org.ametys.plugins.pagesubscription.type.SubscriptionType;
030import org.ametys.plugins.pagesubscription.type.SubscriptionTypeExtensionPoint;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.runtime.plugin.component.AbstractLogEnabled;
033import org.ametys.web.repository.site.Site;
034import org.ametys.web.repository.site.SiteManager;
035
036/**
037 * Observer to unsubscribe a user or group on deletion
038 */
039public class RemoveSubscriptionOnSubscriberDeletedObserver extends AbstractLogEnabled implements AsyncObserver, Serviceable
040{
041    /** The site manager */
042    protected SiteManager _siteManager;
043    /** The subscription type extension point */
044    protected SubscriptionTypeExtensionPoint _subscriptionTypeEP;
045
046    public void service(ServiceManager manager) throws ServiceException
047    {
048        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
049        _subscriptionTypeEP = (SubscriptionTypeExtensionPoint) manager.lookup(SubscriptionTypeExtensionPoint.ROLE);
050    }
051    
052    public boolean supports(Event event)
053    {
054        String eventId = event.getId();
055        return ObservationConstants.EVENT_USER_DELETED.equals(eventId)
056            || ObservationConstants.EVENT_GROUP_DELETED.equals(eventId);
057    }
058    
059    public void observe(Event event, Map<String, Object> transientVars) throws Exception
060    {
061        boolean isUserEvent = switch (event.getId())
062        {
063            case ObservationConstants.EVENT_USER_DELETED -> true;
064            case ObservationConstants.EVENT_GROUP_DELETED -> false;
065            default ->
066            throw new IllegalArgumentException("Unexpected event id: " + event.getId());
067        };
068        
069        // one of the two is null but that allow using the same for loops for both case
070        // without fetching the subscriber every iteration
071        UserIdentity user = (UserIdentity) event.getArguments().get(ObservationConstants.ARGS_USER);
072        GroupIdentity group = (GroupIdentity) event.getArguments().get(ObservationConstants.ARGS_GROUP);
073        
074        try (AmetysObjectIterable<Site> sites = _siteManager.getSites())
075        {
076            for (Site site : sites)
077            {
078                for (String typeId : _subscriptionTypeEP.getExtensionsIds())
079                {
080                    SubscriptionType subscriptionType = _subscriptionTypeEP.getExtension(typeId);
081                    if (isUserEvent)
082                    {
083                        subscriptionType.unsubscribeAll(site, user);
084                    }
085                    else
086                    {
087                        subscriptionType.unsubscribeAll(site, group);
088                    }
089                }
090            }
091        }
092    }
093
094    public int getPriority()
095    {
096        return Integer.MAX_VALUE;
097    }
098}