/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.fo.ui;
import java.io.File;
import java.io.IOException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.persistence.PersistenceException;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.IdentityShort;
import org.olat.core.commons.modules.bc.FolderConfig;
import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.commons.services.notifications.NotificationsManager;
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.FormLink;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
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.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;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.id.Identity;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.DBRuntimeException;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.CodeHelper;
import org.olat.core.util.FileUtils;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.core.util.WebappHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.vfs.LocalFolderImpl;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.core.util.vfs.VFSItem;
import org.olat.core.util.vfs.VFSLeaf;
import org.olat.core.util.vfs.filters.VFSItemMetaFilter;
import org.olat.modules.fo.Forum;
import org.olat.modules.fo.ForumCallback;
import org.olat.modules.fo.ForumChangedEvent;
import org.olat.modules.fo.ForumLoggingAction;
import org.olat.modules.fo.Message;
import org.olat.modules.fo.Pseudonym;
import org.olat.modules.fo.manager.ForumManager;
import org.olat.modules.fo.ui.events.ErrorEditMessage;
import org.olat.user.DisplayPortraitController;
import org.olat.util.logging.activity.LoggingResourceable;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Description:<br>
* Can be used for creating / editing or replying to a thread/post. editmode is
* set to do internal mode-switch, where needed.
*
* <P>
* Initial Date: 18.06.2009 <br>
*
* @author Roman Haag, roman.haag@frentix.com, frentix GmbH
*/
public class MessageEditController extends FormBasicController {
private static final String CMD_DELETE_ATTACHMENT = "delete.attachment.";
protected static final Integer MAX_BODY_LENGTH = 32000;
// see OLAT-4182/OLAT-4219 and OLAT-4259
// the filtering of .nfs is sort of temporary until we make sure that we no longer reference
// attached files anywhere at the time of deleting it
// likely to be resolved after user logs out, caches get cleared - and if not the server
// restart overnight definitely removes those .nfs files.
private static final String[] enableKeys = new String[]{ "on" };
private RichTextElement bodyEl;
private TextElement titleEl, pseudonymEl, passwordEl;
private MultipleSelectionElement usePseudonymEl;
private FileElement fileUpload;
private DisplayPortraitController portraitCtr;
private DialogBoxController confirmDeleteAttachmentCtrl;
private VFSContainer tempUploadFolder;
private boolean userIsMsgCreator;
private boolean msgHasChildren;
private VFSItemMetaFilter exclFilter;
private final Forum forum;
private final EditMode editMode;
private final boolean guestOnly;
private String proposedPseudonym;
private final ForumCallback foCallback;
private Message message, parentMessage;
@Autowired
private ForumManager fm;
@Autowired
private BaseSecurity securityManager;
@Autowired
private NotificationsManager notificationsManager;
public enum EditMode {
newThread,
edit,
reply
}
/**
*
* @param ureq
* @param control
* @param forumCallback
* @param message may be a new message created by ForumManager.createMessage() which is not yet saved in db
* @param quoteMessage may be null if Editor isn't used to reply to a message
*/
public MessageEditController(UserRequest ureq, WindowControl control, Forum forum, ForumCallback foCallback,
Message message, Message parentMessage, EditMode mode) {
super(ureq, control, FormBasicController.LAYOUT_VERTICAL);
setTranslator(Util.createPackageTranslator(Forum.class, getLocale(), getTranslator()));
this.forum = forum;
this.editMode = mode;
this.message = message;
this.foCallback = foCallback;
this.parentMessage = parentMessage;
this.guestOnly = ureq.getUserSession().getRoles().isGuestOnly();
tempUploadFolder = new LocalFolderImpl(new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()));
exclFilter = new VFSItemMetaFilter();
initForm(ureq);
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer,
* org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest)
*/
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
formLayout.setElementCssClass("o_sel_forum_message_form");
titleEl = uifactory.addTextElement("msgTitle", "msg.title", 100, message.getTitle(), formLayout);
titleEl.setElementCssClass("o_sel_forum_message_title");
titleEl.setMandatory(true);
titleEl.setNotEmptyCheck("error.field.not.empty");
bodyEl = uifactory.addRichTextElementForStringData("msgBody", "msg.body", message.getBody(), 15, -1, true, null, null,
formLayout, ureq.getUserSession(), getWindowControl());
bodyEl.setMandatory(true);
bodyEl.setNotEmptyCheck("error.field.not.empty");
bodyEl.setMaxLength(MAX_BODY_LENGTH);
bodyEl.setNotLongerThanCheck(MAX_BODY_LENGTH, "input.toolong");
setEditPermissions(message);
// list existing attachments. init attachment layout now, to place it in
// right position
createOrUpdateAttachmentListLayout(formLayout);
// provide upload field
if (foCallback.mayEditMessageAsModerator() || ((userIsMsgCreator) && (msgHasChildren == false))) {
fileUpload = uifactory.addFileElement(getWindowControl(), "msg.upload", formLayout);
fileUpload.addActionListener(FormEvent.ONCHANGE);
fileUpload.setMaxUploadSizeKB((int) FolderConfig.getLimitULKB(), "attachments.too.big", new String[] { ((Long) (FolderConfig
.getLimitULKB() / 1024)).toString() });
}
if(foCallback.mayUsePseudonym() || guestOnly) {
String[] enablePseudonymValues = new String[]{ translate("use.pseudonym.label") };
usePseudonymEl = uifactory.addCheckboxesHorizontal("use.pseudonym", formLayout, enableKeys, enablePseudonymValues);
if(StringHelper.containsNonWhitespace(message.getPseudonym())
|| guestOnly || foCallback.pseudonymAsDefault()) {
usePseudonymEl.select(enableKeys[0], true);
}
pseudonymEl = uifactory.addTextElement("pseudonym", "pseudonym", 128, message.getPseudonym(), formLayout);
pseudonymEl.setElementCssClass("o_sel_forum_message_alias");
passwordEl = uifactory.addPasswordElement("password", "password", 128, "", formLayout);
passwordEl.setElementCssClass("o_sel_forum_message_alias_pass");
passwordEl.setPlaceholderKey("password.placeholder", null);
if(guestOnly) {
usePseudonymEl.setVisible(false);
pseudonymEl.setLabel("use.pseudonym", null);
pseudonymEl.setMandatory(true);
proposedPseudonym = (String)ureq.getUserSession().getEntry("FOPseudo" + forum.getKey());
if(StringHelper.containsNonWhitespace(proposedPseudonym)) {
pseudonymEl.setValue(proposedPseudonym);
String proposedPassword = (String)ureq.getUserSession().getEntry("FOPseudo-" + proposedPseudonym);
if(StringHelper.containsNonWhitespace(proposedPassword)) {
passwordEl.setValue(proposedPassword);
}
}
} else if(userIsMsgCreator) {
pseudonymEl.setLabel(null, null);
usePseudonymEl.addActionListener(FormEvent.ONCHANGE);
proposedPseudonym = fm.getPseudonym(forum, getIdentity());
if(StringHelper.containsNonWhitespace(proposedPseudonym)) {
pseudonymEl.setValue(proposedPseudonym);
usePseudonymEl.select(enableKeys[0], true);
String proposedPassword = (String)ureq.getUserSession().getEntry("FOPseudo-" + proposedPseudonym);
if(StringHelper.containsNonWhitespace(proposedPassword)) {
passwordEl.setValue(proposedPassword);
}
}
usePseudonymEl.setMandatory(usePseudonymEl.isAtLeastSelected(1));
pseudonymEl.setVisible(usePseudonymEl.isAtLeastSelected(1));
passwordEl.setVisible(usePseudonymEl.isAtLeastSelected(1));
} else {
usePseudonymEl.setVisible(false);
pseudonymEl.setLabel("use.pseudonym", null);
pseudonymEl.setEnabled(false);
passwordEl.setVisible(false);
}
}
// save and cancel buttons
FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
formLayout.add(buttonLayout);
uifactory.addFormSubmitButton("msg.save", buttonLayout);
uifactory.addFormCancelButton("msg.cancel", buttonLayout, ureq, getWindowControl());
// show message replying to, if in reply modus
if (editMode == EditMode.reply) {
String previewPage = Util.getPackageVelocityRoot(this.getClass()) + "/msg-preview.html";
FormLayoutContainer replyMsgLayout = FormLayoutContainer.createCustomFormLayout("replyMsg", getTranslator(), previewPage);
uifactory.addSpacerElement("spacer1", formLayout, false);
formLayout.add(replyMsgLayout);
replyMsgLayout.setLabel("label.replytomsg", new String[] { StringHelper.escapeHtml(parentMessage.getTitle()) });
replyMsgLayout.contextPut("messageBody", parentMessage.getBody());
replyMsgLayout.contextPut("message", parentMessage);
replyMsgLayout.contextPut("guestOnly", new Boolean(guestOnly));
Identity creator = parentMessage.getCreator();
if(creator != null) {
replyMsgLayout.contextPut("identity", creator);
portraitCtr = new DisplayPortraitController(ureq, getWindowControl(), creator, true, true);
replyMsgLayout.put("portrait", portraitCtr.getInitialComponent());
}
}
}
private void setEditPermissions(Message msg){
// defaults for a new message
userIsMsgCreator = true;
msgHasChildren = false;
// set according to message
if (msg.getKey() != null) {
if(msg.getCreator() != null) {
} else {
userIsMsgCreator = getIdentity().equals(msg.getCreator());
msgHasChildren = fm.hasChildren(msg);
}
}
}
// adds or updates the list of already existing attachments with a delete
// button for each
private void createOrUpdateAttachmentListLayout(FormItemContainer formLayout) {
FormItem attachLayout = formLayout.getFormComponent("attachLayout");
List<VFSItem> attachments = new ArrayList<VFSItem>();
// add already existing attachments:
if (message.getKey() != null) {
VFSContainer msgContainer = fm.getMessageContainer(message.getForum().getKey(), message.getKey());
attachments.addAll(msgContainer.getItems(exclFilter));
}
// add files from TempFolder
attachments.addAll(getTempFolderFileList());
Collections.sort(attachments, new Comparator<VFSItem>(){
final Collator c = Collator.getInstance(getLocale());
public int compare(final VFSItem o1, final VFSItem o2) {
return c.compare((o1).getName(), (o2).getName());
}});
FormLayoutContainer tmpLayout;
if (attachLayout == null) {
String editPage = Util.getPackageVelocityRoot(this.getClass()) + "/attachments-editview.html";
tmpLayout = FormLayoutContainer.createCustomFormLayout("attachLayout", getTranslator(), editPage);
formLayout.add(tmpLayout);
} else {
tmpLayout = (FormLayoutContainer) attachLayout;
}
tmpLayout.contextPut("attachments", attachments);
// add delete links for each attachment if user is allowed to see them
int attNr = 1;
for (VFSItem tmpFile : attachments) {
FormLink tmpLink = uifactory.addFormLink(CMD_DELETE_ATTACHMENT + attNr, tmpLayout, Link.BUTTON_XSMALL);
if (!(foCallback.mayEditMessageAsModerator() || ((userIsMsgCreator) && (msgHasChildren == false)))) {
tmpLink.setEnabled(false);
tmpLink.setVisible(false);
}
tmpLink.setUserObject(tmpFile);
tmpLink.setI18nKey("attachments.remove.string");
attNr++;
}
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose()
*/
@Override
protected void doDispose() {
removeTempUploadedFiles();
if (portraitCtr != null) {
portraitCtr.dispose();
portraitCtr = null;
}
if (confirmDeleteAttachmentCtrl != null) {
confirmDeleteAttachmentCtrl.dispose();
confirmDeleteAttachmentCtrl = null;
}
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true;
if(usePseudonymEl != null) {
pseudonymEl.clearError();
passwordEl.clearError();
if(guestOnly || usePseudonymEl.isAtLeastSelected(1)) {
String pseudonym = pseudonymEl.getValue();
String password = passwordEl.getValue();
if(!StringHelper.containsNonWhitespace(pseudonym)) {
pseudonymEl.setErrorKey("form.legende.mandatory", null);
allOk &= false;
} else if(!validatePseudonym(pseudonym)) {
pseudonymEl.setErrorKey("error.pseudonym", null);
allOk &= false;
} else if(!validatePseudonymProtected(pseudonym, password)) {
allOk &= false;
}
}
}
return allOk & super.validateFormLogic(ureq);
}
private boolean validatePseudonym(String value) {
boolean allOk = true;
if(proposedPseudonym == null || !proposedPseudonym.equalsIgnoreCase(value)) {
List<IdentityShort> sameValues = securityManager.searchIdentityShort(value, 250);
if(sameValues.size() == 1) {
allOk &= !sameValues.get(0).getKey().equals(getIdentity().getKey());
} else if(sameValues.size() > 1) {
allOk &= false;
}
}
return allOk;
}
/**
* No password:
* <ul>
* <li>exists pseudonym with password: error</li>
* <li>doesn't exist pseudonym with passwort -> can use the pseudonym</li>
* </ul>
* With password:
* <ul>
* <li>exists pseudonym with password + password wrong: error</li>
* <li>exists pseudonym with password + password ok: ok</li>
* <li>exists pseudonym with password + password wrong: error</li>
* </ul>
*
* @param value
* @param password
* @return
*/
private boolean validatePseudonymProtected(String value, String password) {
boolean allOk = true;
if(StringHelper.containsNonWhitespace(password)) {
List<Pseudonym> pseudonyms = fm.getPseudonyms(value);
if(pseudonyms.size() > 0) {
boolean authenticated = false;
for(Pseudonym pseudonym:pseudonyms) {
if(fm.authenticatePseudonym(pseudonym, password)) {
authenticated = true;
break;
}
}
if(!authenticated) {
passwordEl.setErrorKey("error.pseudonym.authentication", null);
allOk &= false;
}
} else if(fm.isPseudonymInUseInForums(value)) {
pseudonymEl.setErrorKey("error.pseudonym", null);
allOk &= false;
}
} else if(fm.isPseudonymProtected(value)) {
pseudonymEl.setErrorKey("error.pseudonym.protected", null);
allOk &= false;
}
return allOk;
}
/**
* @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest)
*/
@Override
protected void formOK(UserRequest ureq) {
try {
commitMessage(ureq);
fireEvent(ureq, Event.DONE_EVENT);
} catch(DBRuntimeException | PersistenceException e) {
DBFactory.getInstance().rollback();
logError("", e);
fireEvent(ureq, new ErrorEditMessage());
}
}
private void commitMessage(UserRequest ureq) {
// if msg exist -> persist uploads directly to final dest
if (message.getKey() != null) {
message = fm.loadMessage(message.getKey());
}
// set values from form to message
message.setTitle(titleEl.getValue());
String body = bodyEl.getValue();
body = body.replace("<p> ", "<p>");
message.setBody(body.trim());
if(usePseudonymEl != null && (usePseudonymEl.isAtLeastSelected(1) || guestOnly)) {
String password = passwordEl.getValue();
String pseudonym = pseudonymEl.getValue();
if(StringHelper.containsNonWhitespace(password)) {
List<Pseudonym> protectedPseudonyms = fm.getPseudonyms(pseudonym);
if(protectedPseudonyms.isEmpty()) {
fm.createProtectedPseudonym(pseudonym, password);
ureq.getUserSession().putEntry("FOPseudo-" + pseudonym, password);
} else {
//we double check the password
boolean authenticated = false;
for(Pseudonym protectedPseudonym:protectedPseudonyms) {
if(fm.authenticatePseudonym(protectedPseudonym, password)) {
ureq.getUserSession().putEntry("FOPseudo-" + protectedPseudonym.getPseudonym(), password);
authenticated = true;
break;
}
}
if(!authenticated) {
validateFormLogic(ureq);
return;
}
}
}
message.setPseudonym(pseudonym);
if(guestOnly) {
ureq.getUserSession().putEntry("FOPseudo" + forum.getKey(), message.getPseudonym());
}
} else if(message.getCreator() != null && message.getCreator().equals(getIdentity())) {
message.setPseudonym(null);
}
if(editMode == EditMode.newThread) {
if(foCallback.mayOpenNewThread()) {
// save a new thread
fm.addTopMessage(message);
fm.markNewMessageAsRead(getIdentity(), forum, message);
persistTempUploadedFiles(message);
// if notification is enabled -> notify the publisher about news
notifiySubscription();
addLoggingResourceable(LoggingResourceable.wrap(message));
//commit before sending events
DBFactory.getInstance().commit();
ForumChangedEvent event = new ForumChangedEvent(ForumChangedEvent.NEW_MESSAGE, message.getKey(), message.getKey(), getIdentity());
CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(event, forum);
ThreadLocalUserActivityLogger.log(ForumLoggingAction.FORUM_MESSAGE_CREATE, getClass());
} else {
showWarning("may.not.save.msg.as.author");
}
} else if(editMode == EditMode.edit) {
boolean children = fm.countMessageChildren(message.getKey()) > 0;
if (foCallback.mayEditMessageAsModerator() || (userIsMsgCreator && !children)) {
message.setModifier(getIdentity());
message = fm.updateMessage(message, true);
persistTempUploadedFiles(message);
notifiySubscription();
//commit before sending events
DBFactory.getInstance().commit();
Long threadTopKey = message.getThreadtop() == null ? null : message.getThreadtop().getKey();
ForumChangedEvent event = new ForumChangedEvent(ForumChangedEvent.CHANGED_MESSAGE, threadTopKey, message.getKey(), getIdentity());
CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(event, forum);
ThreadLocalUserActivityLogger.log(ForumLoggingAction.FORUM_MESSAGE_EDIT, getClass(),
LoggingResourceable.wrap(message));
} else {
showWarning("may.not.save.msg.as.author");
}
} else if(editMode == EditMode.reply) {
fm.replyToMessage(message, parentMessage);
fm.markNewMessageAsRead(getIdentity(), forum, message);
persistTempUploadedFiles(message);
notifiySubscription();
Long threadTopKey = message.getThreadtop() == null ? null : message.getThreadtop().getKey();
//commit before sending events
DBFactory.getInstance().commit();
ForumChangedEvent event = new ForumChangedEvent(ForumChangedEvent.NEW_MESSAGE, threadTopKey, message.getKey(), getIdentity());
CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(event, forum);
ThreadLocalUserActivityLogger.log(ForumLoggingAction.FORUM_REPLY_MESSAGE_CREATE, getClass(),
LoggingResourceable.wrap(message));
}
}
private void notifiySubscription() {
if (foCallback.getSubscriptionContext() != null) {
notificationsManager.markPublisherNews(foCallback.getSubscriptionContext(), getIdentity(), true);
}
}
@Override
protected void formCancelled(UserRequest ureq) {
// remove uploaded files if editing is canceled
removeTempUploadedFiles();
fireEvent(ureq, Event.CANCELLED_EVENT);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(usePseudonymEl == source) {
usePseudonymEl.setMandatory(usePseudonymEl.isAtLeastSelected(1));
pseudonymEl.setVisible(usePseudonymEl.isAtLeastSelected(1));
passwordEl.setVisible(usePseudonymEl.isAtLeastSelected(1));
} else if (source == fileUpload) {
if (fileUpload.isUploadSuccess()) {
String fileName = fileUpload.getUploadFileName();
if (fileUpload.getUploadSize() / 1024 < fileUpload.getMaxUploadSizeKB()) {
// checking tmp-folder and msg-container for filename
boolean fileExists = false;
if (getTempFolderFileList().contains(fileName)) {
fileExists = true;
}
if (message.getKey() != null) {
VFSContainer msgContainer = fm.getMessageContainer(message.getForum().getKey(), message.getKey());
if (msgContainer.resolve(fileName) != null) {
fileExists = true;
}
}
if (fileExists) {
fileUpload.setErrorKey("attachments.error.file.exists", null);
fileUpload.getUploadFile().delete();
fileUpload.showError(true);
} else {
// files got stored in an extra tempFolder, to use the same
// fileUploader multiple times
fileUpload.moveUploadFileTo(tempUploadFolder);
fileUpload.showError(false);
fileUpload.reset();
createOrUpdateAttachmentListLayout(this.flc);
showInfo("attachments.upload.successful", fileName);
}
} else {
fileUpload.setErrorKey("attachments.too.big", new String[] { Long.toString((fileUpload.getMaxUploadSizeKB() / 1024)) });
fileUpload.getUploadFile().delete();
fileUpload.showError(true);
}
}
} else if (source instanceof FormLink) {
FormLink activeLink = (FormLink) source;
// attachment delete button may have been pressed
Object userObj = activeLink.getUserObject();
if (userObj != null) {
setEditPermissions(message);
if (userObj instanceof VFSLeaf) {
VFSLeaf file = (VFSLeaf) userObj;
if (foCallback.mayEditMessageAsModerator() || (userIsMsgCreator && !msgHasChildren)) {
confirmDeleteAttachmentCtrl = activateYesNoDialog(ureq, null, translate("reallydeleteAtt"), confirmDeleteAttachmentCtrl);
confirmDeleteAttachmentCtrl.setUserObject(file);
} else {
if ((userIsMsgCreator) && (msgHasChildren == true)) {
// user is author of the current message but it has already at
// least one child
showWarning("may.not.delete.att.as.author");
} else {
// user isn't author of the current message
showInfo("may.not.delete.att");
}
}
}
}
}
}
private List<VFSItem> getTempFolderFileList() {
if (tempUploadFolder == null) {
tempUploadFolder = new OlatRootFolderImpl(File.separator + "tmp/" + CodeHelper.getGlobalForeverUniqueID() + "/", null);
}
return tempUploadFolder.getItems(exclFilter);
}
/**
* @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
* org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event)
*/
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
super.event(ureq, source, event);
if (source == confirmDeleteAttachmentCtrl) {
if (DialogBoxUIFactory.isYesEvent(event)) { // ok to really delete this // attachment
Object userObj = confirmDeleteAttachmentCtrl.getUserObject();
if (userObj instanceof VFSLeaf) {
((VFSLeaf)userObj).delete();
showInfo("delete.att.ok");
createOrUpdateAttachmentListLayout(flc);
}
}
}
}
/**
* Used to get the message edited right before. the new values got saved to it
* locally by formOK()
*
* @return the edited message
*/
public Message getMessage() {
if (!StringHelper.containsNonWhitespace(message.getTitle()) && message == null) {
throw new AssertException("Getting back the edited message failed! You first have to edit one and intialize properly!");
} else {
return message;
}
}
/**
* gives back the mode in which the editor was (create/edit/reply)
*
* @return editMode which can be matched against static Strings from this
* class
*/
public EditMode getLastEditModus() {
return editMode;
}
/**
* - used locally if in edit mode where the msg-key is known
* - called from ForumController after creating a thread or a reply to copy temp files to
* msg-folder
*
* @param tmpMessage
*/
public void persistTempUploadedFiles(Message tmpMessage) {
if (tmpMessage == null) throw new AssertException("Message may not be null to persist temp files");
VFSContainer msgContainer = fm.getMessageContainer(forum.getKey(), message.getKey());
if (msgContainer != null) {
List<VFSItem> tmpFList = getTempFolderFileList();
for (VFSItem file : tmpFList) {
VFSLeaf leaf = (VFSLeaf) file;
try {
FileUtils.bcopy(
leaf.getInputStream(),
msgContainer.createChildLeaf(leaf.getName()).getOutputStream(false),
"forumSaveUploadedFile"
);
} catch (IOException e) {
removeTempUploadedFiles();
throw new RuntimeException ("I/O error saving uploaded file:" + msgContainer + "/" + leaf.getName());
}
}
}
removeTempUploadedFiles();
}
private void removeTempUploadedFiles() {
if (tempUploadFolder != null) {
tempUploadFolder.delete();
tempUploadFolder = null;
}
}
}