From 9237e0014acdd9db9a92d5762357f7e5e15a203f Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Fri, 11 Aug 2017 09:11:12 +0200 Subject: [PATCH] OO-2878: add attachment to the info messsages, add the possibility to send the emails only to owners, coaches or participants and not all of them --- .../java/org/olat/_spring/mainContext.xml | 3 +- .../commons/info/{model => }/InfoMessage.java | 9 +- .../InfoMessageFrontendManager.java | 13 +- .../{manager => }/InfoMessageManager.java | 27 ++-- .../InfoSubscriptionManager.java | 29 ++-- .../info/_spring/infoMessageContext.xml | 23 --- .../InfoMessageFrontendManagerImpl.java | 152 +++++++++++++----- .../info/manager/InfoMessageManagerImpl.java | 24 +-- .../commons/info/manager/MailFormatter.java | 4 +- .../info/model/InfoMessageImpl.hbm.xml | 34 ---- .../commons/info/model/InfoMessageImpl.java | 57 +++++-- .../InfoMessageNotificationHandler.java | 21 ++- .../InfoSubscriptionManagerImpl.java | 28 ++-- .../InfoMessagePortletRunController.java | 10 +- .../commons/info/restapi/InfoMessageVO.java | 2 +- .../info/restapi/InfoMessageWebService.java | 2 +- .../info/restapi/InfoMessagesWebService.java | 4 +- .../olat/commons/info/ui/CreateInfoStep.java | 8 +- .../info/ui/CreateInfoStepController.java | 31 ++-- .../info/ui/InfoDisplayController.java | 138 +++++++++++++--- .../commons/info/ui/InfoDisplayHelper.java | 2 +- .../commons/info/ui/InfoEditController.java | 37 ++--- .../info/ui/InfoEditFormController.java | 132 ++++++++++----- .../info/ui/InfoMessageForDisplay.java | 9 +- .../commons/info/ui/InfoSecurityCallback.java | 2 +- .../info/ui/SendInfoMailFormatter.java | 2 +- .../olat/commons/info/ui/SendMailOption.java | 3 +- .../info/ui/SendMailStepController.java | 2 +- .../info/ui/SendSubscriberMailOption.java | 21 ++- .../olat/commons/info/ui/WizardConstants.java | 10 +- .../commons/info/ui/_content/display.html | 18 +++ .../info/ui/_i18n/LocalStrings_de.properties | 2 + .../info/ui/_i18n/LocalStrings_en.properties | 2 + .../info/ui/_i18n/LocalStrings_fr.properties | 1 + .../_spring/notificationsContext.xml | 1 - .../org/olat/course/nodes/InfoCourseNode.java | 4 +- .../nodes/info/InfoPeekViewController.java | 12 +- .../course/nodes/info/InfoRunController.java | 54 +++---- .../nodes/info/SendMembersMailOption.java | 44 +++-- .../info/_i18n/LocalStrings_de.properties | 4 +- .../info/_i18n/LocalStrings_en.properties | 4 +- .../info/_i18n/LocalStrings_fr.properties | 4 +- .../info/_i18n/LocalStrings_it.properties | 2 +- .../info/_i18n/LocalStrings_jp.properties | 3 +- .../info/_i18n/LocalStrings_nl_NL.properties | 3 +- .../info/_i18n/LocalStrings_pl.properties | 3 +- .../info/_i18n/LocalStrings_pt_BR.properties | 3 +- .../BusinessGroupMembershipProcessor.java | 2 +- .../manager/BusinessGroupServiceImpl.java | 2 +- .../group/ui/run/InfoGroupRunController.java | 24 ++- .../ui/run/SendGroupMembersMailOption.java | 25 ++- .../service/document/InfoMessageDocument.java | 2 +- .../indexer/group/GroupInfoIndexer.java | 6 +- .../course/InfoCourseNodeIndexer.java | 4 +- .../org/olat/upgrade/OLATUpgrade_11_4_0.java | 2 +- .../database/mysql/alter_11_5_x_to_12_0_0.sql | 1 + .../database/mysql/setupDatabase.sql | 1 + .../oracle/alter_11_5_x_to_12_0_0.sql | 2 + .../database/oracle/setupDatabase.sql | 1 + .../postgresql/alter_11_5_x_to_12_0_0.sql | 6 + .../database/postgresql/setupDatabase.sql | 1 + .../olat/commons/info/InfoManagerTest.java | 2 - .../info/InfoMessageFrontendManagerTest.java | 2 - 63 files changed, 646 insertions(+), 440 deletions(-) rename src/main/java/org/olat/commons/info/{model => }/InfoMessage.java (93%) rename src/main/java/org/olat/commons/info/{manager => }/InfoMessageFrontendManager.java (87%) rename src/main/java/org/olat/commons/info/{manager => }/InfoMessageManager.java (55%) rename src/main/java/org/olat/commons/info/{notification => }/InfoSubscriptionManager.java (56%) delete mode 100644 src/main/java/org/olat/commons/info/_spring/infoMessageContext.xml delete mode 100644 src/main/java/org/olat/commons/info/model/InfoMessageImpl.hbm.xml diff --git a/src/main/java/org/olat/_spring/mainContext.xml b/src/main/java/org/olat/_spring/mainContext.xml index 9f281a42f91..a9f827a6f32 100644 --- a/src/main/java/org/olat/_spring/mainContext.xml +++ b/src/main/java/org/olat/_spring/mainContext.xml @@ -8,7 +8,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - <context:component-scan base-package="org.olat.note,org.olat.social,org.olat.commons.memberlist" /> + <context:component-scan base-package="org.olat.note,org.olat.social,org.olat.commons.memberlist,org.olat.commons.info" /> <import resource="classpath:/org/olat/core/util/threadlog/_spring/threadlogCorecontext.xml"/> <import resource="classpath:/org/olat/core/_spring/mainCorecontext.xml"/> @@ -24,7 +24,6 @@ <import resource="classpath:/org/olat/basesecurity/_spring/baseSecurityContext.xml"/> <import resource="classpath:/org/olat/collaboration/_spring/collaborationToolsContext.xml"/> <import resource="classpath:/org/olat/commons/calendar/_spring/calendarContext.xml"/> - <import resource="classpath:/org/olat/commons/info/_spring/infoMessageContext.xml"/> <import resource="classpath:/org/olat/commons/servlets/_spring/staticContext.xml"/> <import resource="classpath:/org/olat/course/_spring/courseContext.xml"/> diff --git a/src/main/java/org/olat/commons/info/model/InfoMessage.java b/src/main/java/org/olat/commons/info/InfoMessage.java similarity index 93% rename from src/main/java/org/olat/commons/info/model/InfoMessage.java rename to src/main/java/org/olat/commons/info/InfoMessage.java index b8de6b7f12a..d975bb12da4 100644 --- a/src/main/java/org/olat/commons/info/model/InfoMessage.java +++ b/src/main/java/org/olat/commons/info/InfoMessage.java @@ -18,7 +18,7 @@ * <p> */ -package org.olat.commons.info.model; +package org.olat.commons.info; import java.util.Date; @@ -26,9 +26,6 @@ import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; /** - * - * Description:<br> - * TODO: srosse Class Description for InfoMessage * * <P> * Initial Date: 27 jul. 2010 <br> @@ -51,6 +48,10 @@ public interface InfoMessage { public String getMessage(); public void setMessage(String message); + + public String getAttachmentPath(); + + public void setAttachmentPath(String path); public Long getResId(); diff --git a/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManager.java b/src/main/java/org/olat/commons/info/InfoMessageFrontendManager.java similarity index 87% rename from src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManager.java rename to src/main/java/org/olat/commons/info/InfoMessageFrontendManager.java index a43fc80e807..f1b3131881c 100644 --- a/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManager.java +++ b/src/main/java/org/olat/commons/info/InfoMessageFrontendManager.java @@ -18,17 +18,20 @@ * <p> */ -package org.olat.commons.info.manager; +package org.olat.commons.info; +import java.io.File; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Locale; import org.olat.basesecurity.IdentityRef; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.manager.MailFormatter; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.util.resource.OresHelper; +import org.olat.core.util.vfs.VFSLeaf; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupRef; @@ -62,6 +65,12 @@ public interface InfoMessageFrontendManager { public void saveInfoMessage(InfoMessage msg); + public VFSLeaf getAttachment(InfoMessage msg); + + public String storeAttachment(File file, String filename, OLATResourceable ores, String subPath); + + public void deleteAttachments(Collection<String> paths); + public void deleteInfoMessage(InfoMessage infoMessage); public void updateInfoMessagesOfIdentity(BusinessGroupRef businessGroup, IdentityRef identity); diff --git a/src/main/java/org/olat/commons/info/manager/InfoMessageManager.java b/src/main/java/org/olat/commons/info/InfoMessageManager.java similarity index 55% rename from src/main/java/org/olat/commons/info/manager/InfoMessageManager.java rename to src/main/java/org/olat/commons/info/InfoMessageManager.java index 24f4b65916e..82b46040570 100644 --- a/src/main/java/org/olat/commons/info/manager/InfoMessageManager.java +++ b/src/main/java/org/olat/commons/info/InfoMessageManager.java @@ -18,40 +18,31 @@ * <p> */ -package org.olat.commons.info.manager; +package org.olat.commons.info; import java.util.Date; import java.util.List; import org.olat.basesecurity.IdentityRef; -import org.olat.commons.info.model.InfoMessage; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.group.BusinessGroupRef; -public abstract class InfoMessageManager { - - protected static InfoMessageManager INSTANCE; - - - public static InfoMessageManager getInstance() { - return INSTANCE; - } - +public interface InfoMessageManager { - public abstract InfoMessage createInfoMessage(OLATResourceable ores, String subPath, String businessPath, Identity author); + public InfoMessage createInfoMessage(OLATResourceable ores, String subPath, String businessPath, Identity author); - public abstract void saveInfoMessage(InfoMessage infoMessage); + public void saveInfoMessage(InfoMessage infoMessage); - public abstract void deleteInfoMessage(InfoMessage infoMessage); + public void deleteInfoMessage(InfoMessage infoMessage); - public abstract List<InfoMessage> loadInfoMessagesOfIdentity(BusinessGroupRef businessGroup, IdentityRef identity); + public List<InfoMessage> loadInfoMessagesOfIdentity(BusinessGroupRef businessGroup, IdentityRef identity); - public abstract InfoMessage loadInfoMessageByKey(Long key); + public InfoMessage loadInfoMessageByKey(Long key); - public abstract List<InfoMessage> loadInfoMessageByResource(OLATResourceable ores, String subPath, String businessPath, + public List<InfoMessage> loadInfoMessageByResource(OLATResourceable ores, String subPath, String businessPath, Date after, Date before, int firstResult, int maxReturn); - public abstract int countInfoMessageByResource(OLATResourceable ores, String subPath, String businessPath, + public int countInfoMessageByResource(OLATResourceable ores, String subPath, String businessPath, Date after, Date before); } diff --git a/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManager.java b/src/main/java/org/olat/commons/info/InfoSubscriptionManager.java similarity index 56% rename from src/main/java/org/olat/commons/info/notification/InfoSubscriptionManager.java rename to src/main/java/org/olat/commons/info/InfoSubscriptionManager.java index 210b10e8362..0b010e065f8 100644 --- a/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManager.java +++ b/src/main/java/org/olat/commons/info/InfoSubscriptionManager.java @@ -18,10 +18,11 @@ * <p> */ -package org.olat.commons.info.notification; +package org.olat.commons.info; import java.util.List; +import org.olat.commons.info.notification.InfoSubscription; import org.olat.core.commons.services.notifications.PublisherData; import org.olat.core.commons.services.notifications.Subscriber; import org.olat.core.commons.services.notifications.SubscriptionContext; @@ -38,30 +39,24 @@ import org.olat.core.util.prefs.Preferences; * Initial Date: 27 jul. 2010 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public abstract class InfoSubscriptionManager { - - protected static InfoSubscriptionManager INSTANCE; - - public static InfoSubscriptionManager getInstance() { - return INSTANCE; - } +public interface InfoSubscriptionManager { - public abstract SubscriptionContext getInfoSubscriptionContext(OLATResourceable resource, String subPath); + public SubscriptionContext getInfoSubscriptionContext(OLATResourceable resource, String subPath); - public abstract PublisherData getInfoPublisherData(OLATResourceable resource, String businessPath); + public PublisherData getInfoPublisherData(OLATResourceable resource, String businessPath); - public abstract InfoSubscription getInfoSubscription(Preferences prefs); + public InfoSubscription getInfoSubscription(Preferences prefs); - public abstract Subscriber getInfoSubscriber(Identity identity, OLATResourceable resource, String subPath); + public Subscriber getInfoSubscriber(Identity identity, OLATResourceable resource, String subPath); - public abstract List<Identity> getInfoSubscribers(OLATResourceable resource, String subPath); + public List<Identity> getInfoSubscribers(OLATResourceable resource, String subPath); - public abstract void subscribe(OLATResourceable resource, String resSubPath, String businessPath, Identity identity); + public void subscribe(OLATResourceable resource, String resSubPath, String businessPath, Identity identity); - public abstract void unsubscribe(OLATResourceable resource, String subPath, Identity identity); + public void unsubscribe(OLATResourceable resource, String subPath, Identity identity); - public abstract void markPublisherNews(OLATResourceable resource, String subPath); + public void markPublisherNews(OLATResourceable resource, String subPath); - public abstract void deleteSubscriptionContext(SubscriptionContext context); + public void deleteSubscriptionContext(SubscriptionContext context); } diff --git a/src/main/java/org/olat/commons/info/_spring/infoMessageContext.xml b/src/main/java/org/olat/commons/info/_spring/infoMessageContext.xml deleted file mode 100644 index 202632f6799..00000000000 --- a/src/main/java/org/olat/commons/info/_spring/infoMessageContext.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd"> - - <bean id="infoMessageFrontendManager" class="org.olat.commons.info.manager.InfoMessageFrontendManagerImpl"> - <property name="coordinatorManager" ref="coordinatorManager"/> - <property name="infoMessageManager" ref="infoMessageManager"/> - <property name="infoSubscriptionManager" ref="infoSubscriptionManager"/> - <property name="mailManager" ref="mailManager"/> - </bean> - - <bean id="infoMessageManager" class="org.olat.commons.info.manager.InfoMessageManagerImpl"> - <property name="dbInstance" ref="database"/> - </bean> - - <bean id="infoSubscriptionManager" class="org.olat.commons.info.notification.InfoSubscriptionManagerImpl"> - <property name="notificationsManager" ref="notificationsManager"/> - </bean> - -</beans> diff --git a/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManagerImpl.java b/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManagerImpl.java index 518e2912430..4a49b5e002a 100644 --- a/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManagerImpl.java +++ b/src/main/java/org/olat/commons/info/manager/InfoMessageFrontendManagerImpl.java @@ -20,6 +20,16 @@ package org.olat.commons.info.manager; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -27,9 +37,12 @@ import java.util.Locale; import java.util.Set; import org.olat.basesecurity.IdentityRef; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; +import org.olat.commons.info.InfoMessageManager; +import org.olat.commons.info.InfoSubscriptionManager; import org.olat.commons.info.model.InfoMessageImpl; -import org.olat.commons.info.notification.InfoSubscriptionManager; +import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; @@ -44,8 +57,14 @@ import org.olat.core.util.mail.MailContext; import org.olat.core.util.mail.MailContextImpl; import org.olat.core.util.mail.MailManager; import org.olat.core.util.mail.MailerResult; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSItem; +import org.olat.core.util.vfs.VFSLeaf; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupRef; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + /** * @@ -55,47 +74,21 @@ import org.olat.group.BusinessGroupRef; * Initial Date: 28 juil. 2010 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ +@Service public class InfoMessageFrontendManagerImpl implements InfoMessageFrontendManager { + + private final DateFormat formater = new SimpleDateFormat("yyyyMMdd'T'HHmmss"); + private static final OLog log = Tracing.createLoggerFor(InfoMessageFrontendManagerImpl.class); - private static final OLog log = Tracing.createLoggerFor(InfoMessageFrontendManagerImpl.class); - + @Autowired private MailManager mailManager; + @Autowired private CoordinatorManager coordinatorManager; + @Autowired private InfoMessageManager infoMessageManager; + @Autowired private InfoSubscriptionManager infoSubscriptionManager; - /** - * [used by Spring] - * @param mailManager - */ - public void setMailManager(MailManager mailManager) { - this.mailManager = mailManager; - } - - /** - * [used by Spring] - * @param coordinatorManager - */ - public void setCoordinatorManager(CoordinatorManager coordinatorManager) { - this.coordinatorManager = coordinatorManager; - } - - /** - * [used by Spring] - * @param infoMessageManager - */ - public void setInfoMessageManager(InfoMessageManager infoMessageManager) { - this.infoMessageManager = infoMessageManager; - } - - /** - * [used by Spring] - * @param infoSubscriptionManager - */ - public void setInfoSubscriptionManager(InfoSubscriptionManager infoSubscriptionManager) { - this.infoSubscriptionManager = infoSubscriptionManager; - } - @Override public InfoMessage loadInfoMessage(Long key) { return infoMessageManager.loadInfoMessageByKey(key); @@ -110,6 +103,72 @@ public class InfoMessageFrontendManagerImpl implements InfoMessageFrontendManage public void saveInfoMessage(InfoMessage infoMessage) { infoMessageManager.saveInfoMessage(infoMessage); } + + @Override + public VFSLeaf getAttachment(InfoMessage msg) { + VFSLeaf attachment = null; + if(StringHelper.containsNonWhitespace(msg.getAttachmentPath())) { + VFSItem item = getStoragePath().resolve(msg.getAttachmentPath()); + if(item instanceof VFSLeaf) { + attachment = (VFSLeaf)item; + } + } + return attachment; + } + + @Override + public void deleteAttachments(Collection<String> paths) { + if(paths == null || paths.isEmpty()) return; + + VFSContainer ressourceContainer = getStoragePath(); + for(String path:paths) { + VFSItem item = ressourceContainer.resolve(path); + if(item instanceof VFSLeaf) { + ((VFSLeaf)item).delete(); + } + } + } + + @Override + public String storeAttachment(File file, String filename, OLATResourceable ores, String subPath) { + try { + File ressourceDir = getResourceDir(ores); + + String datePart; + synchronized(formater) { + datePart = formater.format(new Date()); + } + if(filename == null) { + filename = file.getName(); + } + filename = datePart + "_" + filename; + File attachment = new File(ressourceDir, filename); + Files.copy(file.toPath(), attachment.toPath(), StandardCopyOption.REPLACE_EXISTING); + + File root = getStoragePath().getBasefile(); + Path relativePath = root.toPath().relativize(attachment.toPath()); + return relativePath.toString(); + } catch (IOException e) { + log.error("", e); + return null; + } + } + + private File getResourceDir(OLATResourceable ores) { + File root = getStoragePath().getBasefile(); + String type = ores.getResourceableTypeName().toLowerCase(); + File typePath = new File(root, type); + String id = ores.getResourceableId().toString(); + File resourceFile = new File(typePath, id); + if(!resourceFile.exists()) { + resourceFile.mkdirs(); + } + return resourceFile; + } + + private OlatRootFolderImpl getStoragePath() { + return new OlatRootFolderImpl("/infomessages/", null); + } @Override public boolean sendInfoMessage(InfoMessage infoMessage, MailFormatter mailFormatter, Locale locale, Identity from, List<Identity> tos) { @@ -138,13 +197,22 @@ public class InfoMessageFrontendManagerImpl implements InfoMessageFrontendManage if(!StringHelper.containsNonWhitespace(body)) { body = infoMessage.getMessage(); } - //fxdiff VCRP-16: intern mail system + File attachment = null; + if(StringHelper.containsNonWhitespace(infoMessage.getAttachmentPath())) { + File root = getStoragePath().getBasefile(); + attachment = new File(root, infoMessage.getAttachmentPath()); + } + MailContext context = new MailContextImpl(mailFormatter.getBusinessPath()); MailBundle bundle = new MailBundle(); bundle.setContext(context); bundle.setFromId(from); bundle.setContactList(contactList); - bundle.setContent(subject, body); + if(attachment != null) { + bundle.setContent(subject, body, attachment); + } else { + bundle.setContent(subject, body); + } MailerResult result = mailManager.sendMessage(bundle); send = result.isSuccessful(); @@ -161,6 +229,9 @@ public class InfoMessageFrontendManagerImpl implements InfoMessageFrontendManage @Override public void deleteInfoMessage(InfoMessage infoMessage) { + if(StringHelper.containsNonWhitespace(infoMessage.getAttachmentPath())) { + deleteAttachments(Collections.singletonList(infoMessage.getAttachmentPath())); + } infoMessageManager.deleteInfoMessage(infoMessage); infoSubscriptionManager.markPublisherNews(infoMessage.getOLATResourceable(), infoMessage.getResSubPath()); } @@ -185,13 +256,18 @@ public class InfoMessageFrontendManagerImpl implements InfoMessageFrontendManage public void removeInfoMessagesAndSubscriptionContext(BusinessGroup group) { List<InfoMessage> messages = infoMessageManager.loadInfoMessageByResource(group, InfoMessageFrontendManager.businessGroupResSubPath, null, null, null, 0, 0); + List<String> pathToDelete = new ArrayList<>(); for (InfoMessage im : messages) { infoMessageManager.deleteInfoMessage(im); + if(StringHelper.containsNonWhitespace(im.getAttachmentPath())) { + pathToDelete.add(im.getAttachmentPath()); + } } String resName = group.getResourceableTypeName(); Long resId = group.getResourceableId(); SubscriptionContext subscriptionContext = new SubscriptionContext(resName, resId, ""); infoSubscriptionManager.deleteSubscriptionContext(subscriptionContext); + deleteAttachments(pathToDelete); } @Override diff --git a/src/main/java/org/olat/commons/info/manager/InfoMessageManagerImpl.java b/src/main/java/org/olat/commons/info/manager/InfoMessageManagerImpl.java index 8e4668e3cec..6b7223164f3 100644 --- a/src/main/java/org/olat/commons/info/manager/InfoMessageManagerImpl.java +++ b/src/main/java/org/olat/commons/info/manager/InfoMessageManagerImpl.java @@ -26,7 +26,8 @@ import java.util.List; import java.util.StringTokenizer; import org.olat.basesecurity.IdentityRef; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageManager; import org.olat.commons.info.model.InfoMessageImpl; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBQuery; @@ -34,6 +35,8 @@ import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroupRef; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -44,24 +47,11 @@ import org.olat.group.BusinessGroupRef; * Initial Date: 26 jul. 2010 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class InfoMessageManagerImpl extends InfoMessageManager { +@Service("infoMessageManager") +public class InfoMessageManagerImpl implements InfoMessageManager { + @Autowired private DB dbInstance; - - /** - * [used by Spring] - */ - private InfoMessageManagerImpl() { - INSTANCE = this; - } - - /** - * [used by Spring] - * @param dbInstance - */ - public void setDbInstance(DB dbInstance) { - this.dbInstance = dbInstance; - } @Override public InfoMessage createInfoMessage(OLATResourceable ores, String subPath, String businessPath, Identity author) { diff --git a/src/main/java/org/olat/commons/info/manager/MailFormatter.java b/src/main/java/org/olat/commons/info/manager/MailFormatter.java index 008d76323b9..a7035a7bdf8 100644 --- a/src/main/java/org/olat/commons/info/manager/MailFormatter.java +++ b/src/main/java/org/olat/commons/info/manager/MailFormatter.java @@ -21,7 +21,7 @@ package org.olat.commons.info.manager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; /** * @@ -37,6 +37,6 @@ public interface MailFormatter { public String getSubject(InfoMessage msg); public String getBody(InfoMessage msg); - //fxdiff VCRP-16: intern mail system + public String getBusinessPath(); } diff --git a/src/main/java/org/olat/commons/info/model/InfoMessageImpl.hbm.xml b/src/main/java/org/olat/commons/info/model/InfoMessageImpl.hbm.xml deleted file mode 100644 index 8deb349cc00..00000000000 --- a/src/main/java/org/olat/commons/info/model/InfoMessageImpl.hbm.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> -<hibernate-mapping default-lazy="false"> - <class name="org.olat.commons.info.model.InfoMessageImpl" table="o_info_message"> - - <id name="key" type="long" column="info_id" unsaved-value="null"> - <generator class="enhanced-sequence"> - <param name="sequence_name">hibernate_unique_key</param> - <param name="force_table_use">true</param> - <param name="optimizer">legacy-hilo</param> - <param name="value_column">next_hi</param> - <param name="increment_size">32767</param> - <param name="initial_value">32767</param> - </generator> - </id> - - <version name="version" access="field" column="version"/> - <property name="creationDate" column="creationdate" type="timestamp" /> - <property name="modificationDate" column="modificationdate" type="timestamp" /> - - <property name="title" column="title" type="string" length="2048" not-null="false"/> - <property name="message" column="message" type="string" length="2048" not-null="false"/> - - <property name="resName" column="resname" type="string" not-null="true" length="50" index="mark_name_idx"/> - <property name="resId" column="resid" type="long" not-null="true" index="mark_id_idx" /> - <property name="resSubPath" column="ressubpath" type="string" length="2048" index="mark_subpath_idx" not-null="false"/> - <property name="businessPath" column="businesspath" type="string" length="2048" index="mark_businesspath_idx" not-null="false"/> - - <many-to-one name="author" class="org.olat.basesecurity.IdentityImpl" column="fk_author_id" outer-join="true" cascade="none" not-null="true"/> - <many-to-one name="modifier" class="org.olat.basesecurity.IdentityImpl" column="fk_modifier_id" outer-join="true" cascade="none" not-null="false"/> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/src/main/java/org/olat/commons/info/model/InfoMessageImpl.java b/src/main/java/org/olat/commons/info/model/InfoMessageImpl.java index 67690ee93df..42ed3313bba 100644 --- a/src/main/java/org/olat/commons/info/model/InfoMessageImpl.java +++ b/src/main/java/org/olat/commons/info/model/InfoMessageImpl.java @@ -36,6 +36,7 @@ import javax.persistence.TemporalType; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; import org.olat.basesecurity.IdentityImpl; +import org.olat.commons.info.InfoMessage; import org.olat.core.id.CreateInfo; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; @@ -77,6 +78,8 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { private String title; @Column(name="message", nullable=true, insertable=true, updatable=true) private String message; + @Column(name="attachmentpath", nullable=true, insertable=true, updatable=true) + private String attachmentPath; @Column(name="resid", nullable=false, insertable=true, updatable=false) private Long resId; @@ -97,35 +100,63 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { public InfoMessageImpl() { // } + + @Override + public Long getKey() { + return key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate= creationDate; + } + + @Override public Date getModificationDate() { return modificationDate; } + @Override public void setModificationDate(Date modificationDate) { this.modificationDate = modificationDate; } - - public void setCreationDate(Date creationDate) { - this.creationDate= creationDate; - } + @Override public String getTitle() { return title; } + @Override public void setTitle(String title) { this.title = title; } + @Override public String getMessage() { return message; } + @Override public void setMessage(String message) { this.message = message; } + @Override + public String getAttachmentPath() { + return attachmentPath; + } + + @Override + public void setAttachmentPath(String attachmentPath) { + this.attachmentPath = attachmentPath; + } + + @Override public Long getResId() { return resId; } @@ -134,6 +165,7 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { this.resId = resId; } + @Override public String getResName() { return resName; } @@ -142,6 +174,7 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { this.resName = resName; } + @Override public String getResSubPath() { return resSubPath; } @@ -150,6 +183,7 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { this.resSubPath = subPath; } + @Override public String getBusinessPath() { return businessPath; } @@ -158,6 +192,7 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { this.businessPath = businessPath; } + @Override public Identity getAuthor() { return author; } @@ -166,14 +201,17 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { this.author = author; } + @Override public Identity getModifier() { return modifier; } + @Override public void setModifier(Identity modifier) { this.modifier = modifier; } + @Override public OLATResourceable getOLATResourceable() { final String name = resName; final Long id = resId; @@ -210,15 +248,4 @@ public class InfoMessageImpl implements InfoMessage, CreateInfo, Persistable { public boolean equalsByPersistableKey(Persistable persistable) { return equals(persistable); } - - @Override - public Long getKey() { - return key; - } - - - @Override - public Date getCreationDate() { - return creationDate; - } } diff --git a/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java b/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java index 2c6c8baca41..4bfd1c14fc5 100644 --- a/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java +++ b/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java @@ -24,8 +24,8 @@ import java.util.Date; import java.util.List; import java.util.Locale; -import org.olat.commons.info.manager.InfoMessageManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageManager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationHelper; import org.olat.core.commons.services.notifications.NotificationsHandler; @@ -39,13 +39,16 @@ 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.LogDelegator; +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.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -56,10 +59,16 @@ import org.olat.repository.RepositoryManager; * Initial Date: 27 jul. 2010 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class InfoMessageNotificationHandler extends LogDelegator implements NotificationsHandler { +@Service("org.olat.commons.info.notification.InfoMessageNotificationHandler") +public class InfoMessageNotificationHandler implements NotificationsHandler { + + private static final OLog log = Tracing.createLoggerFor(InfoMessageNotificationHandler.class); private static final String CSS_CLASS_ICON = "o_infomsg_icon"; + @Autowired + private InfoMessageManager infoMessageManager; + @Override public SubscriptionInfo createSubscriptionInfo(Subscriber subscriber, Locale locale, Date compareDate) { SubscriptionInfo si = null; @@ -96,7 +105,7 @@ public class InfoMessageNotificationHandler extends LogDelegator implements Noti si = new SubscriptionInfo(subscriber.getKey(), p.getType(), new TitleItem(title, CSS_CLASS_ICON), null); OLATResourceable ores = OresHelper.createOLATResourceableInstance(resName, resId); - List<InfoMessage> infos = InfoMessageManager.getInstance().loadInfoMessageByResource(ores, resSubPath, null, compareDate, null, 0, 0); + List<InfoMessage> infos = infoMessageManager.loadInfoMessageByResource(ores, resSubPath, null, compareDate, null, 0, 0); for(InfoMessage info:infos) { Identity ident = info.getAuthor(); String desc = translator.translate("notifications.entry", new String[] { info.getTitle(), NotificationHelper.getFormatedName(ident) }); @@ -108,7 +117,7 @@ public class InfoMessageNotificationHandler extends LogDelegator implements Noti si.addSubscriptionListItem(subListItem); } } catch (Exception e) { - logError("Unexpected exception", e); + log.error("Unexpected exception", e); si = NotificationsManager.getInstance().getNoSubscriptionInfo(); } } else { diff --git a/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManagerImpl.java b/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManagerImpl.java index 369d27aeb3b..0e24fae845d 100644 --- a/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManagerImpl.java +++ b/src/main/java/org/olat/commons/info/notification/InfoSubscriptionManagerImpl.java @@ -23,7 +23,8 @@ package org.olat.commons.info.notification; import java.util.Collections; import java.util.List; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoSubscriptionManager; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.PublisherData; @@ -33,6 +34,8 @@ import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.util.prefs.Preferences; import org.olat.core.util.resource.OresHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * @@ -43,26 +46,13 @@ import org.olat.core.util.resource.OresHelper; * Initial Date: 27 jul. 2010 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -public class InfoSubscriptionManagerImpl extends InfoSubscriptionManager { +@Service +public class InfoSubscriptionManagerImpl implements InfoSubscriptionManager { + + private static final String PUBLISHER_TYPE = OresHelper.calculateTypeName(InfoMessage.class); + @Autowired private NotificationsManager notificationsManager; - - private String PUBLISHER_TYPE = OresHelper.calculateTypeName(InfoMessage.class); - - /** - * [used by Spring] - */ - private InfoSubscriptionManagerImpl() { - INSTANCE = this; - } - - /** - * [user by Spring] - * @param notificationsManager - */ - public void setNotificationsManager(NotificationsManager notificationsManager) { - this.notificationsManager = notificationsManager; - } @Override public SubscriptionContext getInfoSubscriptionContext(OLATResourceable resource, String subPath) { diff --git a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java index 44293dc535d..1bfc7015b86 100644 --- a/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java +++ b/src/main/java/org/olat/commons/info/portlet/InfoMessagePortletRunController.java @@ -28,8 +28,8 @@ import java.util.List; import java.util.Locale; import org.olat.NewControllerFactory; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionInfo; import org.olat.core.commons.services.notifications.model.SubscriptionListItem; @@ -120,9 +120,9 @@ public class InfoMessagePortletRunController extends AbstractPortletRunControlle @Override protected SortingCriteria createDefaultSortingCriteria() { - SortingCriteria sortingCriteria = new SortingCriteria(sortingTermsList, getDefaultMaxEntries()); - sortingCriteria.setAscending(false); - return sortingCriteria; + SortingCriteria sortCriteria = new SortingCriteria(sortingTermsList, getDefaultMaxEntries()); + sortCriteria.setAscending(false); + return sortCriteria; } @Override diff --git a/src/main/java/org/olat/commons/info/restapi/InfoMessageVO.java b/src/main/java/org/olat/commons/info/restapi/InfoMessageVO.java index 63bb5b12c24..8002ab65c9d 100644 --- a/src/main/java/org/olat/commons/info/restapi/InfoMessageVO.java +++ b/src/main/java/org/olat/commons/info/restapi/InfoMessageVO.java @@ -25,7 +25,7 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; @XmlAccessorType(XmlAccessType.FIELD) diff --git a/src/main/java/org/olat/commons/info/restapi/InfoMessageWebService.java b/src/main/java/org/olat/commons/info/restapi/InfoMessageWebService.java index 958b7a51d56..cf5907017c4 100644 --- a/src/main/java/org/olat/commons/info/restapi/InfoMessageWebService.java +++ b/src/main/java/org/olat/commons/info/restapi/InfoMessageWebService.java @@ -27,7 +27,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; /** * diff --git a/src/main/java/org/olat/commons/info/restapi/InfoMessagesWebService.java b/src/main/java/org/olat/commons/info/restapi/InfoMessagesWebService.java index 0fb513fc9e9..27da63c69f2 100644 --- a/src/main/java/org/olat/commons/info/restapi/InfoMessagesWebService.java +++ b/src/main/java/org/olat/commons/info/restapi/InfoMessagesWebService.java @@ -39,8 +39,8 @@ import javax.ws.rs.core.Response.Status; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; diff --git a/src/main/java/org/olat/commons/info/ui/CreateInfoStep.java b/src/main/java/org/olat/commons/info/ui/CreateInfoStep.java index c9eb9a33110..02e42808380 100644 --- a/src/main/java/org/olat/commons/info/ui/CreateInfoStep.java +++ b/src/main/java/org/olat/commons/info/ui/CreateInfoStep.java @@ -22,6 +22,7 @@ package org.olat.commons.info.ui; import java.util.List; +import org.olat.commons.info.InfoMessage; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.control.WindowControl; @@ -41,8 +42,11 @@ import org.olat.core.gui.control.generic.wizard.StepsRunContext; */ public class CreateInfoStep extends BasicStep { - public CreateInfoStep(UserRequest ureq, List<SendMailOption> options) { + private final InfoMessage message; + + public CreateInfoStep(UserRequest ureq, List<SendMailOption> options, InfoMessage message) { super(ureq); + this.message = message; setI18nTitleAndDescr("wizard.step0.title", "wizard.step0.description"); setNextStep(new SendMailStep(ureq, options)); } @@ -54,6 +58,6 @@ public class CreateInfoStep extends BasicStep { @Override public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) { - return new CreateInfoStepController(ureq, wControl, runContext, form); + return new CreateInfoStepController(ureq, wControl, runContext, form, message); } } diff --git a/src/main/java/org/olat/commons/info/ui/CreateInfoStepController.java b/src/main/java/org/olat/commons/info/ui/CreateInfoStepController.java index ab8ffafcb68..cf626bf701c 100644 --- a/src/main/java/org/olat/commons/info/ui/CreateInfoStepController.java +++ b/src/main/java/org/olat/commons/info/ui/CreateInfoStepController.java @@ -20,11 +20,13 @@ package org.olat.commons.info.ui; +import org.olat.commons.info.InfoMessage; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.wizard.StepFormBasicController; import org.olat.core.gui.control.generic.wizard.StepsEvent; @@ -42,27 +44,26 @@ import org.olat.core.gui.control.generic.wizard.StepsRunContext; public class CreateInfoStepController extends StepFormBasicController { private final StepsRunContext runContext; - private final InfoEditFormController infoEditFormController; + private final InfoEditFormController editForm; - public CreateInfoStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form rootForm) { + public CreateInfoStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form rootForm, InfoMessage message) { super(ureq, wControl, rootForm, runContext, LAYOUT_VERTICAL, null); this.runContext = runContext; - - infoEditFormController = new InfoEditFormController(ureq, wControl, rootForm, true); - listenTo(infoEditFormController); + editForm = new InfoEditFormController(ureq, wControl, rootForm, true, message); + listenTo(editForm); initForm(ureq); } @Override public FormItem getStepFormItem() { - return infoEditFormController.getInitialFormItem(); + return editForm.getInitialFormItem(); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - formLayout.add(infoEditFormController.getInitialFormItem()); + formLayout.add(editForm.getInitialFormItem()); } @Override @@ -70,15 +71,25 @@ public class CreateInfoStepController extends StepFormBasicController { // } + @Override + public void event(UserRequest ureq, Controller source, Event event) { + if(source == editForm) { + if(event == Event.CHANGED_EVENT) { + runContext.put(WizardConstants.PATH_TO_DELETE, editForm.getAttachmentPathToDelete()); + } + } + super.event(ureq, source, event); + } + @Override protected boolean validateFormLogic(UserRequest ureq) { - return infoEditFormController.validateFormLogic(ureq); + return editForm.validateFormLogic(ureq); } @Override protected void formOK(UserRequest ureq) { - runContext.put(WizardConstants.MSG_TITLE, infoEditFormController.getTitle()); - runContext.put(WizardConstants.MSG_MESSAGE, infoEditFormController.getMessage()); + runContext.put(WizardConstants.MSG, editForm.getInfoMessage()); + runContext.put(WizardConstants.PATH_TO_DELETE, editForm.getAttachmentPathToDelete()); fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); } } diff --git a/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java b/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java index efb93bb8932..7b5baf0fb71 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java +++ b/src/main/java/org/olat/commons/info/ui/InfoDisplayController.java @@ -22,14 +22,21 @@ package org.olat.commons.info.ui; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import javax.servlet.http.HttpServletRequest; + +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.commons.info.manager.MailFormatter; -import org.olat.commons.info.model.InfoMessage; -import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.modules.bc.meta.MetaInfo; +import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged; +import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.date.DateComponentFactory; import org.olat.core.gui.components.date.DateElement; @@ -38,6 +45,7 @@ import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; @@ -49,6 +57,8 @@ import org.olat.core.gui.control.generic.wizard.Step; import org.olat.core.gui.control.generic.wizard.StepRunnerCallback; import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; +import org.olat.core.gui.media.MediaResource; +import org.olat.core.gui.media.NotFoundMediaResource; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.id.User; @@ -62,11 +72,14 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.LockResult; import org.olat.core.util.resource.OresHelper; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.VFSMediaResource; import org.olat.course.nodes.info.InfoCourseNodeConfiguration; import org.olat.group.BusinessGroup; import org.olat.modules.ModuleConfiguration; import org.olat.user.UserManager; import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -95,6 +108,9 @@ public class InfoDisplayController extends FormBasicController { private final OLATResourceable ores; private final String resSubPath; private final String businessPath; + private final String thumbnailMapper; + private final String attachmentMapper; + private Map<Long,VFSLeaf> infoKeyToAttachment; private int maxResults = 0; private int maxResultsConfig = 0; @@ -102,24 +118,26 @@ public class InfoDisplayController extends FormBasicController { private Date after = null; private Date afterConfig = null; - private final UserManager userManager; - private final InfoMessageFrontendManager infoMessageManager; + @Autowired + private UserManager userManager; + @Autowired + private InfoMessageFrontendManager infoMessageManager; private LockResult lockEntry; private MailFormatter sendMailFormatter; - private List<SendMailOption> sendMailOptions = new ArrayList<SendMailOption>(); + private List<SendMailOption> sendMailOptions = new ArrayList<>(); public InfoDisplayController(UserRequest ureq, WindowControl wControl, InfoSecurityCallback secCallback, BusinessGroup businessGroup, String resSubPath, String businessPath) { super(ureq, wControl, "display"); - userManager = CoreSpringFactory.getImpl(UserManager.class); - infoMessageManager = CoreSpringFactory.getImpl(InfoMessageFrontendManager.class); this.secCallback = secCallback; this.ores = businessGroup.getResource(); this.resSubPath = resSubPath; this.businessPath = businessPath; // default show 10 messages for groups maxResults = maxResultsConfig = 10; + thumbnailMapper = registerCacheableMapper(ureq, "InfoMessagesThumbnail", new ThumbnailMapper()); + attachmentMapper = registerCacheableMapper(ureq, "InfoMessages", new AttachmentMapper()); initForm(ureq); @@ -135,10 +153,10 @@ public class InfoDisplayController extends FormBasicController { this.resSubPath = resSubPath; this.businessPath = businessPath; - userManager = CoreSpringFactory.getImpl(UserManager.class); - infoMessageManager = CoreSpringFactory.getImpl(InfoMessageFrontendManager.class); maxResults = maxResultsConfig = getConfigValue(config, InfoCourseNodeConfiguration.CONFIG_LENGTH, 10); duration = getConfigValue(config, InfoCourseNodeConfiguration.CONFIG_DURATION, 90); + thumbnailMapper = registerCacheableMapper(ureq, "InfoMessagesThumbnail", new ThumbnailMapper()); + attachmentMapper = registerCacheableMapper(ureq, "InfoMessages", new AttachmentMapper()); if(duration > 0) { Calendar cal = Calendar.getInstance(); @@ -182,7 +200,7 @@ public class InfoDisplayController extends FormBasicController { } public List<SendMailOption> getSendMailOptions() { - return this.sendMailOptions; + return sendMailOptions; } public void addSendMailOptions(SendMailOption sendMailOption) { @@ -217,9 +235,14 @@ public class InfoDisplayController extends FormBasicController { List<InfoMessage> msgs = infoMessageManager.loadInfoMessageByResource(ores, resSubPath, businessPath, after, null, 0, maxResults); List<InfoMessageForDisplay> infoDisplays = new ArrayList<>(msgs.size()); + Map<Long,VFSLeaf> keyToDisplay = new HashMap<>(); for(InfoMessage info:msgs) { previousDisplayKeys.add(info.getKey()); - infoDisplays.add(createInfoMessageForDisplay(info)); + InfoMessageForDisplay infoDisplay = createInfoMessageForDisplay(info); + infoDisplays.add(infoDisplay); + if(infoDisplay.getAttachment() != null) { + keyToDisplay.put(info.getKey(), infoDisplay.getAttachment()); + } String dateCmpName = "info.date." + info.getKey(); DateElement dateEl = DateComponentFactory.createDateElementWithYear(dateCmpName, info.getCreationDate()); @@ -243,6 +266,7 @@ public class InfoDisplayController extends FormBasicController { } } flc.contextPut("infos", infoDisplays); + infoKeyToAttachment = keyToDisplay; int numOfInfos = infoMessageManager.countInfoMessageByResource(ores, resSubPath, businessPath, null, null); oldMsgsLink.setVisible((msgs.size() < numOfInfos)); @@ -275,9 +299,9 @@ public class InfoDisplayController extends FormBasicController { infos = translate("display.info.noauthor", new String[]{creationDate}); } else { infos = translate("display.info", new String[]{StringHelper.escapeHtml(authorName), creationDate}); - } - - return new InfoMessageForDisplay(info.getKey(), info.getTitle(), message, infos, modifier); + } + VFSLeaf attachment = infoMessageManager.getAttachment(info); + return new InfoMessageForDisplay(info.getKey(), info.getTitle(), message, attachment, infos, modifier); } @Override @@ -291,6 +315,12 @@ public class InfoDisplayController extends FormBasicController { oldMsgsLink.setElementCssClass("o_sel_course_info_old_msgs"); newMsgsLink = uifactory.addFormLink("display.new_messages", "display.new_messages", "display.new_messages", formLayout, Link.BUTTON); newMsgsLink.setElementCssClass("o_sel_course_info_new_msgs"); + + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; + layoutCont.contextPut("thumbnailMapper", thumbnailMapper); + layoutCont.contextPut("attachmentMapper", attachmentMapper); + } } @Override @@ -356,7 +386,8 @@ public class InfoDisplayController extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == newInfoLink) { - start = new CreateInfoStep(ureq, sendMailOptions); + InfoMessage msg = infoMessageManager.createInfoMessage(ores, resSubPath, businessPath, getIdentity()); + start = new CreateInfoStep(ureq, sendMailOptions, msg); newInfoWizard = new StepsMainRunController(ureq, getWindowControl(), start, new FinishedCallback(), new CancelCallback(), translate("create_message"), "o_sel_info_messages_create_wizard"); listenTo(newInfoWizard); @@ -380,6 +411,11 @@ public class InfoDisplayController extends FormBasicController { } } + @Override + protected void propagateDirtinessToContainer(FormItem fiSrc, FormEvent fe) { + //nothing to do + } + protected void popupDelete(UserRequest ureq, InfoMessage msg) { OLATResourceable mres = OresHelper.createOLATResourceableInstance(InfoMessage.class, msg.getKey()); lockEntry = CoordinatorManager.getInstance().getCoordinator().getLocker().acquireLock(mres, ureq.getIdentity(), ""); @@ -435,16 +471,13 @@ public class InfoDisplayController extends FormBasicController { @Override public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) { - String title = (String)runContext.get(WizardConstants.MSG_TITLE); - String message = (String)runContext.get(WizardConstants.MSG_MESSAGE); + InfoMessage msg = (InfoMessage)runContext.get(WizardConstants.MSG); @SuppressWarnings("unchecked") Set<String> selectedOptions = (Set<String>)runContext.get(WizardConstants.SEND_MAIL); - - InfoMessage msg = infoMessageManager.createInfoMessage(ores, resSubPath, businessPath, ureq.getIdentity()); - msg.setTitle(title); - msg.setMessage(message); - - List<Identity> identities = new ArrayList<Identity>(); + @SuppressWarnings("unchecked") + Collection<String> pathToDelete = (Set<String>)runContext.get(WizardConstants.PATH_TO_DELETE); + + List<Identity> identities = new ArrayList<>(); for(SendMailOption option:sendMailOptions) { if(selectedOptions != null && selectedOptions.contains(option.getOptionKey())) { identities.addAll(option.getSelectedIdentities()); @@ -452,6 +485,7 @@ public class InfoDisplayController extends FormBasicController { } infoMessageManager.sendInfoMessage(msg, sendMailFormatter, ureq.getLocale(), ureq.getIdentity(), identities); + infoMessageManager.deleteAttachments(pathToDelete); ThreadLocalUserActivityLogger.log(CourseLoggingAction.INFO_MESSAGE_CREATED, getClass(), LoggingResourceable.wrap(msg.getOLATResourceable(), OlatResourceableType.infoMessage)); @@ -463,7 +497,63 @@ public class InfoDisplayController extends FormBasicController { protected class CancelCallback implements StepRunnerCallback { @Override public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) { + @SuppressWarnings("unchecked") + Collection<String> pathToDelete = (Set<String>)runContext.get(WizardConstants.PATH_TO_DELETE); + infoMessageManager.deleteAttachments(pathToDelete); return Step.NOSTEP; } } + + private class AttachmentMapper implements Mapper { + @Override + public MediaResource handle(String relPath, HttpServletRequest request) { + if(infoKeyToAttachment == null) { + return new NotFoundMediaResource(relPath); + } + + String[] query = relPath.split("/"); + if(query.length > 1) { + try { + Long infoKey = Long.valueOf(Long.parseLong(query[1])); + VFSLeaf attachment = infoKeyToAttachment.get(infoKey); + return new VFSMediaResource(attachment); + } catch (NumberFormatException e) { + //ignore them + } + } + return new NotFoundMediaResource(relPath); + } + } + + private class ThumbnailMapper implements Mapper { + @Override + public MediaResource handle(String relPath, HttpServletRequest request) { + if(infoKeyToAttachment == null) { + return new NotFoundMediaResource(relPath); + } + + String[] query = relPath.split("/"); + if(query.length > 2) { + try { + Long infoKey = Long.valueOf(Long.parseLong(query[1])); + VFSLeaf attachment = infoKeyToAttachment.get(infoKey); + if(attachment != null) { + MetaInfo meta = ((MetaTagged)attachment).getMetaInfo(); + if (meta.getUUID().equals(query[2])) { + if (meta.isThumbnailAvailable()) { + VFSLeaf thumb = meta.getThumbnail(200, 200, false); + if(thumb != null) { + // Positive lookup, send as response + return new VFSMediaResource(thumb); + } + } + } + } + } catch (NumberFormatException e) { + //ignore them + } + } + return new NotFoundMediaResource(relPath); + } + } } diff --git a/src/main/java/org/olat/commons/info/ui/InfoDisplayHelper.java b/src/main/java/org/olat/commons/info/ui/InfoDisplayHelper.java index 59872431cbb..7df8af9f57c 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoDisplayHelper.java +++ b/src/main/java/org/olat/commons/info/ui/InfoDisplayHelper.java @@ -20,7 +20,7 @@ package org.olat.commons.info.ui; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; import org.olat.core.gui.translator.Translator; import org.olat.core.id.User; import org.olat.core.id.UserConstants; diff --git a/src/main/java/org/olat/commons/info/ui/InfoEditController.java b/src/main/java/org/olat/commons/info/ui/InfoEditController.java index b98ef00262b..bdc3164787e 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoEditController.java +++ b/src/main/java/org/olat/commons/info/ui/InfoEditController.java @@ -20,11 +20,11 @@ package org.olat.commons.info.ui; +import java.util.Collection; import java.util.Date; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; -import org.olat.core.CoreSpringFactory; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; @@ -36,11 +36,9 @@ import org.olat.core.logging.activity.CourseLoggingAction; import org.olat.core.logging.activity.OlatResourceableType; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; /** - * - * Description:<br> - * TODO: srosse Class Description for InfoEditController * * <P> * Initial Date: 24 aug. 2010 <br> @@ -48,33 +46,29 @@ import org.olat.util.logging.activity.LoggingResourceable; */ public class InfoEditController extends FormBasicController { - private final InfoMessage messageToEdit; + private InfoMessage messageToEdit; private final InfoEditFormController editForm; - private final InfoMessageFrontendManager infoFrontendManager; + + @Autowired + private InfoMessageFrontendManager infoFrontendManager; public InfoEditController(UserRequest ureq, WindowControl wControl, InfoMessage messageToEdit) { super(ureq, wControl, "edit"); - this.messageToEdit = messageToEdit; - infoFrontendManager = CoreSpringFactory.getImpl(InfoMessageFrontendManager.class); - editForm = new InfoEditFormController(ureq, wControl, mainForm, false); - editForm.setTitle(messageToEdit.getTitle()); - editForm.setMessage(messageToEdit.getMessage()); + editForm = new InfoEditFormController(ureq, wControl, mainForm, false, messageToEdit); listenTo(editForm); - initForm(ureq); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { FormLayoutContainer editCont = editForm.getInitialFormItem(); + flc.add("edit", editCont); final FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator()); editCont.add(buttonLayout); uifactory.addFormSubmitButton("submit", buttonLayout); uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl()); - - flc.add("edit", editCont); } @Override @@ -89,14 +83,13 @@ public class InfoEditController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { - String title = editForm.getTitle(); - String message = editForm.getMessage(); - - messageToEdit.setTitle(title); - messageToEdit.setMessage(message); + messageToEdit = editForm.getInfoMessage(); messageToEdit.setModificationDate(new Date()); messageToEdit.setModifier(getIdentity()); - infoFrontendManager.sendInfoMessage(messageToEdit, null, null, ureq.getIdentity(), null); + infoFrontendManager.sendInfoMessage(messageToEdit, null, null, getIdentity(), null); + + Collection<String> pathToDelete = editForm.getAttachmentPathToDelete(); + infoFrontendManager.deleteAttachments(pathToDelete); ThreadLocalUserActivityLogger.log(CourseLoggingAction.INFO_MESSAGE_UPDATED, getClass(), LoggingResourceable.wrap(messageToEdit.getOLATResourceable(), OlatResourceableType.infoMessage)); diff --git a/src/main/java/org/olat/commons/info/ui/InfoEditFormController.java b/src/main/java/org/olat/commons/info/ui/InfoEditFormController.java index fbddbb7bc80..a969747bd30 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoEditFormController.java +++ b/src/main/java/org/olat/commons/info/ui/InfoEditFormController.java @@ -20,16 +20,31 @@ package org.olat.commons.info.ui; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FileElement; import org.olat.core.gui.components.form.flexible.elements.RichTextElement; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.util.StringHelper; +import org.olat.core.util.ValidationStatus; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -41,13 +56,23 @@ import org.olat.core.util.StringHelper; */ public class InfoEditFormController extends FormBasicController { - private TextElement title; - private RichTextElement message; + private TextElement titleEl; + private FileElement attachmentEl; + private RichTextElement messageEl; + + private String attachmentPath; + private Set<String> attachmentPathToDelete = new HashSet<>(); + private final boolean showTitle; + private final InfoMessage infoMessage; + + @Autowired + private InfoMessageFrontendManager infoMessageFrontendManager; - public InfoEditFormController(UserRequest ureq, WindowControl wControl, Form mainForm, boolean showTitle) { + public InfoEditFormController(UserRequest ureq, WindowControl wControl, Form mainForm, boolean showTitle, InfoMessage infoMessage) { super(ureq, wControl, LAYOUT_DEFAULT, null, mainForm); this.showTitle = showTitle; + this.infoMessage = infoMessage; initForm(ureq); } @@ -58,16 +83,27 @@ public class InfoEditFormController extends FormBasicController { setFormTitle("edit.title"); } - title = uifactory.addTextElement("info_title", "edit.info_title", 512, "", formLayout); - title.setElementCssClass("o_sel_info_title"); - title.setMandatory(true); - - message = uifactory.addRichTextElementForStringDataMinimalistic("edit.info_message", "edit.info_message", "", 6, 80, + String title = infoMessage.getTitle(); + titleEl = uifactory.addTextElement("info_title", "edit.info_title", 512, title, formLayout); + titleEl.setElementCssClass("o_sel_info_title"); + titleEl.setMandatory(true); + + String message = infoMessage.getMessage(); + messageEl = uifactory.addRichTextElementForStringDataMinimalistic("edit.info_message", "edit.info_message", message, 6, 80, formLayout, getWindowControl()); - message.getEditorConfiguration().setRelativeUrls(false); - message.getEditorConfiguration().setRemoveScriptHost(false); - message.setMandatory(true); - message.setMaxLength(2000); + messageEl.getEditorConfiguration().setRelativeUrls(false); + messageEl.getEditorConfiguration().setRemoveScriptHost(false); + messageEl.setMandatory(true); + messageEl.setMaxLength(2000); + + attachmentEl = uifactory.addFileElement(getWindowControl(), "attachment", formLayout); + attachmentEl.setDeleteEnabled(true); + attachmentEl.setMaxUploadSizeKB(5000, "attachment.max.size", new String[] { "5000" }); + attachmentEl.addActionListener(FormEvent.ONCHANGE); + if(infoMessage.getAttachmentPath() != null) { + attachmentPath = infoMessage.getAttachmentPath(); + attachmentPathToDelete.add(infoMessage.getAttachmentPath()); + } } @Override @@ -75,54 +111,76 @@ public class InfoEditFormController extends FormBasicController { // } - public String getTitle() { - return title.getValue(); - } - - public void setTitle(String titleStr) { - title.setValue(titleStr); - } - - public String getMessage() { - return message.getValue(); - } - - public void setMessage(String messageStr) { - message.setValue(messageStr); - } - @Override protected void formOK(UserRequest ureq) { // } + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(attachmentEl == source) { + if (attachmentEl.isUploadSuccess()) { + File uploadedFile = attachmentEl.getUploadFile(); + String uploadedFilename = attachmentEl.getUploadFileName(); + if(attachmentPath != null) { + attachmentPathToDelete.add(attachmentPath); + } + attachmentPath = infoMessageFrontendManager.storeAttachment(uploadedFile, uploadedFilename, infoMessage.getOLATResourceable(), infoMessage.getResSubPath()); + } else { + attachmentPathToDelete.add(attachmentPath); + } + this.fireEvent(ureq, Event.CHANGED_EVENT); + } + super.formInnerEvent(ureq, source, event); + } + @Override protected boolean validateFormLogic(UserRequest ureq) { - title.clearError(); - message.clearError(); + titleEl.clearError(); + messageEl.clearError(); boolean allOk = true; - String t = title.getValue(); + String t = titleEl.getValue(); if(!StringHelper.containsNonWhitespace(t)) { - title.setErrorKey("form.legende.mandatory", new String[] {}); + titleEl.setErrorKey("form.legende.mandatory", new String[] {}); allOk = false; } else if (t.length() > 500) { - title.setErrorKey("input.toolong", new String[] {"500", Integer.toString(t.length())}); + titleEl.setErrorKey("input.toolong", new String[] {"500", Integer.toString(t.length())}); allOk = false; } - String m = message.getValue(); + String m = messageEl.getValue(); if(!StringHelper.containsNonWhitespace(m)) { - message.setErrorKey("form.legende.mandatory", new String[] {}); + messageEl.setErrorKey("form.legende.mandatory", new String[] {}); allOk = false; } else if (m.length() > 2000) { - message.setErrorKey("input.toolong", new String[] {"2000", Integer.toString(m.length())}); + messageEl.setErrorKey("input.toolong", new String[] {"2000", Integer.toString(m.length())}); allOk = false; } - return allOk && super.validateFormLogic(ureq); + List<ValidationStatus> validation = new ArrayList<>(); + attachmentEl.validate(validation); + if(validation.size() > 0) { + allOk &= false; + } + return allOk & super.validateFormLogic(ureq); + } + + public InfoMessage getInfoMessage() { + infoMessage.setTitle(titleEl.getValue()); + infoMessage.setMessage(messageEl.getValue()); + infoMessage.setAttachmentPath(attachmentPath); + return infoMessage; + } + + public Collection<String> getAttachmentPathToDelete() { + if(attachmentPath != null) { + attachmentPathToDelete.remove(attachmentPath); + } + return attachmentPathToDelete; } + @Override public FormLayoutContainer getInitialFormItem() { return flc; } diff --git a/src/main/java/org/olat/commons/info/ui/InfoMessageForDisplay.java b/src/main/java/org/olat/commons/info/ui/InfoMessageForDisplay.java index 1aa3d4f550e..bcf541804c0 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoMessageForDisplay.java +++ b/src/main/java/org/olat/commons/info/ui/InfoMessageForDisplay.java @@ -21,6 +21,7 @@ package org.olat.commons.info.ui; import org.olat.core.util.StringHelper; +import org.olat.core.util.vfs.VFSLeaf; /** * @@ -38,13 +39,15 @@ public class InfoMessageForDisplay { private final String message; private final String infos; private final String modifier; + private final VFSLeaf attachment; - public InfoMessageForDisplay(Long key, String title, String message, String infos, String modifier) { + public InfoMessageForDisplay(Long key, String title, String message, VFSLeaf attachment, String infos, String modifier) { this.key = key; this.title = title; this.infos = infos; this.message = message; this.modifier = modifier; + this.attachment = attachment; } public Long getKey() { @@ -62,6 +65,10 @@ public class InfoMessageForDisplay { public String getInfos() { return infos; } + + public VFSLeaf getAttachment() { + return attachment; + } public boolean isModified() { return StringHelper.containsNonWhitespace(modifier); diff --git a/src/main/java/org/olat/commons/info/ui/InfoSecurityCallback.java b/src/main/java/org/olat/commons/info/ui/InfoSecurityCallback.java index 562bed7e944..60d72549932 100644 --- a/src/main/java/org/olat/commons/info/ui/InfoSecurityCallback.java +++ b/src/main/java/org/olat/commons/info/ui/InfoSecurityCallback.java @@ -20,7 +20,7 @@ package org.olat.commons.info.ui; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; /** * diff --git a/src/main/java/org/olat/commons/info/ui/SendInfoMailFormatter.java b/src/main/java/org/olat/commons/info/ui/SendInfoMailFormatter.java index edff133c6db..b4fd472a2b0 100644 --- a/src/main/java/org/olat/commons/info/ui/SendInfoMailFormatter.java +++ b/src/main/java/org/olat/commons/info/ui/SendInfoMailFormatter.java @@ -24,8 +24,8 @@ package org.olat.commons.info.ui; import java.text.DateFormat; import java.util.List; +import org.olat.commons.info.InfoMessage; import org.olat.commons.info.manager.MailFormatter; -import org.olat.commons.info.model.InfoMessage; import org.olat.core.gui.translator.Translator; import org.olat.core.helpers.Settings; import org.olat.core.id.UserConstants; diff --git a/src/main/java/org/olat/commons/info/ui/SendMailOption.java b/src/main/java/org/olat/commons/info/ui/SendMailOption.java index 4554d99b074..c919d6f93fa 100644 --- a/src/main/java/org/olat/commons/info/ui/SendMailOption.java +++ b/src/main/java/org/olat/commons/info/ui/SendMailOption.java @@ -21,7 +21,6 @@ package org.olat.commons.info.ui; import java.util.List; -import java.util.Locale; import org.olat.core.id.Identity; @@ -37,7 +36,7 @@ public interface SendMailOption { public String getOptionKey(); - public String getOptionTranslatedName(Locale locale); + public String getOptionName(); public List<Identity> getSelectedIdentities(); diff --git a/src/main/java/org/olat/commons/info/ui/SendMailStepController.java b/src/main/java/org/olat/commons/info/ui/SendMailStepController.java index d503830da8d..628d80e39e4 100644 --- a/src/main/java/org/olat/commons/info/ui/SendMailStepController.java +++ b/src/main/java/org/olat/commons/info/ui/SendMailStepController.java @@ -57,7 +57,7 @@ public class SendMailStepController extends StepFormBasicController { int count = 0; for(SendMailOption option:options) { sendOptionKeys[count] = option.getOptionKey(); - sendOptionValues[count++] = option.getOptionTranslatedName(ureq.getLocale()); + sendOptionValues[count++] = option.getOptionName(); } initForm(ureq); diff --git a/src/main/java/org/olat/commons/info/ui/SendSubscriberMailOption.java b/src/main/java/org/olat/commons/info/ui/SendSubscriberMailOption.java index 2d568e7c6a5..927c1bdd0f8 100644 --- a/src/main/java/org/olat/commons/info/ui/SendSubscriberMailOption.java +++ b/src/main/java/org/olat/commons/info/ui/SendSubscriberMailOption.java @@ -23,8 +23,8 @@ package org.olat.commons.info.ui; import java.util.List; import java.util.Locale; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.core.gui.translator.Translator; +import org.olat.commons.info.InfoMessageFrontendManager; +import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.util.Util; @@ -40,14 +40,15 @@ import org.olat.core.util.Util; */ public class SendSubscriberMailOption implements SendMailOption { - private final OLATResourceable ores; + private final String label; private final String resSubPath; - private final InfoMessageFrontendManager messageManager; + private final OLATResourceable ores; - public SendSubscriberMailOption(OLATResourceable ores, String resSubPath, InfoMessageFrontendManager messageManager) { + public SendSubscriberMailOption(OLATResourceable ores, String resSubPath, Locale locale) { this.ores = ores; this.resSubPath = resSubPath; - this.messageManager = messageManager; + label = Util.createPackageTranslator(SendSubscriberMailOption.class, locale) + .translate("wizard.step1.send_option.subscriber"); } @Override @@ -56,14 +57,12 @@ public class SendSubscriberMailOption implements SendMailOption { } @Override - public String getOptionTranslatedName(Locale locale) { - Translator translator = Util.createPackageTranslator(SendSubscriberMailOption.class, locale); - return translator.translate("wizard.step1.send_option.subscriber"); + public String getOptionName() { + return label; } @Override public List<Identity> getSelectedIdentities() { - List<Identity> identities = messageManager.getInfoSubscribers(ores, resSubPath); - return identities; + return CoreSpringFactory.getImpl(InfoMessageFrontendManager.class).getInfoSubscribers(ores, resSubPath); } } diff --git a/src/main/java/org/olat/commons/info/ui/WizardConstants.java b/src/main/java/org/olat/commons/info/ui/WizardConstants.java index b0a03073778..31843c5b509 100644 --- a/src/main/java/org/olat/commons/info/ui/WizardConstants.java +++ b/src/main/java/org/olat/commons/info/ui/WizardConstants.java @@ -21,9 +21,7 @@ package org.olat.commons.info.ui; /** - * - * Description:<br> - * TODO: srosse Class Description for WizardConstants + * * <P> * Initial Date: 28 jul. 2010 <br> @@ -32,11 +30,9 @@ package org.olat.commons.info.ui; public class WizardConstants { public static final String SEND_MAIL = "send"; - public static final String SEND_MAIL_ALL = "all"; - public static final String SEND_MAIL_GROUPS = "groups"; public static final String SEND_MAIL_SUBSCRIBERS = "subscribers"; - public static final String MSG_TITLE = "title"; - public static final String MSG_MESSAGE = "message"; + public static final String MSG = "message"; + public static final String PATH_TO_DELETE = "pathToDelete"; } diff --git a/src/main/java/org/olat/commons/info/ui/_content/display.html b/src/main/java/org/olat/commons/info/ui/_content/display.html index 07f554e7046..630a35bf982 100644 --- a/src/main/java/org/olat/commons/info/ui/_content/display.html +++ b/src/main/java/org/olat/commons/info/ui/_content/display.html @@ -34,6 +34,24 @@ </div> #if($info.getMessage()) <div class="o_content">$info.getMessage()</div> + #end + + #if($r.isNotEmpty($info.attachment)) + <div class="o_attachment"> + #set($attachment = $info.attachment) + #set($fname = $attachment.name) + <a href="${attachmentMapper}/$info.key/$fname" target="_blank"> + <div class="o_filename">$r.escapeHtml($fname)</div> + <div class="o_size"> + <i class="o_icon o_icon-fw $r.getFiletypeIconCss($fname)"></i> + $r.formatBytes($attachment.getSize()) + </div> + #if ($attachment.getMetaInfo() && $attachment.getMetaInfo().isThumbnailAvailable()) + <img src="${thumbnailMapper}/$info.key/$attachment.getMetaInfo().getUUID()/$fname" class="img-thumbnail" alt="$r.escapeHtml("$fname")" title="$r.escapeHtml("$fname")"/> + <i class="o_icon o_icon-lg o_icon_enlarge"> </i> + #end + </a> + </div> #end #if($r.available("info.delete.${info.getKey()}") or $r.available("info.edit.${info.getKey()}")) <div class="o_button_group"> diff --git a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_de.properties index e2bdfad10a7..0736846e8d5 100644 --- a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_de.properties @@ -1,6 +1,8 @@ #Mon Mar 02 09:54:04 CET 2009 already.deleted=Diese Mitteilung wurde inzwischen durch einen anderen Benutzer gel\u00F6scht. already.edited=Diese Mitteilung wird zurzeit von Benutzer {0} bearbeitet. Versuchen Sie es sp\u00E4ter noch einmal. +attachment=Datei +attachment.max.size=$org.olat.commons.file.filechooser\:error.limit.exceeded new_message=Neue Mitteilung erstellen create_message=Mitteilung erstellen input.toolong=Leider ist Ihr gerade eingegebener Text mit {1} Zeichen zu lang. Bitte beschr\u00E4nken Sie sich auf maximal {0} Zeichen. diff --git a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_en.properties index 59c8bee1e71..f043d1488b2 100644 --- a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_en.properties @@ -1,6 +1,8 @@ #Wed Jan 05 12:37:20 CET 2011 already.deleted=This message has been deleted in the meantime by another user. already.edited=This message is being edited by user {0}. Please try again later. +attachment=File +attachment.max.size=$org.olat.commons.file.filechooser\:error.limit.exceeded create_message=Create message display.info=Published by {0} on {1} display.info.noauthor=Published on {0} diff --git a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_fr.properties index 95cac8ebade..2b9eebd335c 100644 --- a/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/commons/info/ui/_i18n/LocalStrings_fr.properties @@ -1,6 +1,7 @@ #Tue Apr 04 18:37:01 CEST 2017 already.deleted=Entretemps, cette communication a \u00E9t\u00E9 effac\u00E9 par un autre utilisateur. already.edited=Cette communication est actuellement en cours d'\u00E9laboration par l'utilisateur {0}. R\u00E9essayez plus tard, svp. +attachment.max.size=$org.olat.commons.file.filechooser\:error.limit.exceeded create_message=Cr\u00E9er communication display.info=Publi\u00E9 par {0} le {1} display.info.noauthor=Publi\u00E9 le {0} diff --git a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml index 932c363c47e..3eeefcd69a1 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml +++ b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml @@ -14,7 +14,6 @@ <bean id="org.olat.course.nodes.ta.SolutionFileUploadNotificationHandler" class="org.olat.course.nodes.ta.SolutionFileUploadNotificationHandler"/> <bean id="org.olat.modules.wiki.WikiPageChangeOrCreateNotificationHandler" class="org.olat.modules.wiki.WikiPageChangeOrCreateNotificationHandler" /> <bean id="org.olat.user.notification.NewUsersNotificationHandler" class="org.olat.user.notification.NewUsersNotificationHandler" /> - <bean id="org.olat.commons.info.notification.InfoMessageNotificationHandler" class="org.olat.commons.info.notification.InfoMessageNotificationHandler" /> <bean id="notificationsManager" class="org.olat.core.commons.services.notifications.manager.NotificationsManagerImpl" > <property name="dbInstance" ref="database"/> diff --git a/src/main/java/org/olat/course/nodes/InfoCourseNode.java b/src/main/java/org/olat/course/nodes/InfoCourseNode.java index b166086cbe8..c32b40ad660 100644 --- a/src/main/java/org/olat/course/nodes/InfoCourseNode.java +++ b/src/main/java/org/olat/course/nodes/InfoCourseNode.java @@ -23,8 +23,8 @@ package org.olat.course.nodes; import java.util.ArrayList; import java.util.List; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; diff --git a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java index 8e25a60a277..225d0551255 100644 --- a/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java +++ b/src/main/java/org/olat/course/nodes/info/InfoPeekViewController.java @@ -25,9 +25,8 @@ import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; -import org.olat.core.CoreSpringFactory; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.table.BaseTableDataModelWithoutFilter; @@ -51,6 +50,7 @@ import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseModule; import org.olat.course.nodes.InfoCourseNode; import org.olat.course.run.userview.UserCourseEnvironment; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -67,6 +67,9 @@ public class InfoPeekViewController extends BasicController { private final InfoCourseNode courseNode; private TableController tableController; + + @Autowired + private InfoMessageFrontendManager infoService; public InfoPeekViewController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, InfoCourseNode courseNode) { @@ -96,8 +99,7 @@ public class InfoPeekViewController extends BasicController { tableController.addColumnDescriptor(new CustomRenderColumnDescriptor("peekview.title", 0, null, ureq.getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, new InfoNodeRenderer())); - String resSubPath = this.courseNode.getIdent(); - InfoMessageFrontendManager infoService = CoreSpringFactory.getImpl(InfoMessageFrontendManager.class); + String resSubPath = courseNode.getIdent(); List<InfoMessage> infos = infoService.loadInfoMessageByResource(ores, resSubPath, null, null, null, 0, 5); InfosTableModel model = new InfosTableModel(infos); diff --git a/src/main/java/org/olat/course/nodes/info/InfoRunController.java b/src/main/java/org/olat/course/nodes/info/InfoRunController.java index 89278a096a9..ad828dd2404 100644 --- a/src/main/java/org/olat/course/nodes/info/InfoRunController.java +++ b/src/main/java/org/olat/course/nodes/info/InfoRunController.java @@ -24,16 +24,15 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import org.olat.basesecurity.GroupRoles; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoSubscriptionManager; import org.olat.commons.info.manager.MailFormatter; -import org.olat.commons.info.model.InfoMessage; import org.olat.commons.info.notification.InfoSubscription; -import org.olat.commons.info.notification.InfoSubscriptionManager; import org.olat.commons.info.ui.InfoDisplayController; import org.olat.commons.info.ui.InfoSecurityCallback; import org.olat.commons.info.ui.SendInfoMailFormatter; import org.olat.commons.info.ui.SendSubscriberMailOption; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.PublisherData; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.commons.services.notifications.ui.ContextualSubscriptionController; @@ -56,10 +55,9 @@ import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.nodes.InfoCourseNode; import org.olat.course.run.userview.NodeEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; -import org.olat.group.BusinessGroupService; import org.olat.modules.ModuleConfiguration; import org.olat.repository.RepositoryManager; -import org.olat.repository.RepositoryService; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -77,27 +75,28 @@ public class InfoRunController extends BasicController { private ContextualSubscriptionController subscriptionController; private final String businessPath; - private final InfoCourseNode courseNode; - private final ModuleConfiguration config; + + @Autowired + private RepositoryManager repositoryManager; + @Autowired private InfoSubscriptionManager subscriptionManager; public InfoRunController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, NodeEvaluation ne, InfoCourseNode courseNode) { super(ureq, wControl); - - this.courseNode = courseNode; - this.config = courseNode.getModuleConfiguration(); + ModuleConfiguration config = courseNode.getModuleConfiguration(); Long resId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); - ICourse course = CourseFactory.loadCourse(resId); - String resSubPath = this.courseNode.getIdent(); + + String resSubPath = courseNode.getIdent(); OLATResourceable infoResourceable = new InfoOLATResourceable(resId); businessPath = normalizeBusinessPath(wControl.getBusinessControl().getAsString()); + ICourse course = CourseFactory.loadCourse(resId); + CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); //manage opt-out subscription UserSession usess = ureq.getUserSession(); if(!usess.getRoles().isGuestOnly()) { - subscriptionManager = InfoSubscriptionManager.getInstance(); SubscriptionContext subContext = subscriptionManager.getInfoSubscriptionContext(infoResourceable, resSubPath); PublisherData pdata = subscriptionManager.getInfoPublisherData(infoResourceable, businessPath); if(InfoCourseNodeEditController.getAutoSubscribe(config)) { @@ -116,28 +115,23 @@ public class InfoRunController extends BasicController { } else { Identity identity = getIdentity(); Roles roles = usess.getRoles(); - CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean institutionalManager = RepositoryManager.getInstance().isInstitutionalRessourceManagerFor(identity, roles, cgm.getCourseEntry()); - boolean courseAdmin = cgm.isIdentityCourseAdministrator(identity); - - canAdd = courseAdmin - || ne.isCapabilityAccessible(InfoCourseNode.EDIT_CONDITION_ID) - || institutionalManager - || roles.isOLATAdmin(); - canAdmin = courseAdmin - || ne.isCapabilityAccessible(InfoCourseNode.ADMIN_CONDITION_ID) - || institutionalManager - || roles.isOLATAdmin(); + boolean isAdmin = roles.isOLATAdmin() + || cgm.isIdentityCourseAdministrator(identity) + || repositoryManager.isInstitutionalRessourceManagerFor(identity, roles, cgm.getCourseEntry()); + + canAdd = isAdmin || ne.isCapabilityAccessible(InfoCourseNode.EDIT_CONDITION_ID); + canAdmin = isAdmin || ne.isCapabilityAccessible(InfoCourseNode.ADMIN_CONDITION_ID); } InfoSecurityCallback secCallback = new InfoCourseSecurityCallback(getIdentity(), canAdd, canAdmin); - RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); infoDisplayController = new InfoDisplayController(ureq, wControl, config, secCallback, infoResourceable, resSubPath, businessPath); - infoDisplayController.addSendMailOptions(new SendSubscriberMailOption(infoResourceable, resSubPath, CoreSpringFactory.getImpl(InfoMessageFrontendManager.class))); - infoDisplayController.addSendMailOptions(new SendMembersMailOption(course.getCourseEnvironment().getCourseGroupManager().getCourseResource(), - RepositoryManager.getInstance(), repositoryService, CoreSpringFactory.getImpl(BusinessGroupService.class))); + infoDisplayController.addSendMailOptions(new SendSubscriberMailOption(infoResourceable, resSubPath, getLocale())); + infoDisplayController.addSendMailOptions(new SendMembersMailOption(cgm.getCourseEntry(), GroupRoles.owner, translate("wizard.step1.send_option.owner"))); + infoDisplayController.addSendMailOptions(new SendMembersMailOption(cgm.getCourseEntry(), GroupRoles.coach, translate("wizard.step1.send_option.coach"))); + infoDisplayController.addSendMailOptions(new SendMembersMailOption(cgm.getCourseEntry(), GroupRoles.participant, translate("wizard.step1.send_option.participant"))); + MailFormatter mailFormatter = new SendInfoMailFormatter(course.getCourseTitle(), businessPath, getTranslator()); infoDisplayController.setSendMailFormatter(mailFormatter); listenTo(infoDisplayController); diff --git a/src/main/java/org/olat/course/nodes/info/SendMembersMailOption.java b/src/main/java/org/olat/course/nodes/info/SendMembersMailOption.java index 68045c2f53d..1133893d121 100644 --- a/src/main/java/org/olat/course/nodes/info/SendMembersMailOption.java +++ b/src/main/java/org/olat/course/nodes/info/SendMembersMailOption.java @@ -23,19 +23,15 @@ package org.olat.course.nodes.info; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Set; import org.olat.basesecurity.GroupRoles; import org.olat.commons.info.ui.SendMailOption; -import org.olat.core.gui.translator.Translator; +import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; -import org.olat.core.util.Util; import org.olat.group.BusinessGroupService; import org.olat.repository.RepositoryEntry; -import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; -import org.olat.resource.OLATResource; /** * @@ -48,38 +44,38 @@ import org.olat.resource.OLATResource; */ public class SendMembersMailOption implements SendMailOption { - private final OLATResource courseResource; - private final RepositoryManager rm; - private final RepositoryService repositoryService; - private final BusinessGroupService businessGroupService; + private final String label; + private final GroupRoles role; + private final RepositoryEntry repositoryEntry; - public SendMembersMailOption(OLATResource courseResource, RepositoryManager rm, RepositoryService repositoryService, BusinessGroupService businessGroupService) { - this.courseResource = courseResource; - this.rm = rm; - this.repositoryService = repositoryService; - this.businessGroupService = businessGroupService; + public SendMembersMailOption(RepositoryEntry repositoryEntry, GroupRoles role, String label) { + this.role = role; + this.label = label; + this.repositoryEntry = repositoryEntry; } @Override public String getOptionKey() { - return "send-mail-course-members"; + return "send-mail-course-members-" + role.name(); } @Override - public String getOptionTranslatedName(Locale locale) { - Translator translator = Util.createPackageTranslator(SendMembersMailOption.class, locale); - return translator.translate("wizard.step1.send_option.member"); + public String getOptionName() { + return label; } @Override public List<Identity> getSelectedIdentities() { - RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(courseResource, true); + Set<Identity> identities = new HashSet<Identity>(); + if(role == GroupRoles.coach || role == GroupRoles.participant) { + List<Identity> members = CoreSpringFactory.getImpl(BusinessGroupService.class) + .getMembersOf(repositoryEntry, role == GroupRoles.coach, role == GroupRoles.participant); + identities.addAll(members); + } - List<Identity> members = businessGroupService.getMembersOf(repositoryEntry, true, true); - Set<Identity> identities = new HashSet<Identity>(members); - List<Identity> reMembers = repositoryService.getMembers(repositoryEntry, GroupRoles.participant.name(), GroupRoles.coach.name(), GroupRoles.owner.name()); + List<Identity> reMembers = CoreSpringFactory.getImpl(RepositoryService.class) + .getMembers(repositoryEntry, role.name()); identities.addAll(reMembers); - - return new ArrayList<Identity>(identities); + return new ArrayList<>(identities); } } diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_de.properties index 365c9347c77..cdef6e4d18a 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_de.properties @@ -20,7 +20,9 @@ pane.tab.infos_config.auto_subscribe.on=Diese Mitteilungen bei Ansicht automatis peekview.title=Title peekview.more=mehr... peekview.noInfos=Keine Mitteilungen -wizard.step1.send_option.member=Mitglieder, Gruppenbetreuer und Kursbesitzer +wizard.step1.send_option.participant=Mitglieder +wizard.step1.send_option.coach=Betreuer +wizard.step1.send_option.owner=Kursbesitzer diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_en.properties index 2a82e9884e3..617278a2e9a 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_en.properties @@ -20,4 +20,6 @@ peekview.more=more... peekview.noInfos=No notifications peekview.title=Title title_info=Notifications -wizard.step1.send_option.member=Members, group tutors, and course owners +wizard.step1.send_option.participant=Participants +wizard.step1.send_option.coach=Tutors +wizard.step1.send_option.owner=Course owners diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_fr.properties index 0999a110d49..47f5cb49fca 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_fr.properties @@ -20,4 +20,6 @@ peekview.more=plus... peekview.noInfos=Aucune communication peekview.title=Titre title_info=Communications -wizard.step1.send_option.member=Membres, tuteurs de groupes et propri\u00E9taires de cours +wizard.step1.send_option.participant=Participants +wizard.step1.send_option.coach=Tuteurs +wizard.step1.send_option.owner=Propri\u00E9taires de cours diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_it.properties index cf86794682d..1f0a8ae15c3 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_it.properties @@ -20,4 +20,4 @@ peekview.more=di pi\u00F9... peekview.noInfos=Nessuna comunicazione peekview.title=Titolo title_info=Comunicazioni -wizard.step1.send_option.member=Membri, tutori di gruppi e proprietari di corsi + diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_jp.properties index 115c432b64f..02da21e410a 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_jp.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_jp.properties @@ -19,5 +19,4 @@ pane.tab.infos_config.title=$\:pane.tab.infos_config peekview.more=\u3055\u3089\u306B ... peekview.noInfos=\u901A\u77E5\u306A\u3057 peekview.title=\u30BF\u30A4\u30C8\u30EB -title_info=\u901A\u77E5 -wizard.step1.send_option.member=\u30E1\u30F3\u30D0\u30FC\u3001\u30B0\u30EB\u30FC\u30D7\u30C1\u30E5\u30FC\u30BF\u30FC\u304A\u3088\u3073\u30B3\u30FC\u30B9\u30AA\u30FC\u30CA\u30FC +title_info=\u901A\u77E5 \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_nl_NL.properties index 7e00f0cb026..3514fd80bb9 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_nl_NL.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_nl_NL.properties @@ -19,5 +19,4 @@ pane.tab.infos_config.title=$\:pane.tab.infos_config peekview.more=meer... peekview.noInfos=Geen mededelingen peekview.title=Titel -title_info=Mededelingen -wizard.step1.send_option.member=Leden, groepsdocenten en cursuseigenaars +title_info=Mededelingen \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pl.properties index 4c8bd95655a..0b270d1fac9 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pl.properties @@ -19,5 +19,4 @@ pane.tab.infos_config.title=$\:pane.tab.infos_config peekview.more=wi\u0119cej... peekview.noInfos=Brak powiadomie\u0144 peekview.title=Tytu\u0142 -title_info=Powiadomienia -wizard.step1.send_option.member=Cz\u0142onkowie, nauczyciele w grupach i w\u0142a\u015Bciciele kurs\u00F3w +title_info=Powiadomienia \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pt_BR.properties index b93a1164624..15bf5069437 100644 --- a/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/course/nodes/info/_i18n/LocalStrings_pt_BR.properties @@ -19,5 +19,4 @@ pane.tab.infos_config.title=$\:pane.tab.infos_config peekview.more=mais... peekview.noInfos=Sem notifica\u00E7\u00F5es peekview.title=T\u00EDtulo -title_info=Notifica\u00E7\u00F5es -wizard.step1.send_option.member=Membros, tutores de grupo, e os propriet\u00E1rios de curso +title_info=Notifica\u00E7\u00F5es \ No newline at end of file diff --git a/src/main/java/org/olat/group/manager/BusinessGroupMembershipProcessor.java b/src/main/java/org/olat/group/manager/BusinessGroupMembershipProcessor.java index 5fe41b1e5b0..ad8d3141bd4 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupMembershipProcessor.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupMembershipProcessor.java @@ -25,7 +25,7 @@ import java.util.List; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.IdentityRef; import org.olat.basesecurity.model.IdentityRefImpl; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.gui.control.Event; import org.olat.core.util.coordinate.CoordinatorManager; diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java index 23bbd6bfc4c..dbd5d5219fe 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java @@ -44,7 +44,7 @@ import org.olat.basesecurity.IdentityRef; import org.olat.basesecurity.SecurityGroup; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.notifications.NotificationsManager; diff --git a/src/main/java/org/olat/group/ui/run/InfoGroupRunController.java b/src/main/java/org/olat/group/ui/run/InfoGroupRunController.java index 102d4191933..97311924edb 100644 --- a/src/main/java/org/olat/group/ui/run/InfoGroupRunController.java +++ b/src/main/java/org/olat/group/ui/run/InfoGroupRunController.java @@ -23,11 +23,12 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import org.olat.basesecurity.GroupRoles; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; +import org.olat.commons.info.InfoSubscriptionManager; import org.olat.commons.info.manager.MailFormatter; -import org.olat.commons.info.model.InfoMessage; import org.olat.commons.info.notification.InfoSubscription; -import org.olat.commons.info.notification.InfoSubscriptionManager; import org.olat.commons.info.ui.InfoDisplayController; import org.olat.commons.info.ui.InfoSecurityCallback; import org.olat.commons.info.ui.SendInfoMailFormatter; @@ -48,7 +49,6 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.util.UserSession; import org.olat.core.util.resource.OresHelper; import org.olat.group.BusinessGroup; -import org.olat.group.BusinessGroupService; import org.springframework.beans.factory.annotation.Autowired; /** @@ -64,13 +64,9 @@ public class InfoGroupRunController extends BasicController { private ContextualSubscriptionController subscriptionController; private final String businessPath; - private InfoSubscriptionManager subscriptionManager; @Autowired - private BusinessGroupService groupService; - @Autowired - private InfoMessageFrontendManager messageManager; - + private InfoSubscriptionManager subscriptionManager; public InfoGroupRunController(UserRequest ureq, WindowControl wControl, BusinessGroup businessGroup, boolean canAccess, boolean isAdmin) { super(ureq, wControl); @@ -81,7 +77,6 @@ public class InfoGroupRunController extends BasicController { UserSession usess = ureq.getUserSession(); if(!usess.getRoles().isGuestOnly()) { - subscriptionManager = InfoSubscriptionManager.getInstance(); SubscriptionContext subContext = subscriptionManager.getInfoSubscriptionContext(infoResourceable, resSubPath); PublisherData pdata = subscriptionManager.getInfoPublisherData(infoResourceable, businessPath); subscriptionController = new ContextualSubscriptionController(ureq, getWindowControl(), subContext, pdata); @@ -91,10 +86,13 @@ public class InfoGroupRunController extends BasicController { boolean canAddAndEdit = isAdmin || canAccess; InfoSecurityCallback secCallback = new InfoGroupSecurityCallback(getIdentity(), canAddAndEdit, isAdmin); infoDisplayController = new InfoDisplayController(ureq, wControl, secCallback, businessGroup, resSubPath, businessPath); - SendMailOption subscribers = new SendSubscriberMailOption(infoResourceable, resSubPath, messageManager); + SendMailOption subscribers = new SendSubscriberMailOption(infoResourceable, resSubPath, getLocale()); infoDisplayController.addSendMailOptions(subscribers); - SendMailOption groupMembers = new SendGroupMembersMailOption(groupService, businessGroup); - infoDisplayController.addSendMailOptions(groupMembers); + SendMailOption coaches = new SendGroupMembersMailOption(businessGroup, GroupRoles.coach, translate("sendtochooser.form.radio.owners")); + infoDisplayController.addSendMailOptions(coaches); + SendMailOption participants = new SendGroupMembersMailOption(businessGroup, GroupRoles.participant, translate("sendtochooser.form.radio.partip")); + infoDisplayController.addSendMailOptions(participants); + MailFormatter mailFormatter = new SendInfoMailFormatter(businessGroup.getName(), businessPath, getTranslator()); infoDisplayController.setSendMailFormatter(mailFormatter); listenTo(infoDisplayController); diff --git a/src/main/java/org/olat/group/ui/run/SendGroupMembersMailOption.java b/src/main/java/org/olat/group/ui/run/SendGroupMembersMailOption.java index aad0902a4d7..6f079623f78 100644 --- a/src/main/java/org/olat/group/ui/run/SendGroupMembersMailOption.java +++ b/src/main/java/org/olat/group/ui/run/SendGroupMembersMailOption.java @@ -20,12 +20,11 @@ package org.olat.group.ui.run; import java.util.List; -import java.util.Locale; +import org.olat.basesecurity.GroupRoles; import org.olat.commons.info.ui.SendMailOption; -import org.olat.core.gui.translator.Translator; +import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; -import org.olat.core.util.Util; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; @@ -35,30 +34,28 @@ import org.olat.group.BusinessGroupService; */ public class SendGroupMembersMailOption implements SendMailOption { - private BusinessGroupService groupService; + private final String label; + private final GroupRoles role; private BusinessGroup businessGroup; - - public SendGroupMembersMailOption(BusinessGroupService groupService, BusinessGroup businessGroup) { - this.groupService = groupService; + public SendGroupMembersMailOption(BusinessGroup businessGroup, GroupRoles role, String label) { + this.role = role; + this.label = label; this.businessGroup = businessGroup; } @Override public String getOptionKey() { - return "send-mail-group-members"; + return "send-mail-group-members-" + role.name(); } @Override - public String getOptionTranslatedName(Locale locale) { - Translator translator = Util.createPackageTranslator(SendGroupMembersMailOption.class, locale); - return translator.translate("wizard.step1.send_option.member"); + public String getOptionName() { + return label; } @Override public List<Identity> getSelectedIdentities() { - List<Identity> groupMembers = groupService.getMembers(businessGroup); - return groupMembers; + return CoreSpringFactory.getImpl(BusinessGroupService.class).getMembers(businessGroup, role.name()); } - } diff --git a/src/main/java/org/olat/search/service/document/InfoMessageDocument.java b/src/main/java/org/olat/search/service/document/InfoMessageDocument.java index 32dbc036832..dfa51e3aa66 100644 --- a/src/main/java/org/olat/search/service/document/InfoMessageDocument.java +++ b/src/main/java/org/olat/search/service/document/InfoMessageDocument.java @@ -20,7 +20,7 @@ package org.olat.search.service.document; import org.apache.lucene.document.Document; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.search.model.OlatDocument; diff --git a/src/main/java/org/olat/search/service/indexer/group/GroupInfoIndexer.java b/src/main/java/org/olat/search/service/indexer/group/GroupInfoIndexer.java index 85383e3020e..053630f8296 100644 --- a/src/main/java/org/olat/search/service/indexer/group/GroupInfoIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/group/GroupInfoIndexer.java @@ -23,9 +23,9 @@ import java.io.IOException; import java.util.List; import org.apache.lucene.document.Document; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.manager.InfoMessageManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageFrontendManager; +import org.olat.commons.info.InfoMessageManager; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; diff --git a/src/main/java/org/olat/search/service/indexer/repository/course/InfoCourseNodeIndexer.java b/src/main/java/org/olat/search/service/indexer/repository/course/InfoCourseNodeIndexer.java index 911f50bb9a1..5e8f9f4457c 100644 --- a/src/main/java/org/olat/search/service/indexer/repository/course/InfoCourseNodeIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/repository/course/InfoCourseNodeIndexer.java @@ -29,8 +29,8 @@ import java.io.IOException; import java.util.List; import org.apache.lucene.document.Document; -import org.olat.commons.info.manager.InfoMessageManager; -import org.olat.commons.info.model.InfoMessage; +import org.olat.commons.info.InfoMessage; +import org.olat.commons.info.InfoMessageManager; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_11_4_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_11_4_0.java index b53359fe722..194e20f6d7f 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_11_4_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_11_4_0.java @@ -24,7 +24,7 @@ import java.util.List; import org.olat.basesecurity.GroupRoles; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; -import org.olat.commons.info.manager.InfoMessageFrontendManager; +import org.olat.commons.info.InfoMessageFrontendManager; import org.olat.commons.info.model.InfoMessageImpl; import org.olat.core.commons.persistence.DB; import org.olat.core.gui.translator.Translator; diff --git a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql index f799c67ddf1..e602d69a65b 100644 --- a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql @@ -248,6 +248,7 @@ alter table o_gta_task add column fk_allow_reset_identity bigint default null; alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); +alter table o_info_message add column attachmentpath varchar(1024) default null; diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index bcf6000daf6..d48bb6c9ac6 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -783,6 +783,7 @@ create table if not exists o_info_message ( modificationdate datetime, title varchar(2048), message longtext, + attachmentpath varchar(1024), resname varchar(50) NOT NULL, resid bigint NOT NULL, ressubpath varchar(2048), diff --git a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql index 8bf3d7e7bd2..135895b7568 100644 --- a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql @@ -250,3 +250,5 @@ alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); +alter table alter table o_info_message add attachmentpath varchar(1024) default null; + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 4bcffaa396f..616cd6aa530 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -701,6 +701,7 @@ CREATE TABLE o_info_message ( modificationdate date, title varchar2(2048 char), message clob, + attachmentpath varchar(1024), resname varchar(50 char) NOT NULL, resid number(20) NOT NULL, ressubpath varchar2(2048 char), diff --git a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql index d069ff1f39e..bc764ec4218 100644 --- a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql @@ -250,3 +250,9 @@ alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); +alter table o_info_message add column attachmentpath varchar(1024) default null; + + + + + diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index e18ef22948b..c5f3bda9345 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -629,6 +629,7 @@ create table o_info_message ( modificationdate timestamp, title varchar(2048), message text, + attachmentpath varchar(1024), resname varchar(50) NOT NULL, resid int8 NOT NULL, ressubpath varchar(2048), diff --git a/src/test/java/org/olat/commons/info/InfoManagerTest.java b/src/test/java/org/olat/commons/info/InfoManagerTest.java index d57d2cb0115..63d1f08e63a 100644 --- a/src/test/java/org/olat/commons/info/InfoManagerTest.java +++ b/src/test/java/org/olat/commons/info/InfoManagerTest.java @@ -33,8 +33,6 @@ import java.util.UUID; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.olat.commons.info.manager.InfoMessageManager; -import org.olat.commons.info.model.InfoMessage; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; diff --git a/src/test/java/org/olat/commons/info/InfoMessageFrontendManagerTest.java b/src/test/java/org/olat/commons/info/InfoMessageFrontendManagerTest.java index f1fb12220c0..7099e96c886 100644 --- a/src/test/java/org/olat/commons/info/InfoMessageFrontendManagerTest.java +++ b/src/test/java/org/olat/commons/info/InfoMessageFrontendManagerTest.java @@ -28,8 +28,6 @@ import java.util.UUID; import org.junit.Assert; import org.junit.Test; -import org.olat.commons.info.manager.InfoMessageFrontendManager; -import org.olat.commons.info.model.InfoMessage; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; -- GitLab