001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/content/tags/sakai_2-4-1/content-impl/impl/src/java/org/sakaiproject/content/impl/SiteEmailNotificationContent.java $
003: * $Id: SiteEmailNotificationContent.java 13806 2006-08-17 02:48:04Z ggolden@umich.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2003, 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.content.impl;
021:
022: import java.util.List;
023: import java.util.ResourceBundle;
024: import java.util.Vector;
025:
026: import org.sakaiproject.authz.cover.SecurityService;
027: import org.sakaiproject.component.cover.ServerConfigurationService;
028: import org.sakaiproject.content.api.ContentCollection;
029: import org.sakaiproject.content.cover.ContentHostingService;
030: import org.sakaiproject.entity.api.Entity;
031: import org.sakaiproject.entity.api.Reference;
032: import org.sakaiproject.entity.api.ResourceProperties;
033: import org.sakaiproject.entity.cover.EntityManager;
034: import org.sakaiproject.event.api.Event;
035: import org.sakaiproject.event.api.NotificationAction;
036: import org.sakaiproject.site.api.Site;
037: import org.sakaiproject.site.cover.SiteService;
038: import org.sakaiproject.util.SiteEmailNotification;
039: import org.sakaiproject.util.StringUtil;
040:
041: /**
042: * <p>
043: * SiteEmailNotificationContent fills the notification message and headers with details from the content change that triggered the notification event.
044: * </p>
045: *
046: * @author Sakai Software Development Team
047: */
048: public class SiteEmailNotificationContent extends SiteEmailNotification {
049: private static ResourceBundle rb = ResourceBundle
050: .getBundle("siteemacon");
051:
052: /**
053: * Construct.
054: */
055: public SiteEmailNotificationContent() {
056: }
057:
058: /**
059: * Construct.
060: */
061: public SiteEmailNotificationContent(String siteId) {
062: super (siteId);
063: }
064:
065: /**
066: * @inheritDoc
067: */
068: protected String getResourceAbility() {
069: return ContentHostingService.EVENT_RESOURCE_READ;
070: }
071:
072: /**
073: * @inheritDoc
074: */
075: public NotificationAction getClone() {
076: SiteEmailNotificationContent clone = new SiteEmailNotificationContent();
077: clone.set(this );
078:
079: return clone;
080: }
081:
082: /**
083: * @inheritDoc
084: */
085: protected String getMessage(Event event) {
086: // get the content & properties
087: Reference ref = EntityManager.newReference(event.getResource());
088: ResourceProperties props = ref.getProperties();
089:
090: // get the function
091: String function = event.getEvent();
092:
093: // use either the configured site, or if not configured, the site (context) of the resource
094: String siteId = (getSite() != null) ? getSite() : ref
095: .getContext();
096:
097: // get a site title
098: String title = siteId;
099: try {
100: Site site = SiteService.getSite(siteId);
101: title = site.getTitle();
102: } catch (Exception ignore) {
103: }
104:
105: // get the URL and resource name.
106: StringBuffer buf = new StringBuffer();
107: String url = ref.getUrl();
108: String resourceName = props
109: .getPropertyFormatted(ResourceProperties.PROP_DISPLAY_NAME);
110:
111: // get the resource copyright alert property
112: boolean copyrightAlert = props
113: .getProperty(ResourceProperties.PROP_COPYRIGHT_ALERT) != null ? true
114: : false;
115:
116: // Now build up the message text.
117: if (ContentHostingService.EVENT_RESOURCE_ADD.equals(function)) {
118: buf.append(rb.getString("anewres"));
119: } else {
120: buf.append(rb.getString("anewres2"));
121: }
122: buf.append(" ");
123: buf.append(rb.getString("the"));
124: buf.append(" \"");
125: buf.append(title);
126: buf.append("\" ");
127: buf.append(rb.getString("sitat"));
128: buf.append(" ");
129: buf.append(ServerConfigurationService.getString("ui.service",
130: "Sakai"));
131: buf.append(" (");
132: buf.append(ServerConfigurationService.getPortalUrl());
133: buf.append(")\n");
134:
135: // add location
136: String path = constructPath(ref.getReference());
137: buf.append("\n" + rb.getString("locsit") + " \"" + title
138: + "\" > " + rb.getString("reso") + " " + path + " > "
139: + resourceName);
140: if (copyrightAlert) {
141: buf.append(" (c)");
142: }
143: buf.append("\n");
144:
145: // resource description
146: String description = props
147: .getPropertyFormatted(ResourceProperties.PROP_DESCRIPTION);
148: if ((description != null) && (description.length() > 0)) {
149: buf.append("\n" + rb.getString("descrip") + " "
150: + description + "\n");
151: }
152:
153: // add a reference to the resource
154: buf.append("\n" + rb.getString("resour") + " " + resourceName);
155: if (copyrightAlert) {
156: buf.append(" (c)");
157: }
158: buf.append(" " + url);
159: buf.append("\n");
160:
161: return buf.toString();
162: }
163:
164: /**
165: * @inheritDoc
166: */
167: protected List getHeaders(Event event) {
168: List rv = new Vector();
169:
170: // the Subject
171: rv.add("Subject: " + getSubject(event));
172:
173: // from
174: rv.add(getFrom(event));
175:
176: // to
177: rv.add(getTo(event));
178:
179: return rv;
180: }
181:
182: /**
183: * @inheritDoc
184: */
185: protected String getTag(String newline, String title) {
186: // tag the message
187: String rv = newline
188: + rb.getString("separator")
189: + newline
190: + rb.getString("this")
191: + " "
192: + ServerConfigurationService.getString("ui.service",
193: "Sakai") + " ("
194: + ServerConfigurationService.getPortalUrl() + ") "
195: + rb.getString("forthe") + " " + title + " "
196: + rb.getString("site") + newline
197: + rb.getString("youcan") + newline;
198: return rv;
199: }
200:
201: /**
202: * Form a "Bread Crumb" style path showing the folders in which this referenced resource lives.
203: *
204: * @param ref
205: * The reference string to the resource.
206: * @return The path string for this resource.
207: */
208: protected String constructPath(String ref) {
209: StringBuffer buf = new StringBuffer();
210:
211: // expect the ref to be /content/group/site/folder/folder2/folderEtc/file.ext
212: String[] parts = StringUtil.split(ref, Entity.SEPARATOR);
213:
214: // 0 is null, 1 is "content", 2 is "group" or whatever, 3 is the site, the last is the file name
215: if (parts.length > 4) {
216: // grow this collection id as we descend into the collections
217: String root = Entity.SEPARATOR + parts[2]
218: + Entity.SEPARATOR + parts[3] + Entity.SEPARATOR;
219:
220: // take all the collection parts
221: for (int i = 4; i < parts.length - 1; i++) {
222: buf.append(" > ");
223: String collectionId = parts[i];
224: root = root + collectionId + Entity.SEPARATOR;
225: try {
226: // get the display name
227: ContentCollection collection = ContentHostingService
228: .getCollection(root);
229: buf
230: .append(collection
231: .getProperties()
232: .getPropertyFormatted(
233: ResourceProperties.PROP_DISPLAY_NAME));
234: } catch (Exception any) {
235: // use the id if there's a problem
236: buf.append(collectionId);
237: }
238: }
239: }
240:
241: return buf.toString();
242: }
243:
244: /**
245: * Get the subject for the email.
246: *
247: * @param event
248: * The event that matched criteria to cause the notification.
249: * @return the subject for the email.
250: */
251: protected String getSubject(Event event) {
252: Reference ref = EntityManager.newReference(event.getResource());
253: Entity r = ref.getEntity();
254: ResourceProperties props = ref.getProperties();
255:
256: // get the function
257: String function = event.getEvent();
258:
259: // use either the configured site, or if not configured, the site (context) of the resource
260: String siteId = (getSite() != null) ? getSite() : ref
261: .getContext();
262:
263: // get a site title
264: String title = siteId;
265: try {
266: Site site = SiteService.getSite(siteId);
267: title = site.getTitle();
268: } catch (Exception ignore) {
269: }
270:
271: // use the message's subject
272: String resourceName = props
273: .getPropertyFormatted(ResourceProperties.PROP_DISPLAY_NAME);
274: return "[ "
275: + title
276: + " - "
277: + (ContentHostingService.EVENT_RESOURCE_ADD
278: .equals(function) ? rb.getString("new") : rb
279: .getString("chan")) + " "
280: + rb.getString("reso2") + " ] " + resourceName;
281: }
282:
283: /**
284: * Add to the user list any other users who should be notified about this ref's change.
285: *
286: * @param users
287: * The user list, already populated based on site visit and resource ability.
288: * @param ref
289: * The entity reference.
290: */
291: protected void addSpecialRecipients(List users, Reference ref) {
292: // include any users who have AnnouncementService.SECURE_ALL_GROUPS and getResourceAbility() in the context
293: String contextRef = SiteService.siteReference(ref.getContext());
294:
295: // get the list of users who have SECURE_ALL_GROUPS
296: List allGroupUsers = SecurityService.unlockUsers(
297: ContentHostingService.AUTH_RESOURCE_ALL_GROUPS,
298: contextRef);
299:
300: // filter down by the permission
301: if (getResourceAbility() != null) {
302: List allGroupUsers2 = SecurityService.unlockUsers(
303: getResourceAbility(), contextRef);
304: allGroupUsers.retainAll(allGroupUsers2);
305: }
306:
307: // remove any in the list already
308: allGroupUsers.removeAll(users);
309:
310: // combine
311: users.addAll(allGroupUsers);
312: }
313: }
|