/**
* OLAT - Online Learning and Training
* http://www.olat.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),
* University of Zurich, Switzerland.
*
*/
package org.olat.modules.co;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
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.SelectionElement;
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.util.CSSHelper;
import org.olat.core.id.Identity;
import org.olat.core.id.UserConstants;
import org.olat.core.util.FileUtils;
import org.olat.core.util.Util;
import org.olat.core.util.mail.ContactList;
import org.olat.core.util.mail.MailHelper;
/**
* highly configurable contact form. Depending on each field value the
* corresponding fields become editable or not.
*
* By creation time the defaults are: a FROM: field containing the logged in
* users e-mail, an empty TO: field not editable, empty SUBJECT: and BODY:
* fields both editable, and last but not least a submit cancel buttons pair.
*
*
* Send-Limitations:
* - maxLength for 'body' TextAreaElement -> 10000 characters, about 4 pages
*
>
* - maxLength for 'to' TextAreaElement -> 30000 characters, enough space for
* a lot of mail group names, each mail group containing umlimited ammount of
* e-mail addresses
*
*
* Initial Date: Jul 19, 2004
* @author patrick
*/
class ContactForm extends FormBasicController {
//
private final static String NLS_CONTACT_TO = "contact.to";
private TextElement tto = null;
private TextElement ttoBig = null;
private final static String NLS_CONTACT_FROM = "contact.from";
private TextElement tfrom;
private final static String NLS_CONTACT_SUBJECT = "contact.subject";
private TextElement tsubject;
private final static String NLS_CONTACT_BODY = "contact.body";
private TextElement tbody;
private final static String NLS_CONTACT_ATTACHMENT = "contact.attachment";
private final static String NLS_CONTACT_ATTACHMENT_EXPL = "contact.attachment.maxsize";
private int contactAttachmentMaxSizeInMb = 5;
private FileElement attachmentEl;
private List attachmentLinks = new ArrayList();
private FormLayoutContainer uploadCont;
private boolean recipientsAreEditable = false;
private final static int emailCols = 60;
private boolean readOnly=false;
private boolean hasMsgCancel=false;
private final static String NLS_CONTACT_SEND_CP_FROM = "contact.cp.from";
private SelectionElement tcpfrom;
private Identity emailFrom;
private File attachementTempDir;
private long attachmentSize = 0l;
private Map attachmentCss = new HashMap();
private Map attachmentNames = new HashMap();
private Map contactLists = new Hashtable();
public ContactForm(UserRequest ureq, WindowControl wControl, Identity emailFrom, boolean readOnly, boolean isCancellable, boolean hasRecipientsEditable) {
super(ureq, wControl);
this.emailFrom = emailFrom;
this.readOnly = readOnly;
this.recipientsAreEditable = hasRecipientsEditable;
this.hasMsgCancel = isCancellable;
this.contactAttachmentMaxSizeInMb = MailHelper.getMaxSizeForAttachement();
initForm(ureq);
}
/**
* @param defaultSubject
*/
protected void setSubject(final String defaultSubject) {
tsubject.setValue(defaultSubject);
tsubject.setEnabled(!readOnly);
tsubject.setMandatory(tsubject.isEnabled());
}
/**
* add a ContactList as EmailTo:
*
* @param emailList
*/
protected void addEmailTo(ContactList emailList) {
if (contactLists.containsKey(emailList.getName())) {
//there is already a ContactList with this name...
ContactList existing = contactLists.get(emailList.getName());
//, merge their values.
existing.add(emailList);
//the form itself must not be updated, because it already displays
// the name.
} else {
//a new ContactList, put it into contactLists
contactLists.put(emailList.getName(), emailList);
//and add its name in the form
addContactFormEmailTo("<" + emailList.getName() + ">");
}
}
/**
* @param defaultEmailTo
*/
private void addContactFormEmailTo(String defaultEmailTo) {
defaultEmailTo += tto.getValue();
tto.setValue(defaultEmailTo);
ttoBig.setValue(defaultEmailTo);
tto.setVisible(!recipientsAreEditable);
ttoBig.setVisible(recipientsAreEditable);
}
/**
* @param defaultBody
*/
protected void setBody(String defaultBody) {
tbody.setValue(defaultBody);
tbody.setEnabled(!readOnly);
tbody.setVisible(true);
tbody.setMandatory(!readOnly);
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
if(readOnly){
return true;
}
boolean subjectOk = !tsubject.isEmpty("error.field.not.empty");
boolean bodyOk = !tbody.isEmpty("error.field.not.empty");
// the body message may not be longer than about 4 pages or 10000
// characters
//bodyOk = bodyOk && tbody.notLongerThan(10000, "input.toolong");
boolean toOk = false;
if (tto != null) {
toOk = !tto.isEmpty("error.field.not.empty");
} else {
toOk = !ttoBig.isEmpty("error.field.not.empty");
// limit of recipients about 700 (1 emailaddress medial 40
// characters)
//toOk = toOk && ttoBig.notLongerThan(30000, "input.toolong");
}
boolean fromOk = !tfrom.isEmpty("error.field.not.empty");
return subjectOk && bodyOk && toOk && fromOk;
}
/**
* @return
*/
protected String getEmailFrom() {
String ccMail = emailFrom.getUser().getProperty(UserConstants.EMAIL, null);
return ccMail;
}
/**
* a List with ContactLists as elements is returned
*
* @return
*/
protected List getEmailToContactLists() {
List retVal = new ArrayList();
retVal.addAll(contactLists.values());
return retVal;
}
/**
* retrieve the contact list names from the to field, and map them back to the
* stored contact lists names.
*
* @return
*/
protected String getEmailTo() {
String retVal = "";
String value;
if (tto != null) value = tto.getValue();
else value = ttoBig.getValue();
String sep = "";
int i = 0;
int j = -1;
i = value.indexOf("<", j + 1);
j = value.indexOf(">", j + 2);
while (i > -1 && j > 0) {
String contactListName = value.substring(i + 1, j);
i = value.indexOf("<", j + 1);
j = value.indexOf(">", j + 2);
if (contactLists.containsKey(contactListName)) {
ContactList found = contactLists.get(contactListName);
retVal += sep + found.toString();
sep = ", ";
}
}
return retVal;
}
/**
* @return
*/
protected String getSubject() {
return tsubject.getValue();
}
/**
* @return email body text
*/
protected String getBody() {
return tbody.getValue();
}
protected List getAttachments() {
List attachments = new ArrayList();
for(FormLink removeLink : attachmentLinks) {
attachments.add((File)removeLink.getUserObject());
}
return attachments;
}
protected void cleanUpAttachments() {
if(attachementTempDir != null && attachementTempDir.exists()) {
FileUtils.deleteDirsAndFiles(attachementTempDir, true, true);
attachementTempDir = null;
}
}
protected boolean isTcpFrom() {
return tcpfrom.isSelected(0);
}
protected void setDisplayOnly (boolean readOnly) {
this.readOnly = readOnly;
if (readOnly) {
flc.setEnabled(false);
}
}
@Override
protected void formOK(UserRequest ureq) {
fireEvent (ureq, Event.DONE_EVENT);
}
@Override
protected void formCancelled(UserRequest ureq) {
fireEvent (ureq, Event.CANCELLED_EVENT);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(source == attachmentEl) {
String filename = attachmentEl.getUploadFileName();
if(attachementTempDir == null) {
attachementTempDir = FileUtils.createTempDir("attachements", null, null);
}
long size = attachmentEl.getUploadSize();
if(size + attachmentSize > (contactAttachmentMaxSizeInMb * 1024 * 1024)) {
showWarning(NLS_CONTACT_ATTACHMENT_EXPL, Integer.toString(contactAttachmentMaxSizeInMb));
attachmentEl.reset();
} else {
File attachment = attachmentEl.moveUploadFileTo(attachementTempDir);
attachmentEl.reset();
attachmentSize += size;
FormLink removeFile = uifactory.addFormLink(attachment.getName(), "delete", null, uploadCont, Link.BUTTON_SMALL);
removeFile.setUserObject(attachment);
attachmentLinks.add(removeFile);
//pretty labels
uploadCont.setLabel(NLS_CONTACT_ATTACHMENT, null);
attachmentNames.put(attachment.getName(), filename);
attachmentCss.put(attachment.getName(), CSSHelper.createFiletypeIconCssClassFor(filename));
uploadCont.contextPut("attachments", attachmentLinks);
uploadCont.contextPut("attachmentNames", attachmentNames);
uploadCont.contextPut("attachmentCss", attachmentCss);
attachmentEl.setLabel(null, null);
}
} else if (attachmentLinks.contains(source)) {
File uploadedFile = (File)source.getUserObject();
if(uploadedFile != null && uploadedFile.exists()) {
attachmentSize -= uploadedFile.length();
uploadedFile.delete();
}
attachmentLinks.remove(source);
uploadCont.remove(source);
if(attachmentLinks.isEmpty()) {
uploadCont.setLabel(null, null);
attachmentEl.setLabel(NLS_CONTACT_ATTACHMENT, null);
}
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("header.newcntctmsg");
tfrom = uifactory.addTextElement("ttfrom", NLS_CONTACT_FROM, 255, "", formLayout);
tfrom.setValue(emailFrom.getName());
tfrom.setEnabled(false);
tto = uifactory.addTextElement("tto", NLS_CONTACT_TO, 255, "", formLayout);
tto.setEnabled(false);
tto.setVisible(false);
ttoBig = uifactory.addTextAreaElement("ttoBig", NLS_CONTACT_TO, -1, 2, emailCols, true, "", formLayout);
ttoBig.setEnabled(false);
ttoBig.setVisible(false);
tsubject = uifactory.addTextElement("tsubject", NLS_CONTACT_SUBJECT, 255, "", formLayout);
tsubject.setDisplaySize(emailCols);
tbody = uifactory.addTextAreaElement("tbody", NLS_CONTACT_BODY, -1, 10, emailCols, true, "", formLayout);
tbody.setEnabled(!readOnly);
String VELOCITY_ROOT = Util.getPackageVelocityRoot(this.getClass());
uploadCont = FormLayoutContainer.createCustomFormLayout("file_upload_inner", getTranslator(), VELOCITY_ROOT + "/attachments.html");
uploadCont.setRootForm(mainForm);
formLayout.add(uploadCont);
attachmentEl = uifactory.addFileElement("file_upload_1", NLS_CONTACT_ATTACHMENT, formLayout);
attachmentEl.setLabel(NLS_CONTACT_ATTACHMENT, null);
attachmentEl.addActionListener(this, FormEvent.ONCHANGE);
attachmentEl.setExampleKey(NLS_CONTACT_ATTACHMENT_EXPL, new String[]{Integer.toString(contactAttachmentMaxSizeInMb)});
tcpfrom = uifactory.addCheckboxesVertical("tcpfrom", "", formLayout, new String[]{"xx"}, new String[]{translate(NLS_CONTACT_SEND_CP_FROM)}, null, 1);
FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttonGroupLayout", getTranslator());
formLayout.add(buttonGroupLayout);
uifactory.addFormSubmitButton("msg.save", buttonGroupLayout);
if (hasMsgCancel) {
uifactory.addFormCancelButton("msg.cancel", buttonGroupLayout, ureq, getWindowControl());
}
}
@Override
protected void doDispose() {
cleanUpAttachments();
}
}