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