1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.blogs.action;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
18  import com.liferay.portal.kernel.json.JSONFactoryUtil;
19  import com.liferay.portal.kernel.json.JSONObject;
20  import com.liferay.portal.kernel.servlet.SessionErrors;
21  import com.liferay.portal.kernel.util.Constants;
22  import com.liferay.portal.kernel.util.ContentTypes;
23  import com.liferay.portal.kernel.util.ParamUtil;
24  import com.liferay.portal.kernel.util.StringPool;
25  import com.liferay.portal.kernel.util.StringUtil;
26  import com.liferay.portal.kernel.util.Validator;
27  import com.liferay.portal.kernel.workflow.WorkflowConstants;
28  import com.liferay.portal.model.LayoutTypePortlet;
29  import com.liferay.portal.security.auth.PrincipalException;
30  import com.liferay.portal.security.permission.ActionKeys;
31  import com.liferay.portal.security.permission.PermissionChecker;
32  import com.liferay.portal.service.ServiceContext;
33  import com.liferay.portal.service.ServiceContextFactory;
34  import com.liferay.portal.service.SubscriptionLocalServiceUtil;
35  import com.liferay.portal.struts.ActionConstants;
36  import com.liferay.portal.struts.PortletAction;
37  import com.liferay.portal.theme.ThemeDisplay;
38  import com.liferay.portal.util.PortalUtil;
39  import com.liferay.portal.util.PropsValues;
40  import com.liferay.portal.util.WebKeys;
41  import com.liferay.portlet.asset.AssetTagException;
42  import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
43  import com.liferay.portlet.blogs.EntryContentException;
44  import com.liferay.portlet.blogs.EntryDisplayDateException;
45  import com.liferay.portlet.blogs.EntryTitleException;
46  import com.liferay.portlet.blogs.NoSuchEntryException;
47  import com.liferay.portlet.blogs.model.BlogsEntry;
48  import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
49  import com.liferay.portlet.blogs.service.BlogsEntryServiceUtil;
50  import com.liferay.portlet.blogs.service.permission.BlogsPermission;
51  import com.liferay.util.servlet.ServletResponseUtil;
52  
53  import java.io.InputStream;
54  
55  import java.util.Calendar;
56  
57  import javax.portlet.ActionRequest;
58  import javax.portlet.ActionResponse;
59  import javax.portlet.PortletConfig;
60  import javax.portlet.RenderRequest;
61  import javax.portlet.RenderResponse;
62  
63  import javax.servlet.http.HttpServletRequest;
64  import javax.servlet.http.HttpServletResponse;
65  
66  import org.apache.struts.action.ActionForm;
67  import org.apache.struts.action.ActionForward;
68  import org.apache.struts.action.ActionMapping;
69  
70  /**
71   * <a href="EditEntryAction.java.html"><b><i>View Source</i></b></a>
72   *
73   * @author Brian Wing Shun Chan
74   * @author Wilson S. Man
75   * @author Thiago Moreira
76   */
77  public class EditEntryAction extends PortletAction {
78  
79      public void processAction(
80              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
81              ActionRequest actionRequest, ActionResponse actionResponse)
82          throws Exception {
83  
84          String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
85  
86          try {
87              BlogsEntry entry = null;
88              String oldUrlTitle = StringPool.BLANK;
89  
90              if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
91                  Object[] returnValue = updateEntry(actionRequest);
92  
93                  entry = (BlogsEntry)returnValue[0];
94                  oldUrlTitle = ((String)returnValue[1]);
95              }
96              else if (cmd.equals(Constants.DELETE)) {
97                  deleteEntry(actionRequest);
98              }
99              else if (cmd.equals(Constants.SUBSCRIBE)) {
100                 subscribe(actionRequest);
101             }
102             else if (cmd.equals(Constants.UNSUBSCRIBE)) {
103                 unsubscribe(actionRequest);
104             }
105 
106             String redirect = ParamUtil.getString(actionRequest, "redirect");
107             boolean updateRedirect = false;
108 
109             if (redirect.indexOf(
110                     "/blogs/" + oldUrlTitle + "/maximized") != -1) {
111 
112                 oldUrlTitle += "/maximized";
113             }
114 
115             if ((entry != null) && (Validator.isNotNull(oldUrlTitle)) &&
116                 (redirect.endsWith("/blogs/" + oldUrlTitle) ||
117                  redirect.indexOf("/blogs/" + oldUrlTitle + "?") != -1)) {
118 
119                 int pos = redirect.indexOf("?");
120 
121                 if (pos == -1) {
122                     pos = redirect.length();
123                 }
124 
125                 String newRedirect = redirect.substring(
126                     0, pos - oldUrlTitle.length());
127 
128                 newRedirect += entry.getUrlTitle();
129 
130                 if (oldUrlTitle.indexOf("/maximized") != -1) {
131                     newRedirect += "/maximized";
132                 }
133 
134                 if (pos < redirect.length()) {
135                     newRedirect +=
136                         "?" + redirect.substring(pos + 1, redirect.length());
137                 }
138 
139                 redirect = newRedirect;
140                 updateRedirect = true;
141             }
142 
143             int workflowAction = ParamUtil.getInteger(
144                 actionRequest, "workflowAction");
145 
146             if ((entry != null) &&
147                 (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
148 
149                 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
150 
151                 jsonObj.put("entryId", entry.getEntryId());
152                 jsonObj.put("redirect", redirect);
153                 jsonObj.put("updateRedirect", updateRedirect);
154 
155                 HttpServletRequest request = PortalUtil.getHttpServletRequest(
156                     actionRequest);
157                 HttpServletResponse response =
158                     PortalUtil.getHttpServletResponse(actionResponse);
159                 InputStream is = new UnsyncByteArrayInputStream(
160                     jsonObj.toString().getBytes());
161                 String contentType = ContentTypes.TEXT_JAVASCRIPT;
162 
163                 ServletResponseUtil.sendFile(
164                     request, response, null, is, contentType);
165 
166                 setForward(actionRequest, ActionConstants.COMMON_NULL);
167             }
168             else {
169                 ThemeDisplay themeDisplay =
170                     (ThemeDisplay)actionRequest.getAttribute(
171                         WebKeys.THEME_DISPLAY);
172 
173                 LayoutTypePortlet layoutTypePortlet =
174                     themeDisplay.getLayoutTypePortlet();
175 
176                 if (layoutTypePortlet.hasPortletId(
177                         portletConfig.getPortletName())) {
178 
179                     sendRedirect(actionRequest, actionResponse, redirect);
180                 }
181                 else {
182                     actionResponse.sendRedirect(redirect);
183                 }
184             }
185         }
186         catch (Exception e) {
187             if (e instanceof NoSuchEntryException ||
188                 e instanceof PrincipalException) {
189 
190                 SessionErrors.add(actionRequest, e.getClass().getName());
191 
192                 setForward(actionRequest, "portlet.blogs.error");
193             }
194             else if (e instanceof EntryContentException ||
195                      e instanceof EntryDisplayDateException ||
196                      e instanceof EntryTitleException) {
197 
198                 SessionErrors.add(actionRequest, e.getClass().getName());
199             }
200             else if (e instanceof AssetTagException) {
201                 SessionErrors.add(actionRequest, e.getClass().getName(), e);
202             }
203             else {
204                 throw e;
205             }
206         }
207     }
208 
209     public ActionForward render(
210             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
211             RenderRequest renderRequest, RenderResponse renderResponse)
212         throws Exception {
213 
214         try {
215             ActionUtil.getEntry(renderRequest);
216 
217             if (PropsValues.BLOGS_PINGBACK_ENABLED) {
218                 BlogsEntry entry = (BlogsEntry)renderRequest.getAttribute(
219                     WebKeys.BLOGS_ENTRY);
220 
221                 if ((entry != null) && entry.isAllowPingbacks()) {
222                     HttpServletResponse response =
223                         PortalUtil.getHttpServletResponse(renderResponse);
224 
225                     response.addHeader(
226                         "X-Pingback",
227                         PortalUtil.getPortalURL(renderRequest) +
228                             "/xmlrpc/pingback");
229                 }
230             }
231         }
232         catch (Exception e) {
233             if (e instanceof NoSuchEntryException ||
234                 e instanceof PrincipalException) {
235 
236                 SessionErrors.add(renderRequest, e.getClass().getName());
237 
238                 return mapping.findForward("portlet.blogs.error");
239             }
240             else {
241                 throw e;
242             }
243         }
244 
245         return mapping.findForward(
246             getForward(renderRequest, "portlet.blogs.edit_entry"));
247     }
248 
249     protected void deleteEntry(ActionRequest actionRequest) throws Exception {
250         long entryId = ParamUtil.getLong(actionRequest, "entryId");
251 
252         BlogsEntryServiceUtil.deleteEntry(entryId);
253     }
254 
255     protected void subscribe(ActionRequest actionRequest) throws Exception {
256         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
257             WebKeys.THEME_DISPLAY);
258 
259         PermissionChecker permissionChecker =
260             themeDisplay.getPermissionChecker();
261 
262         if (BlogsPermission.contains(
263                 permissionChecker, themeDisplay.getScopeGroupId(),
264                 ActionKeys.SUBSCRIBE)) {
265 
266             SubscriptionLocalServiceUtil.addSubscription(
267                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
268                 themeDisplay.getScopeGroupId());
269         }
270     }
271 
272     protected void unsubscribe(ActionRequest actionRequest) throws Exception {
273         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
274             WebKeys.THEME_DISPLAY);
275 
276         PermissionChecker permissionChecker =
277             themeDisplay.getPermissionChecker();
278 
279         if (BlogsPermission.contains(
280                 permissionChecker, themeDisplay.getScopeGroupId(),
281                 ActionKeys.SUBSCRIBE)) {
282 
283             SubscriptionLocalServiceUtil.deleteSubscription(
284                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
285                 themeDisplay.getScopeGroupId());
286         }
287     }
288 
289     protected Object[] updateEntry(ActionRequest actionRequest)
290         throws Exception {
291 
292         long entryId = ParamUtil.getLong(actionRequest, "entryId");
293 
294         String title = ParamUtil.getString(actionRequest, "title");
295         String content = ParamUtil.getString(actionRequest, "content");
296 
297         int displayDateMonth = ParamUtil.getInteger(
298             actionRequest, "displayDateMonth");
299         int displayDateDay = ParamUtil.getInteger(
300             actionRequest, "displayDateDay");
301         int displayDateYear = ParamUtil.getInteger(
302             actionRequest, "displayDateYear");
303         int displayDateHour = ParamUtil.getInteger(
304             actionRequest, "displayDateHour");
305         int displayDateMinute = ParamUtil.getInteger(
306             actionRequest, "displayDateMinute");
307         int displayDateAmPm = ParamUtil.getInteger(
308             actionRequest, "displayDateAmPm");
309 
310         if (displayDateAmPm == Calendar.PM) {
311             displayDateHour += 12;
312         }
313 
314         boolean allowPingbacks = ParamUtil.getBoolean(
315             actionRequest, "allowPingbacks");
316         boolean allowTrackbacks = ParamUtil.getBoolean(
317             actionRequest, "allowTrackbacks");
318         String[] trackbacks = StringUtil.split(
319             ParamUtil.getString(actionRequest, "trackbacks"));
320 
321         ServiceContext serviceContext = ServiceContextFactory.getInstance(
322             BlogsEntry.class.getName(), actionRequest);
323 
324         BlogsEntry entry = null;
325         String oldUrlTitle = StringPool.BLANK;
326 
327         if (entryId <= 0) {
328 
329             // Add entry
330 
331             entry = BlogsEntryServiceUtil.addEntry(
332                 title, content, displayDateMonth, displayDateDay,
333                 displayDateYear, displayDateHour, displayDateMinute,
334                 allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
335 
336             AssetPublisherUtil.addAndStoreSelection(
337                 actionRequest, BlogsEntry.class.getName(), entry.getEntryId(),
338                 -1);
339         }
340         else {
341 
342             // Update entry
343 
344             entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
345 
346             String tempOldUrlTitle = entry.getUrlTitle();
347 
348             entry = BlogsEntryServiceUtil.updateEntry(
349                 entryId, title, content, displayDateMonth, displayDateDay,
350                 displayDateYear, displayDateHour, displayDateMinute,
351                 allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
352 
353             if (!tempOldUrlTitle.equals(entry.getUrlTitle())) {
354                 oldUrlTitle = tempOldUrlTitle;
355             }
356 
357             AssetPublisherUtil.addAndStoreSelection(
358                 actionRequest, BlogsEntry.class.getName(), entry.getEntryId(),
359                 -1);
360         }
361 
362         return new Object[] {entry, oldUrlTitle};
363     }
364 
365 }