001/* 002 * Copyright 2015 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.web.clientsideelement; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import javax.jcr.Repository; 026import javax.jcr.RepositoryException; 027import javax.jcr.Session; 028import javax.mail.MessagingException; 029 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.commons.lang.StringUtils; 033 034import org.ametys.core.group.Group; 035import org.ametys.core.group.GroupIdentity; 036import org.ametys.core.group.GroupManager; 037import org.ametys.core.ui.Callable; 038import org.ametys.core.ui.ClientSideElement; 039import org.ametys.core.user.User; 040import org.ametys.core.user.UserIdentity; 041import org.ametys.core.user.UserManager; 042import org.ametys.core.util.I18nUtils; 043import org.ametys.core.util.mail.SendMailHelper; 044import org.ametys.plugins.core.user.UserHelper; 045import org.ametys.runtime.config.Config; 046import org.ametys.runtime.i18n.I18nizableText; 047import org.ametys.web.WebConstants; 048import org.ametys.web.repository.page.Page; 049import org.ametys.web.repository.site.Site; 050import org.ametys.web.site.SiteConfigurationExtensionPoint; 051import org.ametys.web.skin.Skin; 052import org.ametys.web.skin.SkinsManager; 053 054/** 055 * This {@link ClientSideElement} creates a button that will be enabled if page and its hierarchy is valid. 056 * 057 */ 058public class LivePageClientSideElement extends AbstractPageClientSideElement 059{ 060 /** The {@link UserManager} */ 061 private UserManager _userManager; 062 063 /** The {@link UserManager} for front-end users */ 064 private UserManager _foUsersManager; 065 066 /** The {@link GroupManager} for front-end groups */ 067 private GroupManager _foGroupsManager; 068 069 /** The {@link SiteConfigurationExtensionPoint} */ 070 private SiteConfigurationExtensionPoint _siteConfiguration; 071 072 /** The {@link I18nUtils} */ 073 private I18nUtils _i18nUtils; 074 075 /** The {@link SkinsManager}*/ 076 private SkinsManager _skinManager; 077 078 /** The repository */ 079 private Repository _repository; 080 081 private UserHelper _userHelper; 082 083 @Override 084 public void service(ServiceManager smanager) throws ServiceException 085 { 086 super.service(smanager); 087 _userManager = (UserManager) smanager.lookup(UserManager.ROLE); 088 _foUsersManager = (UserManager) smanager.lookup(UserManager.ROLE); 089 _foGroupsManager = (GroupManager) smanager.lookup(GroupManager.ROLE); 090 _siteConfiguration = (SiteConfigurationExtensionPoint) smanager.lookup(SiteConfigurationExtensionPoint.ROLE); 091 _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE); 092 _skinManager = (SkinsManager) smanager.lookup(SkinsManager.ROLE); 093 _repository = (Repository) smanager.lookup(Repository.class.getName()); 094 _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE); 095 } 096 097 /** 098 * Get the live status of given pages 099 * @param pageIds The page id 100 * @return the result 101 */ 102 @SuppressWarnings("unchecked") 103 @Callable 104 public Map<String, Object> getStatus (List<String> pageIds) 105 { 106 Map<String, Object> results = new HashMap<>(); 107 108 results.put("invalid-pages", new ArrayList<Map<String, Object>>()); 109 results.put("invalid-hierarchy", new ArrayList<Map<String, Object>>()); 110 results.put("allright-pages", new ArrayList<Map<String, Object>>()); 111 results.put("noright-pages", new ArrayList<Map<String, Object>>()); 112 113 Session liveSession = null; 114 try 115 { 116 liveSession = _repository.login(WebConstants.LIVE_WORKSPACE); 117 118 for (String pageId : pageIds) 119 { 120 Page page = _resolver.resolveById(pageId); 121 Skin skin = _skinManager.getSkin(page.getSite().getSkinId()); 122 123 boolean error = false; 124 125 // Has right ? 126 if (!hasRight(page)) 127 { 128 Map<String, Object> pageParams = getPageDefaultParameters(page); 129 pageParams.put("description", getNoRightPageDescription(page)); 130 131 List<Map<String, Object>> noRightsPages = (List<Map<String, Object>>) results.get("noright-pages"); 132 noRightsPages.add(pageParams); 133 134 error = true; 135 } 136 137 // Is page valid ? 138 boolean validPage = _synchronizeComponent.isPageValid(page, skin); 139 if (!validPage) 140 { 141 Map<String, Object> pageParams = getPageDefaultParameters(page); 142 pageParams.put("description", _getInvalidPageDescription(page)); 143 144 List<Map<String, Object>> invalidPages = (List<Map<String, Object>>) results.get("invalid-pages"); 145 invalidPages.add(pageParams); 146 147 error = true; 148 } 149 // Is hierarchy valid ? 150 else if (validPage && !_synchronizeComponent.isHierarchyValid(page, liveSession)) 151 { 152 Map<String, Object> pageParams = getPageDefaultParameters(page); 153 pageParams.put("description", _getInvalidHierarchyDescription(page)); 154 155 List<Map<String, Object>> invalidHierarchy = (List<Map<String, Object>>) results.get("invalid-hierarchy"); 156 invalidHierarchy.add(pageParams); 157 158 error = true; 159 } 160 161 // All right 162 if (!error) 163 { 164 Map<String, Object> pageParams = getPageDefaultParameters(page); 165 pageParams.put("description", getAllRightPageDescription(page)); 166 167 List<Map<String, Object>> allrightPages = (List<Map<String, Object>>) results.get("allright-pages"); 168 allrightPages.add(pageParams); 169 } 170 171 } 172 173 return results; 174 } 175 catch (RepositoryException e) 176 { 177 throw new RuntimeException("Unable to check live workspace", e); 178 } 179 finally 180 { 181 if (liveSession != null) 182 { 183 liveSession.logout(); 184 } 185 } 186 187 } 188 189 /** 190 * Send a notification for online pages. 191 * @param pageIds the ids of the pages 192 * @param users the users that will be notified 193 * @param groups the groups that will be notified 194 * @param comment the comment of the notifier 195 * @return true 196 */ 197 @Callable 198 public boolean sendOnlineNotification(List<String> pageIds, List<Map<String, String>> users, List<Map<String, String>> groups, String comment) 199 { 200 UserIdentity userIdentity = _currentUserProvider.getUser(); 201 User notifier = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 202 203 List<UserIdentity> userIdentities = new ArrayList<>(); 204 for (Map<String, String> user : users) 205 { 206 UserIdentity ui = _userHelper.json2userIdentity(user); 207 if (ui != null) 208 { 209 userIdentities.add(ui); 210 } 211 } 212 List<GroupIdentity> groupIdentities = new ArrayList<>(); 213 for (Map<String, String> group : groups) 214 { 215 String id = group.get("groupId"); 216 String groupDirectory = group.get("groupDirectory"); 217 groupIdentities.add(new GroupIdentity(id, groupDirectory)); 218 } 219 Set<User> distinctUsers = _getDistinctUsers (userIdentities, groupIdentities); 220 221 for (String pageId : pageIds) 222 { 223 Page page = _resolver.resolveById(pageId); 224 225 String from = _getSender(notifier, page); 226 String subject = _getSubject (notifier, page); 227 228 for (User user : distinctUsers) 229 { 230 if (StringUtils.isNotEmpty(user.getEmail())) 231 { 232 try 233 { 234 String body = _getBody(notifier, user, page, comment); 235 SendMailHelper.sendMail(subject, null, body, user.getEmail(), from); 236 } 237 catch (MessagingException e) 238 { 239 getLogger().error("Unable to send mail to user " + user.getEmail(), e); 240 } 241 } 242 } 243 } 244 245 return true; 246 } 247 248 /** 249 * Get i18n description for invalid page 250 * @param page The page 251 * @return The {@link I18nizableText} description 252 */ 253 private I18nizableText _getInvalidPageDescription (Page page) 254 { 255 List<String> i18nParameters = new ArrayList<>(); 256 i18nParameters.add(page.getTitle()); 257 258 I18nizableText ed = (I18nizableText) this._script.getParameters().get("invalid-page-description"); 259 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 260 } 261 262 /** 263 * Get i18n description for invalid hierarchy 264 * @param page The page 265 * @return The {@link I18nizableText} description 266 */ 267 private I18nizableText _getInvalidHierarchyDescription (Page page) 268 { 269 List<String> i18nParameters = new ArrayList<>(); 270 i18nParameters.add(page.getTitle()); 271 272 I18nizableText ed = (I18nizableText) this._script.getParameters().get("invalid-hierarchy-description"); 273 return new I18nizableText(ed.getCatalogue(), ed.getKey(), i18nParameters); 274 } 275 276 /** 277 * Get the email sender 278 * @param sender The user responsible for the action 279 * @param page The published page 280 * @return The sender 281 */ 282 private String _getSender (User sender, Page page) 283 { 284 if (sender != null && sender.getEmail() != null) 285 { 286 return sender.getFullName() + " <" + sender.getEmail() + ">"; 287 } 288 289 String from = _siteConfiguration.getValueAsString(page.getSiteName(), "site-mail-from"); 290 if (StringUtils.isBlank(from)) 291 { 292 from = Config.getInstance().getValueAsString("smtp.mail.from"); 293 } 294 return from; 295 } 296 297 /** 298 * Get the email subject 299 * @param sender The user responsible for the notification 300 * @param page The published page 301 * @return The email subject 302 */ 303 private String _getSubject (User sender, Page page) 304 { 305 Site site = page.getSite(); 306 307 Map<String, I18nizableText> subjectI18nParameters = new HashMap<>(); 308 subjectI18nParameters.put("user", new I18nizableText(sender.getFullName())); 309 subjectI18nParameters.put("siteTitle", new I18nizableText(site.getTitle())); 310 subjectI18nParameters.put("pageTitle", new I18nizableText(page.getTitle())); 311 312 I18nizableText msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_SUBJECT", subjectI18nParameters); 313 314 return _i18nUtils.translate(msg, page.getSitemapName()); 315 } 316 317 /** 318 * Get the email body 319 * @param sender The user responsible for the notification 320 * @param user The recipient of the notification 321 * @param page The published page 322 * @param comment The user's comment. Can be empty or null. 323 * @return The email body 324 */ 325 private String _getBody (User sender, User user, Page page, String comment) 326 { 327 Site site = page.getSite(); 328 329 Map<String, I18nizableText> bodyI18nParameters = new HashMap<>(); 330 bodyI18nParameters.put("sender", new I18nizableText(sender.getFullName())); 331 bodyI18nParameters.put("user", new I18nizableText(user.getFullName())); 332 bodyI18nParameters.put("siteTitle", new I18nizableText(site.getTitle())); 333 bodyI18nParameters.put("siteUrl", new I18nizableText(site.getUrl())); 334 bodyI18nParameters.put("pageTitle", new I18nizableText(page.getTitle())); 335 bodyI18nParameters.put("pageUrl", new I18nizableText(site.getUrl() + "/" + page.getSitemap().getName() + "/" + page.getPathInSitemap() + ".html")); 336 337 I18nizableText msg = null; 338 if (StringUtils.isNotEmpty(comment)) 339 { 340 bodyI18nParameters.put("comment", new I18nizableText(comment)); 341 msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY_WITH_COMMENT", bodyI18nParameters); 342 } 343 else 344 { 345 msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY", bodyI18nParameters); 346 } 347 348 return _i18nUtils.translate(msg, page.getSitemapName()); 349 } 350 351 private Set<User> _getDistinctUsers (List<UserIdentity> userIdentities, List<GroupIdentity> groupIdentities) 352 { 353 Set<User> users = new HashSet<>(); 354 355 for (UserIdentity userIdentity : userIdentities) 356 { 357 if (userIdentity != null && StringUtils.isNotEmpty(userIdentity.getLogin()) && StringUtils.isNotEmpty(userIdentity.getPopulationId())) 358 { 359 User user = _foUsersManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 360 if (user != null) 361 { 362 users.add(user); 363 } 364 } 365 } 366 367 for (GroupIdentity groupIdentity : groupIdentities) 368 { 369 if (groupIdentity != null && StringUtils.isNotEmpty(groupIdentity.getId()) && StringUtils.isNotEmpty(groupIdentity.getDirectoryId())) 370 { 371 Group group = _foGroupsManager.getGroup(groupIdentity.getDirectoryId(), groupIdentity.getId()); 372 if (group != null) 373 { 374 Set<UserIdentity> groupUsers = group.getUsers(); 375 for (UserIdentity userIdentity : groupUsers) 376 { 377 User user = _foUsersManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 378 if (user != null) 379 { 380 users.add(user); 381 } 382 } 383 } 384 } 385 } 386 387 return users; 388 } 389}