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