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.StatusConstants;
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.HttpServletResponse;
64  
65  import org.apache.struts.action.ActionForm;
66  import org.apache.struts.action.ActionForward;
67  import org.apache.struts.action.ActionMapping;
68  
69  /**
70   * <a href="EditEntryAction.java.html"><b><i>View Source</i></b></a>
71   *
72   * @author Brian Wing Shun Chan
73   * @author Wilson S. Man
74   * @author Thiago Moreira
75   */
76  public class EditEntryAction extends PortletAction {
77  
78      public void processAction(
79              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
80              ActionRequest actionRequest, ActionResponse actionResponse)
81          throws Exception {
82  
83          String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
84  
85          try {
86              BlogsEntry entry = null;
87              String oldUrlTitle = StringPool.BLANK;
88  
89              if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
90                  Object[] returnValue = updateEntry(actionRequest);
91  
92                  entry = (BlogsEntry)returnValue[0];
93                  oldUrlTitle = ((String)returnValue[1]);
94              }
95              else if (cmd.equals(Constants.DELETE)) {
96                  deleteEntry(actionRequest);
97              }
98              else if (cmd.equals(Constants.SUBSCRIBE)) {
99                  subscribe(actionRequest);
100             }
101             else if (cmd.equals(Constants.UNSUBSCRIBE)) {
102                 unsubscribe(actionRequest);
103             }
104 
105             String redirect = ParamUtil.getString(actionRequest, "redirect");
106             boolean updateRedirect = false;
107 
108             if (redirect.indexOf(
109                     "/blogs/" + oldUrlTitle + "/maximized") != -1) {
110 
111                 oldUrlTitle += "/maximized";
112             }
113 
114             if ((entry != null) && (Validator.isNotNull(oldUrlTitle)) &&
115                 (redirect.endsWith("/blogs/" + oldUrlTitle) ||
116                  redirect.indexOf("/blogs/" + oldUrlTitle + "?") != -1)) {
117 
118                 int pos = redirect.indexOf("?");
119 
120                 if (pos == -1) {
121                     pos = redirect.length();
122                 }
123 
124                 String newRedirect = redirect.substring(
125                     0, pos - oldUrlTitle.length());
126 
127                 newRedirect += entry.getUrlTitle();
128 
129                 if (oldUrlTitle.indexOf("/maximized") != -1) {
130                     newRedirect += "/maximized";
131                 }
132 
133                 if (pos < redirect.length()) {
134                     newRedirect +=
135                         "?" + redirect.substring(pos + 1, redirect.length());
136                 }
137 
138                 redirect = newRedirect;
139                 updateRedirect = true;
140             }
141 
142             if ((entry != null) &&
143                 (entry.getStatus() == StatusConstants.DRAFT)) {
144 
145                 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
146 
147                 jsonObj.put("entryId", entry.getEntryId());
148                 jsonObj.put("redirect", redirect);
149                 jsonObj.put("updateRedirect", updateRedirect);
150 
151                 HttpServletResponse response =
152                     PortalUtil.getHttpServletResponse(actionResponse);
153                 InputStream is = new UnsyncByteArrayInputStream(
154                     jsonObj.toString().getBytes());
155                 String contentType = ContentTypes.TEXT_JAVASCRIPT;
156 
157                 ServletResponseUtil.sendFile(
158                     response, null, is, contentType);
159 
160                 setForward(actionRequest, ActionConstants.COMMON_NULL);
161             }
162             else {
163                 ThemeDisplay themeDisplay =
164                     (ThemeDisplay)actionRequest.getAttribute(
165                         WebKeys.THEME_DISPLAY);
166 
167                 LayoutTypePortlet layoutTypePortlet =
168                     themeDisplay.getLayoutTypePortlet();
169 
170                 if (layoutTypePortlet.hasPortletId(
171                         portletConfig.getPortletName())) {
172 
173                     sendRedirect(actionRequest, actionResponse, redirect);
174                 }
175                 else {
176                     actionResponse.sendRedirect(redirect);
177                 }
178             }
179         }
180         catch (Exception e) {
181             if (e instanceof NoSuchEntryException ||
182                 e instanceof PrincipalException) {
183 
184                 SessionErrors.add(actionRequest, e.getClass().getName());
185 
186                 setForward(actionRequest, "portlet.blogs.error");
187             }
188             else if (e instanceof EntryContentException ||
189                      e instanceof EntryDisplayDateException ||
190                      e instanceof EntryTitleException) {
191 
192                 SessionErrors.add(actionRequest, e.getClass().getName());
193             }
194             else if (e instanceof AssetTagException) {
195                 SessionErrors.add(actionRequest, e.getClass().getName(), e);
196             }
197             else {
198                 throw e;
199             }
200         }
201     }
202 
203     public ActionForward render(
204             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
205             RenderRequest renderRequest, RenderResponse renderResponse)
206         throws Exception {
207 
208         try {
209             ActionUtil.getEntry(renderRequest);
210 
211             if (PropsValues.BLOGS_PINGBACK_ENABLED) {
212                 BlogsEntry entry = (BlogsEntry)renderRequest.getAttribute(
213                     WebKeys.BLOGS_ENTRY);
214 
215                 if ((entry != null) && entry.isAllowPingbacks()) {
216                     HttpServletResponse response =
217                         PortalUtil.getHttpServletResponse(renderResponse);
218 
219                     response.addHeader(
220                         "X-Pingback",
221                         PortalUtil.getPortalURL(renderRequest) +
222                             "/xmlrpc/pingback");
223                 }
224             }
225         }
226         catch (Exception e) {
227             if (e instanceof NoSuchEntryException ||
228                 e instanceof PrincipalException) {
229 
230                 SessionErrors.add(renderRequest, e.getClass().getName());
231 
232                 return mapping.findForward("portlet.blogs.error");
233             }
234             else {
235                 throw e;
236             }
237         }
238 
239         return mapping.findForward(
240             getForward(renderRequest, "portlet.blogs.edit_entry"));
241     }
242 
243     protected void deleteEntry(ActionRequest actionRequest) throws Exception {
244         long entryId = ParamUtil.getLong(actionRequest, "entryId");
245 
246         BlogsEntryServiceUtil.deleteEntry(entryId);
247     }
248 
249     protected void subscribe(ActionRequest actionRequest) throws Exception {
250         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
251             WebKeys.THEME_DISPLAY);
252 
253         PermissionChecker permissionChecker =
254             themeDisplay.getPermissionChecker();
255 
256         if (BlogsPermission.contains(
257                 permissionChecker, themeDisplay.getScopeGroupId(),
258                 ActionKeys.SUBSCRIBE)) {
259 
260             SubscriptionLocalServiceUtil.addSubscription(
261                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
262                 themeDisplay.getScopeGroupId());
263         }
264     }
265 
266     protected void unsubscribe(ActionRequest actionRequest) throws Exception {
267         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
268             WebKeys.THEME_DISPLAY);
269 
270         PermissionChecker permissionChecker =
271             themeDisplay.getPermissionChecker();
272 
273         if (BlogsPermission.contains(
274                 permissionChecker, themeDisplay.getScopeGroupId(),
275                 ActionKeys.SUBSCRIBE)) {
276 
277             SubscriptionLocalServiceUtil.deleteSubscription(
278                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
279                 themeDisplay.getScopeGroupId());
280         }
281     }
282 
283     protected Object[] updateEntry(ActionRequest actionRequest)
284         throws Exception {
285 
286         long entryId = ParamUtil.getLong(actionRequest, "entryId");
287 
288         String title = ParamUtil.getString(actionRequest, "title");
289         String content = ParamUtil.getString(actionRequest, "content");
290 
291         int displayDateMonth = ParamUtil.getInteger(
292             actionRequest, "displayDateMonth");
293         int displayDateDay = ParamUtil.getInteger(
294             actionRequest, "displayDateDay");
295         int displayDateYear = ParamUtil.getInteger(
296             actionRequest, "displayDateYear");
297         int displayDateHour = ParamUtil.getInteger(
298             actionRequest, "displayDateHour");
299         int displayDateMinute = ParamUtil.getInteger(
300             actionRequest, "displayDateMinute");
301         int displayDateAmPm = ParamUtil.getInteger(
302             actionRequest, "displayDateAmPm");
303 
304         if (displayDateAmPm == Calendar.PM) {
305             displayDateHour += 12;
306         }
307 
308         boolean allowPingbacks = ParamUtil.getBoolean(
309             actionRequest, "allowPingbacks");
310         boolean allowTrackbacks = ParamUtil.getBoolean(
311             actionRequest, "allowTrackbacks");
312         String[] trackbacks = StringUtil.split(
313             ParamUtil.getString(actionRequest, "trackbacks"));
314 
315         ServiceContext serviceContext = ServiceContextFactory.getInstance(
316             BlogsEntry.class.getName(), actionRequest);
317 
318         BlogsEntry entry = null;
319         String oldUrlTitle = StringPool.BLANK;
320 
321         if (entryId <= 0) {
322 
323             // Add entry
324 
325             entry = BlogsEntryServiceUtil.addEntry(
326                 title, content, displayDateMonth, displayDateDay,
327                 displayDateYear, displayDateHour, displayDateMinute,
328                 allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
329 
330             if (serviceContext.getStatus() == StatusConstants.APPROVED) {
331                 AssetPublisherUtil.addAndStoreSelection(
332                     actionRequest, BlogsEntry.class.getName(),
333                     entry.getEntryId(), -1);
334             }
335         }
336         else {
337 
338             // Update entry
339 
340             entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
341 
342             String tempOldUrlTitle = entry.getUrlTitle();
343             int oldStatus = entry.getStatus();
344 
345             entry = BlogsEntryServiceUtil.updateEntry(
346                 entryId, title, content, displayDateMonth, displayDateDay,
347                 displayDateYear, displayDateHour, displayDateMinute,
348                 allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
349 
350             if (!tempOldUrlTitle.equals(entry.getUrlTitle())) {
351                 oldUrlTitle = tempOldUrlTitle;
352             }
353 
354             if ((oldStatus == StatusConstants.DRAFT) &&
355                 (serviceContext.getStatus() == StatusConstants.APPROVED)) {
356 
357                 AssetPublisherUtil.addAndStoreSelection(
358                     actionRequest, BlogsEntry.class.getName(),
359                     entry.getEntryId(), -1);
360             }
361         }
362 
363         return new Object[] {entry, oldUrlTitle};
364     }
365 
366 }