001/*
002 *  Copyright 2024 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.dao;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021import java.util.Set;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.components.ContextHelper;
026import org.apache.cocoon.environment.Request;
027
028import org.ametys.core.ui.Callable;
029import org.ametys.core.user.UserIdentity;
030import org.ametys.plugins.pagesubscription.BroadcastChannelHelper.BroadcastChannel;
031import org.ametys.plugins.pagesubscription.FrequencyHelper.Frequency;
032import org.ametys.plugins.pagesubscription.context.PageSubscriptionContext;
033import org.ametys.plugins.pagesubscription.type.PageSubscriptionType;
034import org.ametys.plugins.pagesubscription.type.SubscriptionTypeExtensionPoint;
035import org.ametys.plugins.repository.RepositoryConstants;
036import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
037import org.ametys.web.repository.page.Page;
038import org.ametys.web.rights.PageRightAssignmentContext;
039
040/**
041 * DAO for page subscriptions
042 */
043public class PageSubscriptionsDAO extends AbstractSubscriptionsDAO
044{
045    /** The subscription type extension point */
046    protected SubscriptionTypeExtensionPoint _subscriptionTypeEP;
047    
048    /** The page subscription type */
049    protected PageSubscriptionType _pageSubscriptionType;
050    
051    @Override
052    public void service(ServiceManager smanager) throws ServiceException
053    {
054        super.service(smanager);
055        _subscriptionTypeEP = (SubscriptionTypeExtensionPoint) smanager.lookup(SubscriptionTypeExtensionPoint.ROLE);
056        _pageSubscriptionType = (PageSubscriptionType) _subscriptionTypeEP.getExtension(PageSubscriptionType.ID);
057    }
058    
059    /**
060     * Get subscriptions of a page
061     * @param pageId the page id
062     * @return the results
063     */
064    @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID)
065    public Map<String, Object> getPageSubscriptions(String pageId)
066    {
067        UserIdentity user = _currentUserProvider.getUser();
068        
069        Page page = _resolver.resolveById(pageId);
070        
071        return _getPageSubscriptions(page, user);
072    }
073    
074    private Map<String, Object> _getPageSubscriptions(Page page, UserIdentity user)
075    {
076        Map<String, Object> results = new HashMap<>();
077        
078        Set<UserIdentity> subscribers = getPageSubscribers(page);
079        
080        results.put("hasSubscribed", subscribers.stream()
081                .filter(u -> u.equals(user))
082                .findAny()
083                .isPresent()
084        );
085        results.put("nbSubscribers", subscribers.size());
086        
087        return results;
088    }
089    
090    /**
091     * Subscribe the current user to a page 
092     * @param pageId the page id
093     * @return the results
094     */
095    @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID)
096    public Map<String, Object> subscribePage(String pageId)
097    {
098        Request request = ContextHelper.getRequest(_context);
099        // Retrieve the current workspace.
100        String currentWsp = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
101
102        Map<String, Object> results = new HashMap<>();
103        
104        UserIdentity user = _currentUserProvider.getUser();
105        Page page = _resolver.resolveById(pageId);
106        
107        try
108        {
109            // Force default the workspace.
110            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE);
111            
112            PageSubscriptionContext context = PageSubscriptionContext.newInstance()
113                    .withPage(page);
114            _pageSubscriptionType.subscribe(page.getSite(), user, Frequency.DAILY, List.of(BroadcastChannel.MAIL, BroadcastChannel.SITE), context);
115            results.put("success", true);
116        }
117        catch (Exception e)
118        {
119            getLogger().error("An error occurred subscribing to the page with id '{}'", pageId, e);
120            results.put("success", false);
121        }
122        finally 
123        {
124            // Restore current workspace
125            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWsp);
126        }
127        
128        results.putAll(_getPageSubscriptions(page, user));
129        return results;
130    }
131    
132    /**
133     * Unsubscribe the current user to a page 
134     * @param pageId the page id
135     * @return the results
136     */
137    @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID)
138    public Map<String, Object> unsubscribePage(String pageId)
139    {
140        Map<String, Object> results = new HashMap<>();
141        
142        Request request = ContextHelper.getRequest(_context);
143        // Retrieve the current workspace.
144        String currentWsp = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
145        
146        UserIdentity user = _currentUserProvider.getUser();
147        Page page = _resolver.resolveById(pageId);
148        
149        try
150        {
151            // Force default the workspace.
152            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE);
153            
154            PageSubscriptionContext context = PageSubscriptionContext.newInstance()
155                    .withPage(page);
156            _pageSubscriptionType.unsubscribe(page.getSite(), user, context);
157            results.put("success", true);
158        }
159        catch (Exception e)
160        {
161            getLogger().error("An error occurred unsubscribing to the page with id '{}'", pageId, e);
162            results.put("success", false);
163            return results;
164        }
165        finally 
166        {
167            // Restore current workspace
168            RequestAttributeWorkspaceSelector.setForcedWorkspace(request, currentWsp);
169        }
170        
171        results.putAll(_getPageSubscriptions(page, user));
172        return results;
173    }
174    
175    /**
176     * Get the page subscribers
177     * @param page the page
178     * @return the subscribers
179     */
180    public Set<UserIdentity> getPageSubscribers(Page page)
181    {
182        PageSubscriptionContext context = PageSubscriptionContext.newInstance()
183                .withPage(page);
184        return _pageSubscriptionType.getSubscribers(page.getSite(), null, null, context);
185    }
186    
187}