package be.redtree.bean;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Serializable;
import java.io.StringReader;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import javax.activation.MimetypesFileTypeMap;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.mail.internet.InternetAddress;
import javax.portlet.PortletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import be.redtree.initialize.DefaultValuesBuilder;
import be.redtree.model.Document;
import be.redtree.model.Field;
import be.redtree.model.FieldResult;
import be.redtree.model.Form;
import be.redtree.model.FormResult;
import be.redtree.sql.FormController;
import be.redtree.xstream.CustomProperties;
import be.redtree.xstream.DynamicContent;
import be.redtree.xstream.DynamicElement;
import com.liferay.faces.portal.context.LiferayFacesContext;
import com.liferay.mail.model.FileAttachment;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.mail.SMTPAccount;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.User;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;
import com.liferay.portlet.documentlibrary.model.DLFolder;
import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
import com.liferay.portlet.dynamicdatamapping.storage.Fields;
import com.liferay.portlet.journal.model.JournalArticle;
import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
import com.liferay.util.mail.MailEngine;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
@ManagedBean
@ViewScoped
public class WebFormBean implements Serializable {
private static String MESSAGE_SAVED_SUCCESS = "be.redtree.form.message.save";
private static Log sLog = LogFactory.getLog(WebFormBean.class);
private static String PREFERENCE_FORM_ID = "form.id";
private static String FOLDER_CONTENT = "Webform Documents";
private static String MESSAGE_NO_MULTIPLE_POSTS = "be.redtree.form.error.multiple.posts";
private static String MESSAGE_AUTHENTICATION_REQUIRED = "be.redtree.form.error.authenticate";
private static String MESSAGE_SENT = "be.redtree.form.sent";
private FormController formController = new FormController();
private Form form;
private List<Form> forms;
private List<Field> fields;
private Long selectedForm;
public WebFormBean() {
}
public Boolean getShowForm() throws PortalException, SystemException {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
User user = themeDisplay.getUser();
Long userId = new Long(0);
if (!user.isDefaultUser()) {
userId = user.getUserId();
}
if (getForm() != null) {
if (!this.form.getAllowGuest() && !userId.equals(new Long(0))) {
List<FormResult> formResults = formController.getUserResults(this.form.getId(), userId);
if ((formResults.size() < 1) || (formResults.size() > 0 && this.form.getAllowMultiple())) {
return true;
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("growl", new FacesMessage(LanguageUtil.get(themeDisplay.getLocale(), MESSAGE_NO_MULTIPLE_POSTS), ""));
}
} else if (!this.form.getAllowGuest() && userId.equals(new Long(0))) {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("growl", new FacesMessage(LanguageUtil.get(themeDisplay.getLocale(), MESSAGE_AUTHENTICATION_REQUIRED), ""));
} else if (this.form.getAllowGuest()) {
return true;
}
}
return false;
}
public void submitForm() {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
Long userId = new Long(0);
if (this.form.getAnonymous() && !this.form.getUserinfo()) {
userId = themeDisplay.getUserId();
} else if (this.form.getUserinfo()) {
userId = themeDisplay.getUserId();
}
Long formId = this.form.getId();
Date created = new Date();
List<FieldResult> resultFields = new ArrayList<FieldResult>();
FormResult formResult = new FormResult(userId, formId, created, resultFields);
for (Field field : this.fields) {
Long fieldId = field.getId();
String type = field.getName();
FormResult result = formResult;
Boolean enabled = false;
String content = "";
if (field.getName() != null && !field.getName().trim().isEmpty()) {
if (field.getName().equals("radio") || field.getName().equals("drop")) {
content = field.getTempValue();
resultFields.add(new FieldResult(fieldId, type, enabled, content, result));
} else if (field.getName().equals("checkbox")) {
enabled = field.getValue().getEnabled();
content = "" + field.getValue().getEnabled();
resultFields.add(new FieldResult(fieldId, type, enabled, content, result));
} else if (field.getName().equals("textfield") || field.getName().equals("textarea")) {
content = field.getValue().getLocaleContent();
resultFields.add(new FieldResult(fieldId, type, enabled, content, result));
} else if (field.getName().equals("upload")) {
content = field.getTempValue();
resultFields.add(new FieldResult(fieldId, type, enabled, content, result));
// we need to build a list of links to docs inside the temp
// value for the mail
if (field.getTempValue() != null) {
String[] files = field.getTempValue().split("\\,");
StringBuilder builder = new StringBuilder();
for (String fileEntryId : files) {
try {
DLFileEntry dlFileEntry = DLFileEntryLocalServiceUtil.getFileEntry(new Long(fileEntryId));
String url = "/documents/" + dlFileEntry.getGroupId() + "/" + dlFileEntry.getFolderId() + "/" + URLEncoder.encode(dlFileEntry.getName(), "UTF-8") + "/" + dlFileEntry.getUuid() + "?version=" + dlFileEntry.getVersion();
String name = dlFileEntry.getTitle();
builder.append(name + "|" + url + ",");
} catch (Exception e) {
e.printStackTrace();
}
}
builder.substring(0, builder.toString().length() - 1);
field.setTempValue(builder.toString());
}
}
}
}
formResult.setFields(new HashSet<FieldResult>(resultFields));
formController.addFormResult(formResult);
if (this.form.getSendMail() && this.form.getEmail() != null && !this.form.getEmail().isEmpty()) {
sendMail(themeDisplay.getCompany(), this.form.getEmail(), DefaultValuesBuilder.MAIL_ADMIN_TITLE);
}
if (this.form.getUserCopy()) {
String email = themeDisplay.getUser().getEmailAddress();
if (email == null || email.isEmpty()) {
sLog.error("cannot send mail Form confirmation for user email : " + email);
} else {
sendMail(themeDisplay.getCompany(), email, DefaultValuesBuilder.MAIL_USER_TITLE);
}
}
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("growl", new FacesMessage(LanguageUtil.get(themeDisplay.getLocale(), MESSAGE_SENT), ""));
clearForm();
}
public void sendMail(Company company, String email, String template) {
try {
DateTime dateTime = new DateTime();
String date = dateTime.getDayOfMonth() + "/" + dateTime.getMonthOfYear() + "/" + dateTime.getYear() + " " + dateTime.getHourOfDay() + ":" + dateTime.getMinuteOfHour() + ":" + dateTime.getSecondOfMinute();
String sender = this.form.getEmail();
if (sender == null || sender.isEmpty()) {
sender = "forms@liferay.com";
}
JournalArticle journalArticle = getMailTemplate(company, template);
XStream xstream = new XStream(new StaxDriver());
xstream.autodetectAnnotations(true);
xstream.alias("dynamic-content", DynamicContent.class);
xstream.alias("dynamic-element", DynamicElement.class);
xstream.alias("root", CustomProperties.class);
String content = "";
CustomProperties customProperties = (CustomProperties) xstream.fromXML(journalArticle.getContent());
for (DynamicElement dynamicElement : customProperties.getDynamicElements()) {
if (dynamicElement.getName().equals("HTMLContent")) {
content = dynamicElement.getDynamicContent().getValue();
}
}
String body = getFreemarker(content);
List<InternetAddress> addresses = new ArrayList<InternetAddress>();
addresses.add(new InternetAddress(email, false));
InternetAddress from = new InternetAddress(sender, false);
InternetAddress[] to = addresses.toArray(new InternetAddress[addresses.size()]);
InternetAddress[] cc = new InternetAddress[0];
InternetAddress[] bcc = new InternetAddress[0];
InternetAddress[] bulkAddresses = new InternetAddress[0];
String subject = "Form response : " + form.getLocaleName() + " @ " + date;
boolean htmlFormat = true;
InternetAddress[] replyTo = new InternetAddress[0];
String messageId = null;
String inReplyTo = null;
List<FileAttachment> fileAttachments = new ArrayList<FileAttachment>();
SMTPAccount smtpAccount = null;
MailEngine.send(from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat, replyTo, messageId, inReplyTo, fileAttachments, smtpAccount);
sLog.info("sending mail form : " + sender + " to : " + email);
} catch (Exception e) {
sLog.error("failed to send mail", e);
}
}
private String getFreemarker(String content) throws IOException, TemplateException, PortalException, SystemException {
Template template = new Template("name", new StringReader(content), new Configuration());
Map<String, Object> data = new HashMap<String, Object>();
data.put("form", this.form);
data.put("fields", this.fields);
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
Writer out = new OutputStreamWriter(arrayOutputStream);
template.process(data, out);
return new String(arrayOutputStream.toByteArray(), "UTF-8");
}
public JournalArticle getMailTemplate(Company company, String title) throws PortalException, SystemException, IOException {
try {
return JournalArticleLocalServiceUtil.getArticleByUrlTitle(company.getGroup().getGroupId(), title);
} catch (Exception e) {
sLog.error("Main template " + title + " does not exist");
}
return null;
}
public void clearForm() {
try {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
Long id = new Long(getPreference(portletRequest, PREFERENCE_FORM_ID, "0"));
if (!id.equals(new Long(0))) {
this.form = formController.getForm(id);
}
} catch (Exception e) {
e.printStackTrace();
}
if (this.form != null) {
this.fields = new ArrayList<Field>(form.getFields());
Collections.sort(this.fields, Form.fieldWeightComparator);
}
}
public void removeUpload(Long fieldId, String fileEntryId) {
Field field = getField(fieldId);
List<String> values = new ArrayList<String>();
if (field.getTempValue() != null) {
String[] documents = field.getTempValue().split("\\,");
values = new ArrayList<String>(Arrays.asList(documents));
}
List<String> newValues = new ArrayList<String>();
for (String value : values) {
if (value.equals(fileEntryId)) {
try {
DLFileEntryLocalServiceUtil.deleteDLFileEntry(new Long(fileEntryId));
} catch (Exception e) {
e.printStackTrace();
}
} else {
newValues.add(value);
}
}
StringBuilder builder = new StringBuilder();
for (String value : newValues) {
builder.append(value + ",");
}
String temp = builder.toString();
if (temp.length() > 0) {
field.setTempValue(temp.substring(0, (temp.length() - 1)));
} else {
field.setTempValue(null);
}
}
public void handleFileUpload(FileUploadEvent event) throws IOException, PortalException, SystemException {
Field field = getField((Long) event.getComponent().getAttributes().get("reference"));
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
UploadedFile uploadedFile = event.getFile();
Company company = themeDisplay.getCompany();
long userId = company.getDefaultUser().getUserId();
long groupId = company.getGroup().getGroupId();
long repositoryId = groupId;
ServiceContext serviceContext = new ServiceContext();
DLFolder webFolder = buildFolder(company, FOLDER_CONTENT, new Long(0));
DLFolder formFolder = buildFolder(company, form.getId() + "-" + form.getLocaleName(), webFolder.getFolderId());
DateTime dateTime = new DateTime();
String nameFolder = dateTime.getDayOfMonth() + "-" + dateTime.getMonthOfYear() + "-" + dateTime.getYear();
DLFolder dlFolder = buildFolder(company, nameFolder, formFolder.getFolderId());
long folderId = dlFolder.getFolderId();
String name = uploadedFile.getFileName();
Boolean unique = false;
int x = 1;
while (unique == false) {
OrderByComparator obc = null;
List<DLFileEntry> files = DLFileEntryLocalServiceUtil.getFileEntries(groupId, folderId, -1, -1, obc);
Boolean found = false;
for (DLFileEntry dlFileEntry : files) {
if (dlFileEntry.getTitle().equals(name)) {
found = true;
}
}
if (found == false) {
unique = true;
} else {
name = "(" + x + ") " + uploadedFile.getFileName();
x++;
}
}
String sourceFileName = uploadedFile.getFileName();
String mimeType = new MimetypesFileTypeMap().getContentType(name);
String title = name;
String description = "";
String changeLog = "";
long fileEntryTypeId = new Long(0);
Map<String, Fields> fieldsMap = new HashMap<String, Fields>();
InputStream is = uploadedFile.getInputstream();
long size = uploadedFile.getContents().length;
File file = null;
serviceContext.setScopeGroupId(groupId);
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
serviceContext.setWorkflowAction(WorkflowConstants.STATUS_APPROVED);
DLFileEntry dlFileEntry = DLFileEntryLocalServiceUtil.addFileEntry(userId, groupId, repositoryId, folderId, sourceFileName, mimeType, title, description, changeLog, fileEntryTypeId, fieldsMap, file, is, size, serviceContext);
Long fileEntryId = dlFileEntry.getFileEntryId();
List<String> values = new ArrayList<String>();
if (field.getTempValue() != null) {
String[] documents = field.getTempValue().split("\\,");
values = new ArrayList<String>(Arrays.asList(documents));
}
values.add("" + fileEntryId);
StringBuilder builder = new StringBuilder();
for (String value : values) {
builder.append(value + ",");
}
String temp = builder.toString();
field.setTempValue(temp.substring(0, (temp.length() - 1)));
}
private DLFolder buildFolder(Company company, String name, Long parentId) throws PortalException, SystemException {
DLFolder dlFolder = null;
try {
dlFolder = DLFolderLocalServiceUtil.getFolder(company.getGroup().getGroupId(), parentId, name);
} catch (Exception e) {
sLog.debug("folder " + name + " does not exist, creating for webforms");
boolean mountPoint = false;
long parentFolderId = parentId;
String description = "";
long userId = company.getDefaultUser().getUserId();
long groupId = company.getGroup().getGroupId();
long repositoryId = groupId;
ServiceContext serviceContext = new ServiceContext();
dlFolder = DLFolderLocalServiceUtil.addFolder(userId, groupId, repositoryId, mountPoint, parentFolderId, name, description, false, serviceContext);
}
return dlFolder;
}
public List<Document> getUploadedFiles(Long id) {
Field field = getField(id);
List<Document> documents = new ArrayList<Document>();
if (field.getTempValue() != null) {
String[] fields = field.getTempValue().split("\\,");
for (String fileEntryId : fields) {
try {
if (!fileEntryId.isEmpty()) {
DLFileEntry dlFileEntry = DLFileEntryLocalServiceUtil.getDLFileEntry(new Long(fileEntryId));
documents.add(new Document("" + dlFileEntry.getFileEntryId(), dlFileEntry.getTitle(), dlFileEntry.getMimeType()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return documents;
}
private Field getField(Long id) {
List<Field> fields = this.getFields();
for (Field field : fields) {
if (field.getId().equals(id)) {
return field;
}
}
return null;
}
public void changeForm() {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
savePreference(portletRequest, PREFERENCE_FORM_ID, "" + this.selectedForm);
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("growl", new FacesMessage(LanguageUtil.get(themeDisplay.getLocale(), MESSAGE_SAVED_SUCCESS), ""));
}
public Form getForm() {
if (this.form == null) {
try {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
Long id = new Long(getPreference(portletRequest, PREFERENCE_FORM_ID, "0"));
if (!id.equals(new Long(0))) {
this.form = formController.getForm(id);
return this.form;
}
} catch (Exception e) {
e.printStackTrace();
}
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
this.forms = formController.getForms(themeDisplay.getCompanyId(), false);
}
return form;
}
public void setForm(Form form) {
this.form = form;
}
public List<Form> getForms() {
PortletRequest portletRequest = (PortletRequest) LiferayFacesContext.getCurrentInstance().getExternalContext().getRequest();
ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
this.forms = formController.getForms(themeDisplay.getCompanyId(), false);
return this.forms;
}
public void setForms(List<Form> forms) {
this.forms = forms;
}
public Long getSelectedForm() {
return selectedForm;
}
public void setSelectedForm(Long selectedForm) {
this.selectedForm = selectedForm;
}
public List<Field> getFields() {
if (this.form != null) {
this.fields = new ArrayList<Field>(form.getFields());
Collections.sort(this.fields, Form.fieldWeightComparator);
}
return fields;
}
public void setFields(List<Field> fields) {
this.fields = fields;
}
/**
* mail template building
*/
public static String getPreference(PortletRequest renderRequest, String key, String defaultValue) {
return renderRequest.getPreferences().getValue(key, defaultValue);
}
public static void savePreference(PortletRequest renderRequest, String key, String value) {
javax.portlet.PortletPreferences preferences = renderRequest.getPreferences();
try {
preferences.setValue(key, value);
preferences.store();
} catch (Exception e) {
sLog.error("failed to store property : " + key + " with value : " + value, e);
}
}
}