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.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             if ((entry != null) &&
144                 (entry.getStatus() == StatusConstants.DRAFT)) {
145 
146                 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
147 
148                 jsonObj.put("entryId", entry.getEntryId());
149                 jsonObj.put("redirect", redirect);
150                 jsonObj.put("updateRedirect", updateRedirect);
151 
152                 HttpServletRequest request = PortalUtil.getHttpServletRequest(
153                     actionRequest);
154                 HttpServletResponse response =
155                     PortalUtil.getHttpServletResponse(actionResponse);
156                 InputStream is = new UnsyncByteArrayInputStream(
157                     jsonObj.toString().getBytes());
158                 String contentType = ContentTypes.TEXT_JAVASCRIPT;
159 
160                 ServletResponseUtil.sendFile(
161                     request, response, null, is, contentType);
162 
163                 setForward(actionRequest, ActionConstants.COMMON_NULL);
164             }
165             else {
166                 ThemeDisplay themeDisplay =
167                     (ThemeDisplay)actionRequest.getAttribute(
168                         WebKeys.THEME_DISPLAY);
169 
170                 LayoutTypePortlet layoutTypePortlet =
171                     themeDisplay.getLayoutTypePortlet();
172 
173                 if (layoutTypePortlet.hasPortletId(
174                         portletConfig.getPortletName())) {
175 
176                     sendRedirect(actionRequest, actionResponse, redirect);
177                 }
178                 else {
179                     actionResponse.sendRedirect(redirect);
180                 }
181             }
182         }
183         catch (Exception e) {
184             if (e instanceof NoSuchEntryException ||
185                 e instanceof PrincipalException) {
186 
187                 SessionErrors.add(actionRequest, e.getClass().getName());
188 
189                 setForward(actionRequest, "portlet.blogs.error");
190             }
191             else if (e instanceof EntryContentException ||
192                      e instanceof EntryDisplayDateException ||
193                      e instanceof EntryTitleException) {
194 
195                 SessionErrors.add(actionRequest, e.getClass().getName());
196             }
197             else if (e instanceof AssetTagException) {
198                 SessionErrors.add(actionRequest, e.getClass().getName(), e);
199             }
200             else {
201                 throw e;
202             }
203         }
204     }
205 
206     public ActionForward render(
207             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
208             RenderRequest renderRequest, RenderResponse renderResponse)
209         throws Exception {
210 
211         try {
212             ActionUtil.getEntry(renderRequest);
213 
214             if (PropsValues.BLOGS_PINGBACK_ENABLED) {
215                 BlogsEntry entry = (BlogsEntry)renderRequest.getAttribute(
216                     WebKeys.BLOGS_ENTRY);
217 
218                 if ((entry != null) && entry.isAllowPingbacks()) {
219                     HttpServletResponse response =
220                         PortalUtil.getHttpServletResponse(renderResponse);
221 
222                     response.addHeader(
223                         "X-Pingback",
224                         PortalUtil.getPortalURL(renderRequest) +
225                             "/xmlrpc/pingback");
226                 }
227             }
228         }
229         catch (Exception e) {
230             if (e instanceof NoSuchEntryException ||
231                 e instanceof PrincipalException) {
232 
233                 SessionErrors.add(renderRequest, e.getClass().getName());
234 
235                 return mapping.findForward("portlet.blogs.error");
236             }
237             else {
238                 throw e;
239             }
240         }
241 
242         return mapping.findForward(
243             getForward(renderRequest, "portlet.blogs.edit_entry"));
244     }
245 
246     protected void deleteEntry(ActionRequest actionRequest) throws Exception {
247         long entryId = ParamUtil.getLong(actionRequest, "entryId");
248 
249         BlogsEntryServiceUtil.deleteEntry(entryId);
250     }
251 
252     protected void subscribe(ActionRequest actionRequest) throws Exception {
253         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
254             WebKeys.THEME_DISPLAY);
255 
256         PermissionChecker permissionChecker =
257             themeDisplay.getPermissionChecker();
258 
259         if (BlogsPermission.contains(
260                 permissionChecker, themeDisplay.getScopeGroupId(),
261                 ActionKeys.SUBSCRIBE)) {
262 
263             SubscriptionLocalServiceUtil.addSubscription(
264                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
265                 themeDisplay.getScopeGroupId());
266         }
267     }
268 
269     protected void unsubscribe(ActionRequest actionRequest) throws Exception {
270         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
271             WebKeys.THEME_DISPLAY);
272 
273         PermissionChecker permissionChecker =
274             themeDisplay.getPermissionChecker();
275 
276         if (BlogsPermission.contains(
277                 permissionChecker, themeDisplay.getScopeGroupId(),
278                 ActionKeys.SUBSCRIBE)) {
279 
280             SubscriptionLocalServiceUtil.deleteSubscription(
281                 themeDisplay.getUserId(), BlogsEntry.class.getName(),
282                 themeDisplay.getScopeGroupId());
283         }
284     }
285 
286     protected Object[] updateEntry(ActionRequest actionRequest)
287         throws Exception {
288 
289         long entryId = ParamUtil.getLong(actionRequest, "entryId");
290 
291         String title = ParamUtil.getString(actionRequest, "title");
292         String content = ParamUtil.getString(actionRequest, "content");
293 
294         int displayDateMonth = ParamUtil.getInteger(
295             actionRequest, "displayDateMonth");
296         int displayDateDay = ParamUtil.getInteger(
297             actionRequest, "displayDateDay");
298         int displayDateYear = ParamUtil.getInteger(
299             actionRequest, "displayDateYear");
300         int displayDateHour = ParamUtil.getInteger(
301             actionRequest, "displayDateHour");
302         int displayDateMinute = ParamUtil.getInteger(
303             actionRequest, "displayDateMinute");
304         int displayDateAmPm = ParamUtil.getInteger(
305             actionRequest, "displayDateAmPm");
306 
307         if (displayDateAmPm == Calendar.PM) {
308             displayDateHour += 12;
309         }
310 
311         boolean allowPingbacks = ParamUtil.getBoolean(
312             actionRequest, "allowPingbacks");
313         boolean allowTrackbacks = ParamUtil.getBoolean(
314             actionRequest, "allowTrackbacks");
315         String[] trackbacks = StringUtil.split(
316             ParamUtil.getString(actionRequest, "trackbacks"));
317 
318         ServiceContext serviceContext = ServiceContextFactory.getInstance(
319             BlogsEntry.class.getName(), actionRequest);
320 
321         BlogsEntry entry = null;
322         String oldUrlTitle = StringPool.BLANK;
323 
324         if (entryId <= 0) {
325 
326             // Add entry
327 
328             entry = BlogsEntryServiceUtil.addEntry(
329                 title, content, displayDateMonth, displayDateDay,
330                 displayDateYear, displayDateHour, displayDateMinute,
331                 allowPingbacks, allowTrackbacks, trackbacks, serviceContext);
332 
333             if (serviceContext.getStatus() == StatusConstants.APPROVED) {
334                 AssetPublisherUtil.addAndStoreSelection(
335                     actionRequest, BlogsEntry.class.getName(),
336                     entry.getEntryId(), -1);
337             }
338         }
339         else {
340 
341             // Update entry
342 
343             entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
344 
345             String tempOldUrlTitle = entry.getUrlTitle();
346             int oldStatus = entry.getStatus();
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             if ((oldStatus == StatusConstants.DRAFT) &&
358                 (serviceContext.getStatus() == StatusConstants.APPROVED)) {
359 
360                 AssetPublisherUtil.addAndStoreSelection(
361                     actionRequest, BlogsEntry.class.getName(),
362                     entry.getEntryId(), -1);
363             }
364         }
365 
366         return new Object[] {entry, oldUrlTitle};
367     }
368 
369 }