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