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.commons.lang3.tuple.Pair; 026 027import org.ametys.cms.fo.ForceDefaultRepositoryWorkspaceCallableDecorator; 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.web.repository.page.Page; 036import org.ametys.web.repository.site.Site; 037import org.ametys.web.rights.PageRightAssignmentContext; 038 039/** 040 * DAO for page subscriptions 041 */ 042public class PageSubscriptionsDAO extends AbstractSubscriptionsDAO 043{ 044 /** The subscription type extension point */ 045 protected SubscriptionTypeExtensionPoint _subscriptionTypeEP; 046 047 /** The page subscription type */ 048 protected PageSubscriptionType _pageSubscriptionType; 049 050 @Override 051 public void service(ServiceManager smanager) throws ServiceException 052 { 053 super.service(smanager); 054 _subscriptionTypeEP = (SubscriptionTypeExtensionPoint) smanager.lookup(SubscriptionTypeExtensionPoint.ROLE); 055 _pageSubscriptionType = (PageSubscriptionType) _subscriptionTypeEP.getExtension(PageSubscriptionType.ID); 056 } 057 058 /** 059 * Get subscriptions of a page 060 * @param pageId the page id 061 * @return the results 062 */ 063 @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 064 public Map<String, Object> getPageSubscriptions(String pageId) 065 { 066 UserIdentity user = _currentUserProvider.getUser(); 067 068 Page page = _resolver.resolveById(pageId); 069 070 return _getPageSubscriptions(page, user); 071 } 072 073 private Map<String, Object> _getPageSubscriptions(Page page, UserIdentity user) 074 { 075 Map<String, Object> results = new HashMap<>(); 076 077 Set<UserIdentity> subscribers = getPageSubscribers(page); 078 079 results.put("hasSubscribed", subscribers.stream() 080 .filter(u -> u.equals(user)) 081 .findAny() 082 .isPresent() 083 ); 084 results.put("nbSubscribers", subscribers.size()); 085 086 return results; 087 } 088 089 /** 090 * Subscribe the current user to a page 091 * @param pageId the page id 092 * @return the results 093 */ 094 @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 095 public Map<String, Object> subscribePage(String pageId) 096 { 097 Map<String, Object> results = new HashMap<>(); 098 099 Page page = _resolver.resolveById(pageId); 100 UserIdentity user = _currentUserProvider.getUser(); 101 try 102 { 103 Pair<Frequency, List<BroadcastChannel>> defaultPreference = _getDefaultPreference(page.getSite()); 104 PageSubscriptionContext context = PageSubscriptionContext.newInstance() 105 .withPage(page); 106 _pageSubscriptionType.subscribe(page.getSite(), user, defaultPreference.getLeft(), defaultPreference.getRight(), context); 107 results.put("success", true); 108 } 109 catch (Exception e) 110 { 111 getLogger().error("An error occurred subscribing to the page with id '{}'", pageId, e); 112 results.put("success", false); 113 } 114 115 results.putAll(_getPageSubscriptions(page, user)); 116 return results; 117 } 118 119 private Pair<Frequency, List<BroadcastChannel>> _getDefaultPreference(Site site) 120 { 121 String frequencyValue = site.getValueOrDefault("page-default-frequency"); 122 return "NOMAIL".equals(frequencyValue) 123 ? Pair.of(Frequency.INSTANT, List.of(BroadcastChannel.SITE)) 124 : Pair.of(Frequency.valueOf(frequencyValue), List.of(BroadcastChannel.MAIL, BroadcastChannel.SITE)); 125 } 126 127 /** 128 * Unsubscribe the current user to a page 129 * @param pageId the page id 130 * @return the results 131 */ 132 @Callable(rights = Callable.READ_ACCESS, paramIndex = 0, rightContext = PageRightAssignmentContext.ID, decorators = ForceDefaultRepositoryWorkspaceCallableDecorator.DECORATOR_ID) 133 public Map<String, Object> unsubscribePage(String pageId) 134 { 135 Map<String, Object> results = new HashMap<>(); 136 137 Page page = _resolver.resolveById(pageId); 138 UserIdentity user = _currentUserProvider.getUser(); 139 140 try 141 { 142 PageSubscriptionContext context = PageSubscriptionContext.newInstance() 143 .withPage(page); 144 _pageSubscriptionType.unsubscribe(page.getSite(), user, context); 145 results.put("success", true); 146 } 147 catch (Exception e) 148 { 149 getLogger().error("An error occurred unsubscribing to the page with id '{}'", pageId, e); 150 results.put("success", false); 151 return results; 152 } 153 154 results.putAll(_getPageSubscriptions(page, user)); 155 return results; 156 } 157 158 /** 159 * Get the page subscribers 160 * @param page the page 161 * @return the subscribers 162 */ 163 public Set<UserIdentity> getPageSubscribers(Page page) 164 { 165 PageSubscriptionContext context = PageSubscriptionContext.newInstance() 166 .withPage(page); 167 return _pageSubscriptionType.getSubscribers(page.getSite(), null, null, context); 168 } 169 170}