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