/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/rwiki/trunk/rwiki-impl/impl/src/java/uk/ac/cam/caret/sakai/rwiki/component/service/impl/SiteEmailNotificationRWiki.java $ * $Id: SiteEmailNotificationRWiki.java 126326 2013-06-27 12:27:39Z azeckoski@unicon.net $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation. * * Licensed under the Educational Community License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ecl1.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package uk.ac.cam.caret.sakai.rwiki.component.service.impl; import java.text.DateFormat; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Vector; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.sakaiproject.authz.api.SecurityService; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.email.api.DigestService; import org.sakaiproject.entity.api.EntityManager; import org.sakaiproject.entity.api.Reference; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.event.api.Event; import org.sakaiproject.event.api.NotificationAction; import org.sakaiproject.event.api.NotificationService; import org.sakaiproject.exception.IdUnusedException; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SitePage; import org.sakaiproject.site.api.SiteService; import org.sakaiproject.site.api.ToolConfiguration; import org.sakaiproject.thread_local.api.ThreadLocalManager; import org.sakaiproject.time.api.TimeService; import org.sakaiproject.tool.api.Tool; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserDirectoryService; import org.sakaiproject.user.api.UserNotDefinedException; import org.sakaiproject.util.api.FormattedText; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.util.SiteEmailNotification; import uk.ac.cam.caret.sakai.rwiki.service.api.RWikiObjectService; import uk.ac.cam.caret.sakai.rwiki.service.api.RenderService; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiEntity; import uk.ac.cam.caret.sakai.rwiki.service.api.model.RWikiObject; import uk.ac.cam.caret.sakai.rwiki.service.message.api.PreferenceService; import uk.ac.cam.caret.sakai.rwiki.utils.DigestHtml; import uk.ac.cam.caret.sakai.rwiki.utils.NameHelper; /** * <p> * SiteEmailNotificationRWiki fills the notification message and headers with * details from the content change that triggered the notification event. * </p> * * @author Sakai Software Development Team * @author ieb */ public class SiteEmailNotificationRWiki extends SiteEmailNotification { public class MessageContent { public String title; public String user; public String content; public String moddate; public String localName; public String url; public String contentHTML; } private static Log log = LogFactory .getLog(SiteEmailNotificationRWiki.class); private RenderService renderService = null; private RWikiObjectService rwikiObjectService = null; private PreferenceService preferenceService = null; private SiteService siteService; private SecurityService securityService; private EntityManager entityManager; private ThreadLocalManager threadLocalManager; private TimeService timeService; private DigestService digestService; private UserDirectoryService userDirectoryService; private FormattedText formattedText = (FormattedText) ComponentManager.get(FormattedText.class); private ToolManager toolManager = (ToolManager) ComponentManager.get(ToolManager.class); private static ResourceLoader rl = new ResourceLoader("uk.ac.cam.caret.sakai.rwiki.component.bundle.Messages"); /** * Construct. */ public SiteEmailNotificationRWiki(RWikiObjectService rwikiObjectService, RenderService renderService, PreferenceService preferenceService, SiteService siteService, SecurityService securityService, EntityManager entityManager, ThreadLocalManager threadLocalManager, TimeService timeService, DigestService digestService, UserDirectoryService userDirectoryService) { this.renderService = renderService; this.rwikiObjectService = rwikiObjectService; this.preferenceService = preferenceService; this.siteService = siteService; this.securityService = securityService; this.entityManager = entityManager; this.threadLocalManager = threadLocalManager; this.timeService = timeService; this.digestService = digestService; this.userDirectoryService = userDirectoryService; } /** * Construct. */ public SiteEmailNotificationRWiki(RWikiObjectService rwikiObjectService, RenderService renderService, PreferenceService preferenceService, SiteService siteService, SecurityService securityService, EntityManager entityManager, ThreadLocalManager threadLocalManager, TimeService timeService, DigestService digestService, UserDirectoryService userDirectoryService, String siteId) { super(siteId); this.renderService = renderService; this.rwikiObjectService = rwikiObjectService; this.preferenceService = preferenceService; this.siteService = siteService; this.securityService = securityService; this.entityManager = entityManager; this.threadLocalManager = threadLocalManager; this.timeService = timeService; this.digestService = digestService; this.userDirectoryService = userDirectoryService; } /** * @inheritDoc */ public NotificationAction getClone() { SiteEmailNotificationRWiki clone = new SiteEmailNotificationRWiki( rwikiObjectService, renderService, preferenceService, siteService, securityService, entityManager, threadLocalManager, timeService, digestService, userDirectoryService); clone.set(this); return clone; } protected String getSiteId(String context) { if (context.startsWith("/site/")) //$NON-NLS-1$ { context = context.substring("/site/".length()); //$NON-NLS-1$ } int il = context.indexOf("/"); //$NON-NLS-1$ if (il != -1) { context = context.substring(0, il); } return context; } /** * @inheritDoc */ protected String getPlainMessage(Event event) { MessageContent mc = getMessageContent(event); StringBuilder message = new StringBuilder(); message.append(rl.getString("SiteEmailNotificationRWiki.5")) .append(mc.title) .append(rl.getString("SiteEmailNotificationRWiki.6")) .append(ServerConfigurationService.getString("ui.service", "Sakai")) .append(" (") .append(ServerConfigurationService.getPortalUrl()) .append(") \n\n") .append(rl.getString("SiteEmailNotificationRWiki.13")) .append(mc.title) .append("\" > ") .append(getWikiToolPageName(event)) .append(" > ") .append(mc.localName) .append("\n") .append(rl.getString("SiteEmailNotificationRWiki.16")) .append(mc.moddate) .append("\n") .append(rl.getString("SiteEmailNotificationRWiki.18")) .append(mc.user) .append("\n \n") .append(rl.getString("SiteEmailNotificationRWiki.19")) .append(mc.localName) .append(" ") .append(mc.url) .append(" \n \n") .append(rl.getString("SiteEmailNotificationRWiki.4")) .append(mc.content) .append("\n"); log.debug("Message is " + message); return message.toString(); } protected String getHtmlMessage(Event event) { MessageContent mc = getMessageContent(event); StringBuilder sb = new StringBuilder(); sb.append(rl.getString("SiteEmailNotificationRWiki.5")) .append(mc.title) .append(rl.getString("SiteEmailNotificationRWiki.6")) .append(ServerConfigurationService.getString("ui.service", "Sakai")) .append(" (") .append(ServerConfigurationService.getPortalUrl()) .append(") \n\n") .append(rl.getString("SiteEmailNotificationRWiki.13")) .append(mc.title) .append("\" > ") .append(getWikiToolPageName(event)) .append(" > ") .append(mc.localName) .append("\n") .append(rl.getString("SiteEmailNotificationRWiki.16")) .append(mc.moddate) .append("\n") .append(rl.getString("SiteEmailNotificationRWiki.18")) .append(mc.user) .append("\n \n") .append(rl.getString("SiteEmailNotificationRWiki.19")) .append(mc.localName) .append(" ") .append(mc.url) .append(" \n \n") .append(rl.getString("SiteEmailNotificationRWiki.4")) .append(mc.content) .append("\n"); String message = formattedText.escapeHtml(sb.toString(), true); log.debug("Message is " + message); return message; } private MessageContent getMessageContent(Event event) { MessageContent messageContent = new MessageContent(); // get the content & properties Reference ref = entityManager.newReference(event.getResource()); ResourceProperties props = ref.getProperties(); // get the function // String function = event.getEvent(); // use either the configured site, or if not configured, the site // (context) of the resource String siteId = (getSite() != null) ? getSite() : getSiteId(ref .getContext()); try { Site site = siteService.getSite(siteId); messageContent.title = site.getTitle(); } catch (IdUnusedException e) { messageContent.title = siteId; } // get the URL and resource name. // StringBuffer buf = new StringBuffer(); messageContent.url = ref.getUrl() + "html"; //$NON-NLS-1$ String pageName = props.getProperty(RWikiEntity.RP_NAME); String realm = props.getProperty(RWikiEntity.RP_REALM); messageContent.localName = NameHelper.localizeName(pageName, realm); String userId = props.getProperty(RWikiEntity.RP_USER); try { User u = userDirectoryService.getUser(userId); messageContent.user = u.getDisplayId(); } catch (UserNotDefinedException e) { messageContent.user = userId; } Date date = new Date(Long.parseLong(props.getProperty(RWikiEntity.RP_VERSION))); messageContent.moddate = DateFormat.getDateInstance(DateFormat.FULL, rl.getLocale()).format(date); try { RWikiEntity rwe = (RWikiEntity) rwikiObjectService.getEntity(ref); RWikiObject rwikiObject = rwe.getRWikiObject(); String pageSpace = NameHelper.localizeSpace(pageName, realm); ComponentPageLinkRenderImpl cplr = new ComponentPageLinkRenderImpl( pageSpace, true); messageContent.contentHTML = renderService.renderPage(rwikiObject, pageSpace, cplr); messageContent.content = DigestHtml.digest(messageContent.contentHTML); } catch (Exception ex) { } return messageContent; } @Override protected String plainTextContent(Event event) { return getPlainMessage(event); } @Override protected String htmlContent(Event event) { return getHtmlMessage(event); } /** * @inheritDoc */ protected List<String> getHeaders(Event e) { List<String> rv = super.getHeaders(e); Reference ref = entityManager.newReference(e.getResource()); ResourceProperties props = ref.getProperties(); String pageName = props.getProperty(RWikiEntity.RP_NAME); String realm = props.getProperty(RWikiEntity.RP_REALM); String localName = NameHelper.localizeName(pageName, realm); StringBuilder subjectHeader = new StringBuilder(); subjectHeader.append(rl.getString("SiteEmailNotificationRWiki.37", "Subject: ")) .append(rl.getString("SiteEmailNotificationRWiki.27")) .append(localName) .append(rl.getString("SiteEmailNotificationRWiki.28")); // the Subject rv.add(subjectHeader.toString()); // from rv.add(getFrom(e)); // to rv.add(getTo(e)); return rv; } /** * @inheritDoc */ protected String getTag(String title, boolean shouldUseHtml) { // tag the message StringBuilder rv = new StringBuilder(); if (shouldUseHtml) { rv.append("<hr/><br/>") .append(rl.getString("SiteEmailNotificationRWiki.30")) .append(ServerConfigurationService.getString("ui.service", "Sakai")) .append(" (<a href=\"") .append(ServerConfigurationService.getPortalUrl()) .append("\">") .append(ServerConfigurationService.getPortalUrl()) .append("</a>") .append(rl.getString("SiteEmailNotificationRWiki.3")) .append(rl.getString("SiteEmailNotificationRWiki.35")) .append(rl.getString("SiteEmailNotificationRWiki.36")) .append("<br/>"); } else { rv.append("----------------------\n") .append(rl.getString("SiteEmailNotificationRWiki.30")) .append(ServerConfigurationService.getString("ui.service", "Sakai")) .append(" (") .append(ServerConfigurationService.getPortalUrl()) .append(rl.getString("SiteEmailNotificationRWiki.3")) .append(rl.getString("SiteEmailNotificationRWiki.35")) .append(rl.getString("SiteEmailNotificationRWiki.36")); } return rv.toString(); } protected int getOption(User user, String notificationId, String resourceFilter, int eventPriority, Event event) { // FIXME I don't think this should be here, but it certainly shouldn't // be in preferenceService // We really want a entity reference to page name, without going via the // db! String resourceReference = event.getResource(); if (resourceReference == null || !resourceReference .startsWith(RWikiObjectService.REFERENCE_ROOT) || resourceReference.length() == RWikiObjectService.REFERENCE_ROOT .length()) { return NotificationService.PREF_IGNORE; } resourceReference = resourceReference.substring( RWikiObjectService.REFERENCE_ROOT.length(), resourceReference .lastIndexOf('.')); String preference = preferenceService.findPreferenceAt(user.getId(), resourceReference, PreferenceService.MAIL_NOTIFCIATION); if (preference == null || "".equals(preference)) //$NON-NLS-1$ { return NotificationService.PREF_IGNORE; } if (PreferenceService.NONE_PREFERENCE.equals(preference)) { return NotificationService.PREF_IGNORE; } if (PreferenceService.DIGEST_PREFERENCE.equals(preference)) { return NotificationService.PREF_DIGEST; } if (PreferenceService.SEPARATE_PREFERENCE.equals(preference)) { return NotificationService.PREF_IMMEDIATE; } return NotificationService.PREF_IGNORE; } /** * @inheritDoc */ protected List getRecipients(Event event) { // get the resource reference Reference ref = entityManager.newReference(event.getResource()); // use either the configured site, or if not configured, the site // (context) of the resource String siteId = getSite(); if (siteId == null) { siteId = getSiteId(ref.getContext()); } // if the site is published, use the list of users who can SITE_VISIT // the site, // else use the list of users who can SITE_VISIT_UNP the site. try { Site site = siteService.getSite(siteId); String ability = SiteService.SITE_VISIT; if (!site.isPublished()) { ability = SiteService.SITE_VISIT_UNPUBLISHED; } // get the list of users who can do the right kind of visit List users = securityService.unlockUsers(ability, ref .getReference()); // get the list of users who have the appropriate access to the // resource if (getResourceAbility() != null) { List users2 = securityService.unlockUsers(getResourceAbility(), ref.getReference()); // find intersection of users and user2 users.retainAll(users2); } // add any other users addSpecialRecipients(users, ref); return users; } catch (Exception any) { log.error("Exception in getRecipients()", any); //$NON-NLS-1$ return new Vector(); } } /** * Get the wiki tool's page name * * @param event Event the event * @return the name of the wiki tool's page */ private String getWikiToolPageName(Event event) { String toolName = "Wiki"; Tool tool = toolManager.getCurrentTool(); if (tool != null) { toolName = tool.getTitle(); String toolId = tool.getId(); // sakai.rwiki // get the site id String siteId = getSite(); if (StringUtils.isEmpty(siteId)) { Reference ref = entityManager.newReference(event.getResource()); siteId = getSiteId(ref.getContext()); } if (StringUtils.isNotEmpty(siteId)) { try { Site site = siteService.getSite(siteId); List<SitePage> pages = site.getPages(); for (SitePage p : pages) { Collection<ToolConfiguration> toolConfigurations = p.getTools(new String[] {toolId}); // if tool exists in this page, get the page title if (CollectionUtils.isNotEmpty(toolConfigurations)) { toolName = p.getTitle(); break; } } } catch (IdUnusedException e) { log.error("Site not found while getting wiki name", e); } } } return toolName; } }