/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. */ package org.olat.modules.wiki; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import org.olat.basesecurity.BaseSecurityManager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationHelper; import org.olat.core.commons.services.notifications.NotificationsHandler; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.commons.services.notifications.SubscriptionInfo; import org.olat.core.commons.services.notifications.manager.NotificationsUpgradeHelper; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; import org.olat.core.commons.services.notifications.model.TitleItem; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseFactory; import org.olat.course.CourseModule; import org.olat.course.ICourse; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.WikiCourseNode; import org.olat.course.nodes.wiki.WikiEditController; import org.olat.course.run.environment.CourseEnvironment; import org.olat.fileresource.types.WikiResource; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.modules.ModuleConfiguration; import org.olat.modules.fo.ForumNotificationsHandler; import org.olat.modules.fo.Message; import org.olat.modules.fo.manager.ForumManager; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; /** * Description:<br> * To inform users whether a page has been recently changed or created user can subscribe a wiki * a this class evaluates whether something new is available or not. * <P> * Initial Date: Jun 26, 2006 <br> * * @author guido */ public class WikiPageChangeOrCreateNotificationHandler implements NotificationsHandler { private static final OLog log = Tracing.createLoggerFor(WikiPageChangeOrCreateNotificationHandler.class); private static final String CSS_CLASS_WIKI_PAGE_CHANGED_ICON = "o_wiki_icon"; protected String businessControlString; public WikiPageChangeOrCreateNotificationHandler() { // } /** * @see org.olat.core.commons.services.notifications.NotificationsHandler#createSubscriptionInfo(org.olat.core.commons.services.notifications.Subscriber, * java.util.Locale, java.util.Date) */ @Override public SubscriptionInfo createSubscriptionInfo(Subscriber subscriber, final Locale locale, Date compareDate) { Publisher p = subscriber.getPublisher(); final Date latestNews = p.getLatestNewsDate(); Long resId = p.getResId(); SubscriptionInfo si; final boolean debug = log.isDebug(); // there could be news for me, investigate deeper if(debug) log.debug("compareDate=" + compareDate + " ; latestNews=" + latestNews, null); try { if (NotificationsManager.getInstance().isPublisherValid(p) && compareDate.before(latestNews)) { OLATResourceable ores = null; if (p.getResName().equals( CourseModule.getCourseTypeName() ) ) { // resId = CourseResourceableId p.getSubidentifier() = wikiCourseNode.getIdent() ICourse course = CourseFactory.loadCourse(resId); if(!courseStatus(course)) { return NotificationsManager.getInstance().getNoSubscriptionInfo(); } CourseEnvironment cenv = course.getCourseEnvironment(); CourseNode courseNode = cenv.getRunStructure().getNode(p.getSubidentifier()); if(courseNode == null){ //OLAT-3356 because removing wikicoursenodes was not propagated to // disable subcriptions, we may end up here with a NULL wikicoursenode // Best we can do here -> return noSubsInfo and clean up NotificationsManager.getInstance().deactivate(p); // return nothing available return NotificationsManager.getInstance().getNoSubscriptionInfo(); } ModuleConfiguration config = ((WikiCourseNode)courseNode).getModuleConfiguration(); RepositoryEntry re = WikiEditController.getWikiRepoReference(config, true); resId = re.getOlatResource().getResourceableId(); if(debug) log.debug("resId=" + resId, null); ores = OresHelper.createOLATResourceableInstance(WikiResource.TYPE_NAME, resId); businessControlString = p.getBusinessPath() + "[path="; } else { // resName = 'BusinessGroup' or 'FileResource.WIKI' if(debug) log.debug("p.getResName()=" + p.getResName(), null); ores = OresHelper.createOLATResourceableInstance(p.getResName(), resId); businessControlString = p.getBusinessPath() + "[path="; } Wiki wiki = WikiManager.getInstance().getOrLoadWiki(ores); final List<WikiPage> pages = wiki.getPagesByDate(); Translator translator = Util.createPackageTranslator(WikiPageChangeOrCreateNotificationHandler.class, locale); Translator forumTranslator = Util.createPackageTranslator(ForumNotificationsHandler.class, locale); TitleItem title = getTitleItem(p, translator); si = new SubscriptionInfo(subscriber.getKey(), p.getType(), title, null); for (Iterator<WikiPage> it = pages.listIterator(); it.hasNext();) { WikiPage element = it.next(); // do only show entries newer then the ones already seen Date modDate = new Date(element.getModificationTime()); if(debug) log.debug("modDate=" + modDate + " ; compareDate=" + compareDate, null); if (modDate.after(compareDate)) { if((element.getPageName().startsWith("O_") || element.getPageName().startsWith(WikiPage.WIKI_MENU_PAGE)) && (element.getModifyAuthor() <= 0)) { //theses pages are created sometimes automatically. Check if this is the case continue; } //build Businesscontrol-Path String businessPath = null; String urlToSend = null; if(p.getBusinessPath() != null) { businessPath = businessControlString + element.getPageName() + "]"; urlToSend = BusinessControlFactory.getInstance().getURLFromBusinessPathString(businessPath); } // string[] gets filled into translation key by adding {0...n} to // the string Identity ident = BaseSecurityManager.getInstance().loadIdentityByKey(Long.valueOf(element.getModifyAuthor())); String desc = translator.translate("notifications.entry", new String[] { element.getPageName(), NotificationHelper.getFormatedName(ident)}); SubscriptionListItem subListItem = new SubscriptionListItem(desc, urlToSend, businessPath, modDate, CSS_CLASS_WIKI_PAGE_CHANGED_ICON); si.addSubscriptionListItem(subListItem); } long forumKey = element.getForumKey(); List<Message> mInfos = ForumManager.getInstance().getNewMessageInfo(forumKey, compareDate); for (Message mInfo : mInfos) { String messageTitle = mInfo.getTitle(); Identity creator = mInfo.getCreator(); Identity modifier = mInfo.getModifier(); Date messageModDate = mInfo.getLastModified(); String name; if(modifier != null) { name = NotificationHelper.getFormatedName(modifier); } else { name = NotificationHelper.getFormatedName(creator); } final String descKey = "notifications.entry" + (mInfo.getCreationDate().equals(messageModDate) ? "" : ".modified"); final String desc = forumTranslator.translate(descKey, new String[] { messageTitle, name }); String urlToSend = null; String businessPath = null; if(p.getBusinessPath() != null) { businessPath = businessControlString + element.getPageName() + "][message:" + mInfo.getKey().toString() + "]"; urlToSend = BusinessControlFactory.getInstance().getURLFromBusinessPathString(businessPath); } SubscriptionListItem subListItem = new SubscriptionListItem(desc, urlToSend, businessPath, messageModDate, CSS_CLASS_WIKI_PAGE_CHANGED_ICON); si.addSubscriptionListItem(subListItem); } } } else { //no news si = NotificationsManager.getInstance().getNoSubscriptionInfo(); } } catch (Exception e) { log.error("Error creating wiki's notifications for subscriber: " + subscriber.getKey(), e); checkPublisher(p); si = NotificationsManager.getInstance().getNoSubscriptionInfo(); } return si; } private boolean courseStatus(ICourse course) { return course != null && !course.getCourseEnvironment().getCourseGroupManager().getCourseEntry().getRepositoryEntryStatus().isUnpublished() && !course.getCourseEnvironment().getCourseGroupManager().getCourseEntry().getRepositoryEntryStatus().isClosed(); } private void checkPublisher(Publisher p) { try { if("BusinessGroup".equals(p.getResName())) { BusinessGroup bg = CoreSpringFactory.getImpl(BusinessGroupService.class).loadBusinessGroup(p.getResId()); if(bg == null) { log.info("deactivating publisher with key; " + p.getKey(), null); NotificationsManager.getInstance().deactivate(p); } } else if ("CourseModule".equals(p.getResName())) { if(!NotificationsUpgradeHelper.checkCourse(p)) { log.info("deactivating publisher with key; " + p.getKey(), null); NotificationsManager.getInstance().deactivate(p); } } else { if(!NotificationsUpgradeHelper.checkOLATResourceable(p)) { log.info("deactivating publisher with key; " + p.getKey(), null); NotificationsManager.getInstance().deactivate(p); } } } catch (Exception e) { log.error("", e); } } private TitleItem getTitleItem(Publisher p, Translator translator) { Long resId = p.getResId(); String type = p.getResName(); String title; if("BusinessGroup".equals(type)) { BusinessGroup bg = CoreSpringFactory.getImpl(BusinessGroupService.class).loadBusinessGroup(resId); title = translator.translate("notifications.header.group", new String[]{bg.getName()}); } else if (CourseModule.getCourseTypeName().equals(type)) { String displayName = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(resId); title = translator.translate("notifications.header.course", new String[]{displayName}); } else { title = translator.translate("notifications.header"); } return new TitleItem(title, Wiki.CSS_CLASS_WIKI_ICON); } @Override public String createTitleInfo(Subscriber subscriber, Locale locale) { try { Translator translator = Util.createPackageTranslator(WikiPageChangeOrCreateNotificationHandler.class, locale); TitleItem title = getTitleItem(subscriber.getPublisher(), translator); return title.getInfoContent("text/plain"); } catch (Exception e) { log.error("Error while creating assessment notifications for subscriber: " + subscriber.getKey(), e); checkPublisher(subscriber.getPublisher()); return "-"; } } @Override public String getType() { return "WikiPage"; } }