1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portlet.webform.action;
16  
17  import com.liferay.counter.service.CounterLocalServiceUtil;
18  import com.liferay.mail.service.MailServiceUtil;
19  import com.liferay.portal.kernel.captcha.CaptchaTextException;
20  import com.liferay.portal.kernel.captcha.CaptchaUtil;
21  import com.liferay.portal.kernel.log.Log;
22  import com.liferay.portal.kernel.log.LogFactoryUtil;
23  import com.liferay.portal.kernel.mail.MailMessage;
24  import com.liferay.portal.kernel.servlet.SessionErrors;
25  import com.liferay.portal.kernel.servlet.SessionMessages;
26  import com.liferay.portal.kernel.util.FileUtil;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.struts.PortletAction;
32  import com.liferay.portlet.PortletConfigImpl;
33  import com.liferay.portlet.PortletPreferencesFactoryUtil;
34  import com.liferay.portlet.expando.service.ExpandoValueLocalServiceUtil;
35  import com.liferay.portlet.webform.util.WebFormUtil;
36  
37  import java.util.HashSet;
38  import java.util.LinkedHashMap;
39  import java.util.Map;
40  import java.util.Set;
41  
42  import javax.mail.internet.InternetAddress;
43  
44  import javax.portlet.ActionRequest;
45  import javax.portlet.ActionResponse;
46  import javax.portlet.PortletConfig;
47  import javax.portlet.PortletPreferences;
48  import javax.portlet.RenderRequest;
49  import javax.portlet.RenderResponse;
50  
51  import org.apache.struts.action.ActionForm;
52  import org.apache.struts.action.ActionForward;
53  import org.apache.struts.action.ActionMapping;
54  
55  /**
56   * <a href="ViewAction.java.html"><b><i>View Source</i></b></a>
57   *
58   * @author Daniel Weisser
59   * @author Jorge Ferrer
60   * @author Alberto Montero
61   * @author Julio Camarero
62   */
63  public class ViewAction extends PortletAction {
64  
65      public void processAction(
66              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
67              ActionRequest actionRequest, ActionResponse actionResponse)
68          throws Exception {
69  
70          PortletConfigImpl portletConfigImpl = (PortletConfigImpl)portletConfig;
71  
72          String portletId = portletConfigImpl.getPortletId();
73  
74          PortletPreferences preferences =
75              PortletPreferencesFactoryUtil.getPortletSetup(
76                  actionRequest, portletId);
77  
78          boolean requireCaptcha = GetterUtil.getBoolean(
79              preferences.getValue("requireCaptcha", StringPool.BLANK));
80          String successURL = GetterUtil.getString(
81              preferences.getValue("successURL", StringPool.BLANK));
82          boolean sendAsEmail = GetterUtil.getBoolean(
83              preferences.getValue("sendAsEmail", StringPool.BLANK));
84          boolean saveToDatabase = GetterUtil.getBoolean(
85              preferences.getValue("saveToDatabase", StringPool.BLANK));
86          String databaseTableName = GetterUtil.getString(
87              preferences.getValue("databaseTableName", StringPool.BLANK));
88          boolean saveToFile = GetterUtil.getBoolean(
89              preferences.getValue("saveToFile", StringPool.BLANK));
90          String fileName = GetterUtil.getString(
91              preferences.getValue("fileName", StringPool.BLANK));
92  
93          if (requireCaptcha) {
94              try {
95                  CaptchaUtil.check(actionRequest);
96              }
97              catch (CaptchaTextException cte) {
98                  SessionErrors.add(
99                      actionRequest, CaptchaTextException.class.getName());
100 
101                 return;
102             }
103         }
104 
105         Map<String,String> fieldsMap = new LinkedHashMap<String,String>();
106 
107         for (int i = 1; true; i++) {
108             String fieldLabel = preferences.getValue(
109                 "fieldLabel" + i, StringPool.BLANK);
110 
111             if (Validator.isNull(fieldLabel)) {
112                 break;
113             }
114 
115             fieldsMap.put(fieldLabel, actionRequest.getParameter("field" + i));
116         }
117 
118         Set<String> validationErrors = null;
119 
120         try {
121             validationErrors = validate(fieldsMap, preferences);
122         }
123         catch (Exception e) {
124             actionRequest.setAttribute(
125                 "validationScriptError", e.getMessage().trim());
126 
127             setForward(actionRequest, "portlet.web_form.error");
128 
129             return;
130         }
131 
132         if (validationErrors.isEmpty()) {
133             boolean emailSuccess = true;
134             boolean databaseSuccess = true;
135             boolean fileSuccess = true;
136 
137             if (sendAsEmail) {
138                 emailSuccess = sendEmail(fieldsMap, preferences);
139             }
140 
141             if (saveToDatabase) {
142                 if (Validator.isNull(databaseTableName)) {
143                     databaseTableName = WebFormUtil.getNewDatabaseTableName(
144                         portletId);
145 
146                     preferences.setValue(
147                         "databaseTableName", databaseTableName);
148 
149                     preferences.store();
150                 }
151 
152                 databaseSuccess = saveDatabase(
153                     fieldsMap, preferences, databaseTableName);
154             }
155 
156             if (saveToFile) {
157                 fileSuccess = saveFile(fieldsMap, fileName);
158             }
159 
160             if (emailSuccess && databaseSuccess && fileSuccess) {
161                 SessionMessages.add(actionRequest, "success");
162             }
163             else {
164                 SessionErrors.add(actionRequest, "error");
165             }
166         }
167         else {
168             for (String badField : validationErrors) {
169                 SessionErrors.add(actionRequest, "error" + badField);
170             }
171         }
172 
173         if (SessionErrors.isEmpty(actionRequest) &&
174             Validator.isNotNull(successURL)) {
175 
176             actionResponse.sendRedirect(successURL);
177         }
178         else {
179             sendRedirect(actionRequest, actionResponse);
180         }
181     }
182 
183     public ActionForward render(
184             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
185             RenderRequest renderRequest, RenderResponse renderResponse)
186         throws Exception {
187 
188         return mapping.findForward(
189             getForward(renderRequest, "portlet.web_form.view"));
190     }
191 
192     protected String getMailBody(Map<String,String> fieldsMap) {
193         StringBuilder sb = new StringBuilder();
194 
195         for (String fieldLabel : fieldsMap.keySet()) {
196             String fieldValue = fieldsMap.get(fieldLabel);
197 
198             sb.append(fieldLabel);
199             sb.append(" : ");
200             sb.append(fieldValue);
201             sb.append("\n");
202         }
203 
204         return sb.toString();
205     }
206 
207     private boolean saveDatabase(
208             Map<String,String> fieldsMap, PortletPreferences preferences,
209             String databaseTableName)
210         throws Exception {
211 
212         WebFormUtil.checkTable(databaseTableName, preferences);
213 
214         long classPK = CounterLocalServiceUtil.increment(
215             WebFormUtil.class.getName());
216 
217         try {
218             for (String fieldLabel : fieldsMap.keySet()) {
219                 String fieldValue = fieldsMap.get(fieldLabel);
220 
221                 ExpandoValueLocalServiceUtil.addValue(
222                     WebFormUtil.class.getName(), databaseTableName, fieldLabel,
223                     classPK, fieldValue);
224             }
225 
226             return true;
227         }
228         catch (Exception e) {
229             _log.error(
230                 "The web form data could not be saved to the database", e);
231 
232             return false;
233         }
234     }
235 
236     protected boolean saveFile(Map<String,String> fieldsMap, String fileName) {
237 
238         // Save the file as a standard Excel CSV format. Use ; as a delimiter,
239         // quote each entry with double quotes, and escape double quotes in
240         // values a two double quotes.
241 
242         StringBuilder sb = new StringBuilder();
243 
244         for (String fieldLabel : fieldsMap.keySet()) {
245             String fieldValue = fieldsMap.get(fieldLabel);
246 
247             sb.append("\"");
248             sb.append(StringUtil.replace(fieldValue, "\"", "\"\""));
249             sb.append("\";");
250         }
251 
252         String s = sb.substring(0, sb.length() - 1) + "\n";
253 
254         try {
255             FileUtil.write(fileName, s, false, true);
256 
257             return true;
258         }
259         catch (Exception e) {
260             _log.error("The web form data could not be saved to a file", e);
261 
262             return false;
263         }
264     }
265 
266     protected boolean sendEmail(
267         Map<String,String> fieldsMap, PortletPreferences preferences) {
268 
269         try {
270             String subject = preferences.getValue("subject", StringPool.BLANK);
271             String emailAddress = preferences.getValue(
272                 "emailAddress", StringPool.BLANK);
273 
274             if (Validator.isNull(emailAddress)) {
275                 _log.error(
276                     "The web form email cannot be sent because no email " +
277                         "address is configured");
278 
279                 return false;
280             }
281 
282             String body = getMailBody(fieldsMap);
283 
284             InternetAddress fromAddress = new InternetAddress(emailAddress);
285             InternetAddress toAddress = new InternetAddress(emailAddress);
286 
287             MailMessage mailMessage = new MailMessage(
288                 fromAddress, toAddress, subject, body, false);
289 
290             MailServiceUtil.sendEmail(mailMessage);
291 
292             return true;
293         }
294         catch (Exception e) {
295             _log.error("The web form email could not be sent", e);
296 
297             return false;
298         }
299     }
300 
301     protected Set<String> validate(
302             Map<String,String> fieldsMap, PortletPreferences preferences)
303         throws Exception {
304 
305         Set<String> validationErrors = new HashSet<String>();
306 
307         for (int i = 0; i < fieldsMap.size(); i++) {
308             String fieldType = preferences.getValue(
309                 "fieldType" + (i + 1), StringPool.BLANK);
310             String fieldLabel = preferences.getValue(
311                 "fieldLabel" + (i + 1), StringPool.BLANK);
312             String fieldValue = fieldsMap.get(fieldLabel);
313 
314             boolean fieldOptional = GetterUtil.getBoolean(
315                 preferences.getValue(
316                     "fieldOptional" + (i + 1), StringPool.BLANK));
317 
318             if (Validator.equals(fieldType, "paragraph")) {
319                 continue;
320             }
321 
322             if (!fieldOptional && Validator.isNotNull(fieldLabel) &&
323                 Validator.isNull(fieldValue)) {
324 
325                 validationErrors.add(fieldLabel);
326 
327                 continue;
328             }
329 
330             String validationScript = GetterUtil.getString(
331                 preferences.getValue(
332                     "fieldValidationScript" + (i + 1), StringPool.BLANK));
333 
334             if (Validator.isNotNull(validationScript) &&
335                 !WebFormUtil.validate(
336                     fieldValue, fieldsMap, validationScript)) {
337 
338                 validationErrors.add(fieldLabel);
339 
340                 continue;
341             }
342         }
343 
344         return validationErrors;
345     }
346 
347     protected boolean isCheckMethodOnProcessAction() {
348         return _CHECK_METHOD_ON_PROCESS_ACTION;
349     }
350 
351     private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
352 
353     private static Log _log = LogFactoryUtil.getLog(ViewAction.class);
354 
355 }