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