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); } } }