001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/portal/trunk/portal-util/util/src/java/org/sakaiproject/portal/util/PortalSiteHelper.java $
003: * $Id: PortalSiteHelper.java 21708 2007-02-18 21:59:28Z ian@caret.cam.ac.uk $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2007 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.chat2.model.impl;
021:
022: import java.sql.Connection;
023: import java.sql.PreparedStatement;
024: import java.util.ArrayList;
025: import java.util.Calendar;
026: import java.util.Collections;
027: import java.util.Comparator;
028: import java.util.Date;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.HashMap;
033: import java.util.Observable;
034: import java.util.Observer;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038: import org.hibernate.Criteria;
039: import org.hibernate.Session;
040: import org.hibernate.criterion.Expression;
041: import org.hibernate.criterion.Order;
042: import org.sakaiproject.authz.cover.FunctionManager;
043: import org.sakaiproject.authz.cover.SecurityService;
044: import org.sakaiproject.chat2.model.ChatChannel;
045: import org.sakaiproject.chat2.model.ChatManager;
046: import org.sakaiproject.chat2.model.RoomObserver;
047: import org.sakaiproject.chat2.model.ChatFunctions;
048: import org.sakaiproject.chat2.model.ChatMessage;
049: import org.sakaiproject.component.cover.ServerConfigurationService;
050: import org.sakaiproject.entity.api.EntityManager;
051: import org.sakaiproject.entity.api.Reference;
052: import org.sakaiproject.entity.api.Summary;
053: import org.sakaiproject.event.api.Event;
054: import org.sakaiproject.event.cover.EventTrackingService;
055: import org.sakaiproject.exception.IdInvalidException;
056: import org.sakaiproject.exception.IdUsedException;
057: import org.sakaiproject.exception.PermissionException;
058:
059: import org.sakaiproject.site.api.ToolConfiguration;
060: import org.sakaiproject.site.cover.SiteService;
061: import org.sakaiproject.time.api.Time;
062: import org.sakaiproject.time.cover.TimeService;
063: import org.sakaiproject.tool.cover.SessionManager;
064: import org.sakaiproject.tool.api.ToolManager;
065: import org.sakaiproject.user.api.User;
066: import org.sakaiproject.user.api.UserNotDefinedException;
067: import org.sakaiproject.user.cover.UserDirectoryService;
068: import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
069: import org.springframework.transaction.support.TransactionSynchronizationAdapter;
070: import org.springframework.transaction.support.TransactionSynchronizationManager;
071:
072: /**
073: *
074: * @author andersjb
075: *
076: */
077: public class ChatManagerImpl extends HibernateDaoSupport implements
078: ChatManager, Observer {
079:
080: protected final transient Log logger = LogFactory
081: .getLog(getClass());
082:
083: /** the key for sending message events around */
084: //protected final static String EVENT_CHAT_SEND_MESSAGE = "sakai.chat.message";
085: //protected final static String EVENT_CHAT_SEND_MESSAGE = "chat.new";
086: //protected final static String EVENT_CHAT_DELETE_CHANNEL = "sakai.chat.delete.channel";
087:
088: /** The tool manager */
089: private ToolManager toolManager;
090:
091: /** the clients listening to the various rooms */
092: protected Map roomListeners = new HashMap();
093:
094: private EntityManager entityManager;
095:
096: private ChatChannel defaultChannelSettings;
097:
098: static Comparator channelComparatorAsc = new Comparator() {
099: public int compare(Object o1, Object o2) {
100: return ((ChatMessage) o1).getMessageDate().compareTo(
101: ((ChatMessage) o2).getMessageDate());
102: }
103: };
104:
105: static Comparator channelComparatorDesc = new Comparator() {
106: public int compare(Object o1, Object o2) {
107: return -1
108: * ((ChatMessage) o1).getMessageDate().compareTo(
109: ((ChatMessage) o2).getMessageDate());
110: }
111: };
112:
113: /**
114: * Called on after the startup of the singleton. This sets the global
115: * list of functions which will have permission managed by sakai
116: * @throws Exception
117: */
118: protected void init() throws Exception {
119: logger.info("init()");
120:
121: try {
122:
123: EventTrackingService.addObserver(this );
124:
125: // register functions
126: if (FunctionManager.getRegisteredFunctions(
127: ChatFunctions.CHAT_FUNCTION_PREFIX).size() == 0) {
128: FunctionManager
129: .registerFunction(ChatFunctions.CHAT_FUNCTION_READ);
130: FunctionManager
131: .registerFunction(ChatFunctions.CHAT_FUNCTION_NEW);
132: FunctionManager
133: .registerFunction(ChatFunctions.CHAT_FUNCTION_DELETE_ANY);
134: FunctionManager
135: .registerFunction(ChatFunctions.CHAT_FUNCTION_DELETE_OWN);
136: FunctionManager
137: .registerFunction(ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL);
138: FunctionManager
139: .registerFunction(ChatFunctions.CHAT_FUNCTION_NEW_CHANNEL);
140: FunctionManager
141: .registerFunction(ChatFunctions.CHAT_FUNCTION_EDIT_CHANNEL);
142: }
143:
144: } catch (Exception e) {
145: logger.warn("Error with ChatManager.init()", e);
146: }
147:
148: }
149:
150: /**
151: * Destroy
152: */
153: public void destroy() {
154: EventTrackingService.deleteObserver(this );
155:
156: logger.info("destroy()");
157: }
158:
159: /**
160: * {@inheritDoc}
161: */
162: public ChatChannel createNewChannel(String context, String title,
163: boolean contextDefaultChannel, boolean checkAuthz)
164: throws PermissionException {
165: if (checkAuthz)
166: checkPermission(ChatFunctions.CHAT_FUNCTION_NEW_CHANNEL);
167:
168: ChatChannel channel = new ChatChannel(
169: getDefaultChannelSettings());
170:
171: channel.setCreationDate(new Date());
172: channel.setContext(context);
173: channel.setTitle(title);
174: channel.setContextDefaultChannel(contextDefaultChannel);
175:
176: return channel;
177: }
178:
179: /**
180: * {@inheritDoc}
181: */
182: public void updateChannel(ChatChannel channel, boolean checkAuthz)
183: throws PermissionException {
184:
185: if (checkAuthz)
186: checkPermission(ChatFunctions.CHAT_FUNCTION_EDIT_CHANNEL);
187:
188: getHibernateTemplate().saveOrUpdate(channel);
189: }
190:
191: /**
192: * {@inheritDoc}
193: */
194: public void deleteChannel(ChatChannel channel)
195: throws PermissionException {
196:
197: checkPermission(ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL);
198: getHibernateTemplate().delete(channel);
199:
200: sendDeleteChannel(channel);
201: }
202:
203: /**
204: * {@inheritDoc}
205: */
206: public ChatChannel getChatChannel(String chatChannelId) {
207: return (ChatChannel) getHibernateTemplate().get(
208: ChatChannel.class, chatChannelId);
209: }
210:
211: public Date calculateDateByOffset(int offset) {
212: Calendar tmpDate = Calendar.getInstance();
213: tmpDate.set(Calendar.DAY_OF_MONTH, tmpDate
214: .get(Calendar.DAY_OF_MONTH)
215: - offset);
216: return new Date(tmpDate.getTimeInMillis());
217: }
218:
219: /**
220: * {@inheritDoc}
221: */
222: public List<ChatMessage> getChannelMessages(ChatChannel channel,
223: String context, Date date, int items, boolean sortAsc)
224: throws PermissionException {
225: if (channel == null) {
226: List<ChatMessage> allMessages = new ArrayList<ChatMessage>();
227: List channels = getContextChannels(context, true);
228: for (Iterator i = channels.iterator(); i.hasNext();) {
229: ChatChannel tmpChannel = (ChatChannel) i.next();
230: allMessages.addAll(getChannelMessages(tmpChannel, date,
231: items, sortAsc));
232: }
233:
234: if (sortAsc)
235: Collections.sort(allMessages, channelComparatorAsc);
236: else
237: Collections.sort(allMessages, channelComparatorDesc);
238: return allMessages;
239: } else
240: return getChannelMessages(channel, date, items, sortAsc);
241: }
242:
243: /**
244: *
245: * @see getChannelMessages
246: */
247: protected List<ChatMessage> getChannelMessages(ChatChannel channel,
248: Date date, int items, boolean sortAsc)
249: throws PermissionException {
250: checkPermission(ChatFunctions.CHAT_FUNCTION_READ);
251: int localItems = items;
252: Date localDate = date;
253:
254: Criteria c = this .getSession()
255: .createCriteria(ChatMessage.class);
256:
257: // Find out which values to use.
258: // If the settings of the channel have more strict values then the passed info, use them instead.
259: if (channel.getFilterType()
260: .equals(ChatChannel.FILTER_BY_NUMBER)) {
261: if (localItems < 0)
262: localItems = Integer.MAX_VALUE;
263: if (!channel.isEnableUserOverride()) {
264: localItems = Math.min(localItems, channel
265: .getFilterParam());
266: }
267: } else if (channel.getFilterType().equals(
268: ChatChannel.FILTER_BY_TIME)) {
269: int days = channel.getFilterParam();
270: Date tmpDate = calculateDateByOffset(days);
271: if (!channel.isEnableUserOverride()) {
272: localDate = tmpDate;
273: }
274: }
275:
276: if (channel != null) {
277: c.add(Expression.eq("chatChannel", channel));
278: }
279: if (localDate != null) {
280: c.add(Expression.ge("messageDate", localDate));
281: }
282:
283: //Always sort desc so we get the newest messages
284: // reorder after we get the final list
285: c.addOrder(Order.desc("messageDate"));
286:
287: List messages = new ArrayList();
288:
289: if (localItems != 0) {
290: if (localItems > 0) {
291: c.setMaxResults(localItems);
292: }
293: messages = c.list();
294: }
295: //Reorder the list
296: if (sortAsc)
297: Collections.sort(messages, channelComparatorAsc);
298: else
299: Collections.sort(messages, channelComparatorDesc);
300:
301: return messages;
302:
303: }
304:
305: /**
306: * {@inheritDoc}
307: */
308: public ChatMessage createNewMessage(ChatChannel channel,
309: String owner) throws PermissionException {
310:
311: checkPermission(ChatFunctions.CHAT_FUNCTION_NEW);
312:
313: ChatMessage message = new ChatMessage();
314:
315: message.setChatChannel(channel);
316: message.setOwner(owner);
317: message.setMessageDate(new Date());
318:
319: return message;
320: }
321:
322: /**
323: * saves a Chat Message
324: * @param ChatMessage the message to update
325: */
326: public void updateMessage(ChatMessage message) {
327: getHibernateTemplate().saveOrUpdate(message);
328: }
329:
330: /**
331: * tells us if the message can be deleted by the current session user
332: */
333: public boolean getCanDelete(ChatMessage message, String placementId) {
334: ToolConfiguration toolConfig = SiteService
335: .findTool(placementId);
336: String context = toolConfig.getContext();
337: boolean canDeleteAny = can(
338: ChatFunctions.CHAT_FUNCTION_DELETE_ANY, context);
339: boolean canDeleteOwn = can(
340: ChatFunctions.CHAT_FUNCTION_DELETE_OWN, context);
341: boolean isOwner = SessionManager.getCurrentSessionUserId()
342: .equals(message.getOwner());
343:
344: boolean canDelete = canDeleteAny;
345:
346: if (canDeleteOwn && isOwner)
347: canDelete = true;
348:
349: return canDelete;
350: }
351:
352: public boolean getCanDelete(ChatMessage message) {
353: return getCanDelete(message, toolManager.getCurrentPlacement()
354: .getId());
355: }
356:
357: /**
358: * tells us if the channel can be deleted by the current session user
359: */
360: public boolean getCanDelete(ChatChannel channel, String placementId) {
361: ToolConfiguration toolConfig = SiteService
362: .findTool(placementId);
363: String context = toolConfig.getContext();
364: boolean canDelete = can(
365: ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL, context);
366:
367: return canDelete;
368: }
369:
370: public boolean getCanDelete(ChatChannel channel) {
371: return getCanDelete(channel, toolManager.getCurrentPlacement()
372: .getId());
373: }
374:
375: protected boolean getCanEdit(ChatChannel channel, String placementId) {
376: ToolConfiguration toolConfig = SiteService
377: .findTool(placementId);
378: String context = toolConfig.getContext();
379: boolean canDelete = can(
380: ChatFunctions.CHAT_FUNCTION_EDIT_CHANNEL, context);
381:
382: return canDelete;
383: }
384:
385: public boolean getCanEdit(ChatChannel channel) {
386: return getCanEdit(channel, toolManager.getCurrentPlacement()
387: .getId());
388: }
389:
390: protected boolean getCanCreateChannel(String placementId) {
391: ToolConfiguration toolConfig = SiteService
392: .findTool(placementId);
393: String context = toolConfig.getContext();
394: boolean canDelete = can(
395: ChatFunctions.CHAT_FUNCTION_NEW_CHANNEL, context);
396:
397: return canDelete;
398: }
399:
400: public boolean getCanCreateChannel() {
401: return getCanCreateChannel(toolManager.getCurrentPlacement()
402: .getId());
403: }
404:
405: protected boolean getCanReadMessage(ChatChannel channel,
406: String context) {
407: boolean canRead = can(ChatFunctions.CHAT_FUNCTION_READ, context);
408:
409: return canRead;
410: }
411:
412: public boolean getCanReadMessage(ChatChannel channel) {
413: return getCanReadMessage(channel, toolManager
414: .getCurrentPlacement().getContext());
415: }
416:
417: /**
418: * delete a Chat Message
419: * @param ChatMessage the message to delete
420: */
421: public void deleteMessage(ChatMessage message)
422: throws PermissionException {
423: if (!getCanDelete(message))
424: checkPermission(ChatFunctions.CHAT_FUNCTION_DELETE_ANY);
425:
426: getHibernateTemplate().delete(message);
427:
428: sendDeleteMessage(message);
429: }
430:
431: /**
432: * {@inheritDoc}
433: */
434: public ChatMessage getMessage(String chatMessageId) {
435: return (ChatMessage) getHibernateTemplate().get(
436: ChatMessage.class, chatMessageId);
437: }
438:
439: /**
440: * {@inheritDoc}
441: */
442: public List getContextChannels(String context, boolean lazy) {
443: List channels = getHibernateTemplate().findByNamedQuery(
444: "findChannelsInContext", context);
445: if (!lazy) {
446: for (Iterator i = channels.iterator(); i.hasNext();) {
447: ChatChannel channel = (ChatChannel) i.next();
448: channel.getMessages().size();
449: }
450: }
451: return channels;
452: }
453:
454: /**
455: * {@inheritDoc}
456: */
457: public List getContextChannels(String context,
458: String defaultNewTitle) {
459: List channels = getHibernateTemplate().findByNamedQuery(
460: "findChannelsInContext", context);
461:
462: if (channels.size() == 0) {
463: try {
464: ChatChannel channel = createNewChannel(context,
465: defaultNewTitle, true, false);
466: getHibernateTemplate().save(channel);
467: channels.add(channel);
468: } catch (PermissionException e) {
469: logger
470: .debug("Ignoring exception since it shouldn't be thrown here as we're not checking");
471: }
472:
473: }
474:
475: return channels;
476: }
477:
478: /**
479: * {@inheritDoc}
480: */
481: public ChatChannel getDefaultChannel(String contextId) {
482: List channels = getHibernateTemplate().findByNamedQuery(
483: "findDefaultChannelsInContext", contextId);
484: if (channels.size() == 0) {
485: channels = getContextChannels(contextId, "");
486: }
487: if (channels.size() >= 1)
488: return (ChatChannel) channels.get(0);
489:
490: return null;
491: }
492:
493: public void addRoomListener(RoomObserver observer, String roomId) {
494: List roomObservers;
495: synchronized (roomListeners) {
496: if (roomListeners.get(roomId) == null)
497: roomListeners.put(roomId, new ArrayList());
498: roomObservers = (List) roomListeners.get(roomId);
499: }
500: synchronized (roomObservers) {
501: roomObservers.add(observer);
502: }
503: }
504:
505: public void removeRoomListener(RoomObserver observer, String roomId) {
506:
507: if (roomListeners.get(roomId) != null) {
508: List roomObservers = (List) roomListeners.get(roomId);
509:
510: if (roomObservers != null) {
511: synchronized (roomObservers) {
512:
513: roomObservers.remove(observer);
514: if (roomObservers.size() == 0) {
515:
516: synchronized (roomListeners) {
517: roomListeners.remove(roomId);
518: }
519:
520: }
521:
522: }
523:
524: } // end if(roomObservers != null)
525: }
526: }
527:
528: /**
529: * {@inheritDoc}
530: */
531: public void sendMessage(ChatMessage message) {
532: ChatMessageTxSync txSync = new ChatMessageTxSync(message);
533:
534: if (TransactionSynchronizationManager.isSynchronizationActive()) {
535: TransactionSynchronizationManager
536: .registerSynchronization(txSync);
537: } else {
538: txSync.afterCompletion(ChatMessageTxSync.STATUS_COMMITTED);
539: }
540: }
541:
542: /**
543: * {@inheritDoc}
544: */
545: public void sendDeleteMessage(ChatMessage message) {
546: ChatMessageDeleteTxSync txSync = new ChatMessageDeleteTxSync(
547: message);
548:
549: if (TransactionSynchronizationManager.isSynchronizationActive()) {
550: TransactionSynchronizationManager
551: .registerSynchronization(txSync);
552: } else {
553: txSync
554: .afterCompletion(ChatMessageDeleteTxSync.STATUS_COMMITTED);
555: }
556: }
557:
558: /**
559: * {@inheritDoc}
560: */
561: public void sendDeleteChannel(ChatChannel channel) {
562: ChatChannelDeleteTxSync txSync = new ChatChannelDeleteTxSync(
563: channel);
564:
565: if (TransactionSynchronizationManager.isSynchronizationActive()) {
566: TransactionSynchronizationManager
567: .registerSynchronization(txSync);
568: } else {
569: txSync
570: .afterCompletion(ChatChannelDeleteTxSync.STATUS_COMMITTED);
571: }
572: }
573:
574: /**
575: * This helps to send out the message when the record is placed in the database
576: * @author andersjb
577: *
578: */
579: private class ChatMessageDeleteTxSync extends
580: TransactionSynchronizationAdapter {
581: private ChatMessage message;
582:
583: public ChatMessageDeleteTxSync(ChatMessage message) {
584: this .message = message;
585: }
586:
587: public void afterCompletion(int status) {
588: Event event = null;
589: String function = ChatFunctions.CHAT_FUNCTION_DELETE_ANY;
590: if (message.getOwner().equals(
591: SessionManager.getCurrentSessionUserId())) {
592: // own or any
593: function = ChatFunctions.CHAT_FUNCTION_DELETE_OWN;
594: }
595:
596: event = EventTrackingService.newEvent(function, message
597: .getReference(), false);
598:
599: if (event != null)
600: EventTrackingService.post(event);
601: }
602: }
603:
604: /**
605: * This helps to send out the message when the record is placed in the database
606: * @author andersjb
607: *
608: */
609: private class ChatMessageTxSync extends
610: TransactionSynchronizationAdapter {
611: private ChatMessage message;
612:
613: public ChatMessageTxSync(ChatMessage message) {
614: this .message = message;
615: }
616:
617: public void afterCompletion(int status) {
618: Event event = null;
619: event = EventTrackingService.newEvent(
620: ChatFunctions.CHAT_FUNCTION_NEW, message
621: .getReference(), false);
622:
623: if (event != null)
624: EventTrackingService.post(event);
625: }
626: }
627:
628: /**
629: * This helps to send out the message when the record is placed in the database
630: * @author andersjb
631: *
632: */
633: private class ChatChannelDeleteTxSync extends
634: TransactionSynchronizationAdapter {
635: private ChatChannel channel;
636:
637: public ChatChannelDeleteTxSync(ChatChannel channel) {
638: this .channel = channel;
639: }
640:
641: public void afterCompletion(int status) {
642: Event event = null;
643: event = EventTrackingService.newEvent(
644: ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL, channel
645: .getReference(), false);
646:
647: if (event != null)
648: EventTrackingService.post(event);
649: }
650: }
651:
652: /**
653: * This method is called whenever the observed object is changed. An
654: * application calls an <tt>Observable</tt> object's
655: * <code>notifyObservers</code> method to have all the object's
656: * observers notified of the change.
657: *
658: * This operates within its own Thread so normal rules and conditions don't apply
659: *
660: * @param o the observable object.
661: * @param arg an argument passed to the <code>notifyObservers</code>
662: * method.
663: */
664: public void update(Observable o, Object arg) {
665: if (arg instanceof Event) {
666: Event event = (Event) arg;
667:
668: Reference ref = getEntityManager().newReference(
669: event.getResource());
670:
671: if (event.getEvent()
672: .equals(ChatFunctions.CHAT_FUNCTION_NEW)) {
673:
674: //String[] messageParams = event.getResource().split(":");
675:
676: List observers = (List) roomListeners.get(ref
677: .getContainer());
678:
679: if (observers != null) {
680: synchronized (observers) {
681: for (Iterator i = observers.iterator(); i
682: .hasNext();) {
683: RoomObserver observer = (RoomObserver) i
684: .next();
685:
686: observer.receivedMessage(
687: ref.getContainer(), ref.getId());
688: }
689: }
690: }
691:
692: } else if (event.getEvent().equals(
693: ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL)) {
694: //String chatChannelId = event.getResource();
695:
696: List observers = (List) roomListeners.get(ref.getId());
697:
698: if (observers != null) {
699: synchronized (observers) {
700: for (Iterator i = observers.iterator(); i
701: .hasNext();) {
702: RoomObserver observer = (RoomObserver) i
703: .next();
704:
705: observer.roomDeleted(ref.getId());
706: }
707: }
708: }
709: }
710: }
711: }
712:
713: /**
714: * Resets the passed context's default channel
715: *
716: */
717: protected void resetContextDefaultChannel(String context) {
718: Session session = null;
719: Connection conn = null;
720: PreparedStatement statement = null;
721:
722: String query = "update CHAT2_CHANNEL c set c.contextDefaultChannel=? WHERE c.context=?";
723:
724: try {
725: session = getSession();
726: conn = session.connection();
727:
728: statement = conn.prepareStatement(query);
729: statement.setBoolean(1, false);
730: statement.setString(2, context);
731: statement.executeUpdate();
732: } catch (Exception e) {
733: logger.warn(e.getMessage());
734: } finally {
735: if (statement != null) {
736: //ensure the statement is closed
737: try {
738: statement.close();
739: } catch (Exception e) {
740: if (logger.isDebugEnabled()) {
741: logger.debug(e);
742: }
743: }
744: }
745: try {
746: if (conn != null)
747: conn.close();
748: } catch (Exception ex) {
749: logger.warn(ex.getMessage());
750: }
751: }
752: }
753:
754: public void makeDefaultContextChannel(ChatChannel channel) {
755: //reset context's defaults
756: if (isMaintainer()) {
757: try {
758: resetContextDefaultChannel(channel.getContext());
759:
760: //set new one as default
761: channel.setContextDefaultChannel(true);
762: updateChannel(channel, false);
763: } catch (PermissionException e) {
764: logger
765: .debug("Ignoring PermissionException since it is unchecked here.");
766: }
767: }
768: }
769:
770: /**
771: * This turns the site id into a realm (/site/<siteId>)
772: * @return siteId
773: */
774: private String getContextSiteId(String context) {
775: //LOG.debug("getContextSiteId()");
776: return ("/site/" + context);
777: }
778:
779: protected void checkPermission(String function)
780: throws PermissionException {
781: String context = toolManager.getCurrentPlacement().getContext();
782: if (!SecurityService
783: .unlock(function, getContextSiteId(context))) {
784: String user = SessionManager.getCurrentSessionUserId();
785: throw new PermissionException(user, function, context);
786: }
787: }
788:
789: protected boolean can(String function, String context) {
790: return SecurityService.unlock(function,
791: getContextSiteId(context));
792: }
793:
794: protected boolean can(String function) {
795: return can(function, toolManager.getCurrentPlacement()
796: .getContext());
797: }
798:
799: /**
800: * {@inheritDoc}
801: */
802: public boolean isMaintainer() {
803: return SecurityService.unlock("site.upd",
804: getContextSiteId(toolManager.getCurrentPlacement()
805: .getContext()));
806: }
807:
808: protected String getSummaryFromHeader(ChatMessage item)
809: throws UserNotDefinedException {
810: String body = item.getBody();
811: if (body.length() > 50)
812: body = body.substring(1, 49);
813: User user = UserDirectoryService.getUser(item.getOwner());
814: Time messageTime = TimeService.newTime(item.getMessageDate()
815: .getTime());
816: String newText = body + ", " + user.getDisplayName() + ", "
817: + messageTime.toStringLocalFull();
818: return newText;
819: }
820:
821: /**********************************************************************************************************************************************************************************************************************************************************
822: * getSummary implementation
823: *********************************************************************************************************************************************************************************************************************************************************/
824: public Map getSummary(String channel, int items, int days)
825: throws IdUsedException, IdInvalidException,
826: PermissionException {
827: long startTime = System.currentTimeMillis()
828: - (days * 24l * 60l * 60l * 1000l);
829:
830: List messages = getChannelMessages(getChatChannel(channel),
831: new Date(startTime), items, true);
832:
833: Iterator iMsg = messages.iterator();
834: Time pubDate = null;
835: String summaryText = null;
836: Map m = new HashMap();
837: while (iMsg.hasNext()) {
838: ChatMessage item = (ChatMessage) iMsg.next();
839: //MessageHeader header = item.getHeader();
840: Time newTime = TimeService.newTime(item.getMessageDate()
841: .getTime());
842: if (pubDate == null || newTime.before(pubDate))
843: pubDate = newTime;
844: try {
845: String newText = getSummaryFromHeader(item);
846: if (summaryText == null) {
847: summaryText = newText;
848: } else {
849: summaryText = summaryText + "<br>\r\n" + newText;
850: }
851: } catch (UserNotDefinedException e) {
852: logger.warn("Skipping the chat message for user: "
853: + item.getOwner()
854: + " since they cannot be found");
855: }
856: }
857: if (pubDate != null) {
858: m.put(Summary.PROP_PUBDATE, pubDate.toStringRFC822Local());
859: }
860: if (summaryText != null) {
861: m.put(Summary.PROP_DESCRIPTION, summaryText);
862: return m;
863: }
864: return null;
865: }
866:
867: public ToolManager getToolManager() {
868: return toolManager;
869: }
870:
871: public void setToolManager(ToolManager toolManager) {
872: this .toolManager = toolManager;
873: }
874:
875: /**
876: * @return the entityManager
877: */
878: public EntityManager getEntityManager() {
879: return entityManager;
880: }
881:
882: /**
883: * @param entityManager the entityManager to set
884: */
885: public void setEntityManager(EntityManager entityManager) {
886: this .entityManager = entityManager;
887: }
888:
889: /**
890: * Access the partial URL that forms the root of resource URLs.
891: *
892: * @param relative
893: * if true, form within the access path only (i.e. starting with /msg)
894: * @return the partial URL that forms the root of resource URLs.
895: */
896: protected String getAccessPoint(boolean relative) {
897: return (relative ? "" : ServerConfigurationService
898: .getAccessUrl())
899: + REFERENCE_ROOT;
900:
901: } // getAccessPoint
902:
903: /**
904: * {@inheritDoc}
905: */
906: public String[] summarizableToolIds() {
907: String[] toolIds = { CHAT_TOOL_ID };
908: return toolIds;
909: }
910:
911: /**
912: * {@inheritDoc}
913: */
914: public String getSummarizableReference(String siteId) {
915: //I think this should just return null so we get all channels.
916: String channel = null;
917: return channel;
918: }
919:
920: /**
921: * {@inheritDoc}
922: */
923: public String getLabel() {
924: return CHAT;
925: }
926:
927: private boolean inputIsValidInteger(String val) {
928: try {
929: Integer.parseInt(val);
930: return true;
931: } catch (Exception e) {
932: return false;
933: }
934: }
935:
936: public String serviceName() {
937: return ChatManager.class.getName();
938: }
939:
940: public ChatChannel getDefaultChannelSettings() {
941: return defaultChannelSettings;
942: }
943:
944: public void setDefaultChannelSettings(
945: ChatChannel defaultChannelSettings) {
946: this.defaultChannelSettings = defaultChannelSettings;
947: }
948:
949: }
|