001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.blogs.action;
016    
017    import com.liferay.portal.kernel.json.JSONFactoryUtil;
018    import com.liferay.portal.kernel.json.JSONObject;
019    import com.liferay.portal.kernel.portlet.LiferayWindowState;
020    import com.liferay.portal.kernel.sanitizer.SanitizerException;
021    import com.liferay.portal.kernel.servlet.SessionErrors;
022    import com.liferay.portal.kernel.upload.UploadPortletRequest;
023    import com.liferay.portal.kernel.util.Constants;
024    import com.liferay.portal.kernel.util.HttpUtil;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.util.StreamUtil;
027    import com.liferay.portal.kernel.util.StringPool;
028    import com.liferay.portal.kernel.util.StringUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.kernel.workflow.WorkflowConstants;
031    import com.liferay.portal.security.auth.PrincipalException;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.service.ServiceContextFactory;
034    import com.liferay.portal.struts.PortletAction;
035    import com.liferay.portal.theme.ThemeDisplay;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PortletKeys;
038    import com.liferay.portal.util.PropsValues;
039    import com.liferay.portal.util.WebKeys;
040    import com.liferay.portlet.PortletURLImpl;
041    import com.liferay.portlet.asset.AssetCategoryException;
042    import com.liferay.portlet.asset.AssetTagException;
043    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
044    import com.liferay.portlet.blogs.EntryContentException;
045    import com.liferay.portlet.blogs.EntryDisplayDateException;
046    import com.liferay.portlet.blogs.EntrySmallImageNameException;
047    import com.liferay.portlet.blogs.EntrySmallImageSizeException;
048    import com.liferay.portlet.blogs.EntryTitleException;
049    import com.liferay.portlet.blogs.NoSuchEntryException;
050    import com.liferay.portlet.blogs.model.BlogsEntry;
051    import com.liferay.portlet.blogs.service.BlogsEntryLocalServiceUtil;
052    import com.liferay.portlet.blogs.service.BlogsEntryServiceUtil;
053    
054    import java.io.InputStream;
055    
056    import java.util.Calendar;
057    
058    import javax.portlet.ActionRequest;
059    import javax.portlet.ActionResponse;
060    import javax.portlet.PortletConfig;
061    import javax.portlet.PortletRequest;
062    import javax.portlet.RenderRequest;
063    import javax.portlet.RenderResponse;
064    import javax.portlet.WindowState;
065    
066    import javax.servlet.http.HttpServletResponse;
067    
068    import org.apache.struts.action.ActionForm;
069    import org.apache.struts.action.ActionForward;
070    import org.apache.struts.action.ActionMapping;
071    
072    /**
073     * @author Brian Wing Shun Chan
074     * @author Wilson S. Man
075     * @author Thiago Moreira
076     * @author Juan Fern??ndez
077     * @author Zsolt Berentey
078     */
079    public class EditEntryAction extends PortletAction {
080    
081            @Override
082            public void processAction(
083                            ActionMapping actionMapping, ActionForm actionForm,
084                            PortletConfig portletConfig, ActionRequest actionRequest,
085                            ActionResponse actionResponse)
086                    throws Exception {
087    
088                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
089    
090                    try {
091                            BlogsEntry entry = null;
092                            String oldUrlTitle = StringPool.BLANK;
093    
094                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
095                                    Object[] returnValue = updateEntry(actionRequest);
096    
097                                    entry = (BlogsEntry)returnValue[0];
098                                    oldUrlTitle = ((String)returnValue[1]);
099                            }
100                            else if (cmd.equals(Constants.DELETE)) {
101                                    deleteEntries(actionRequest);
102                            }
103                            else if (cmd.equals(Constants.SUBSCRIBE)) {
104                                    subscribe(actionRequest);
105                            }
106                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
107                                    unsubscribe(actionRequest);
108                            }
109    
110                            String redirect = ParamUtil.getString(actionRequest, "redirect");
111                            boolean updateRedirect = false;
112    
113                            if (Validator.isNotNull(oldUrlTitle)) {
114                                    String portletId = HttpUtil.getParameter(
115                                            redirect, "p_p_id", false);
116    
117                                    String oldRedirectParam =
118                                            PortalUtil.getPortletNamespace(portletId) + "redirect";
119    
120                                    String oldRedirect = HttpUtil.getParameter(
121                                            redirect, oldRedirectParam, false);
122    
123                                    if (Validator.isNotNull(oldRedirect)) {
124                                            String newRedirect = HttpUtil.decodeURL(oldRedirect);
125    
126                                            newRedirect = StringUtil.replace(
127                                                    newRedirect, oldUrlTitle, entry.getUrlTitle());
128                                            newRedirect = StringUtil.replace(
129                                                    newRedirect, oldRedirectParam, "redirect");
130    
131                                            redirect = StringUtil.replace(
132                                                    redirect, oldRedirect, newRedirect);
133                                    }
134                                    else if (redirect.endsWith("/blogs/" + oldUrlTitle) ||
135                                                     redirect.contains("/blogs/" + oldUrlTitle + "?") ||
136                                                     redirect.contains("/blog/" + oldUrlTitle + "?")) {
137    
138                                            redirect = StringUtil.replace(
139                                                    redirect, oldUrlTitle, entry.getUrlTitle());
140                                    }
141    
142                                    updateRedirect = true;
143                            }
144    
145                            int workflowAction = ParamUtil.getInteger(
146                                    actionRequest, "workflowAction",
147                                    WorkflowConstants.ACTION_SAVE_DRAFT);
148    
149                            boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");
150    
151                            if (ajax) {
152                                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
153    
154                                    jsonObject.put("entryId", entry.getEntryId());
155                                    jsonObject.put("redirect", redirect);
156                                    jsonObject.put("updateRedirect", updateRedirect);
157    
158                                    writeJSON(actionRequest, actionResponse, jsonObject);
159    
160                                    return;
161                            }
162    
163                            if ((entry != null) &&
164                                    (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
165    
166                                    redirect = getSaveAndContinueRedirect(
167                                            portletConfig, actionRequest, entry, redirect);
168    
169                                    sendRedirect(actionRequest, actionResponse, redirect);
170                            }
171                            else {
172                                    WindowState windowState = actionRequest.getWindowState();
173    
174                                    if (!windowState.equals(LiferayWindowState.POP_UP)) {
175                                            sendRedirect(actionRequest, actionResponse, redirect);
176                                    }
177                                    else {
178                                            redirect = PortalUtil.escapeRedirect(redirect);
179    
180                                            if (Validator.isNotNull(redirect)) {
181                                                    actionResponse.sendRedirect(redirect);
182                                            }
183                                    }
184                            }
185                    }
186                    catch (Exception e) {
187                            if (e instanceof NoSuchEntryException ||
188                                    e instanceof PrincipalException) {
189    
190                                    SessionErrors.add(actionRequest, e.getClass());
191    
192                                    setForward(actionRequest, "portlet.blogs.error");
193                            }
194                            else if (e instanceof EntryContentException ||
195                                             e instanceof EntryDisplayDateException ||
196                                             e instanceof EntrySmallImageNameException ||
197                                             e instanceof EntrySmallImageSizeException ||
198                                             e instanceof EntryTitleException ||
199                                             e instanceof SanitizerException) {
200    
201                                    SessionErrors.add(actionRequest, e.getClass());
202                            }
203                            else if (e instanceof AssetCategoryException ||
204                                             e instanceof AssetTagException) {
205    
206                                    SessionErrors.add(actionRequest, e.getClass(), e);
207                            }
208                            else {
209                                    Throwable cause = e.getCause();
210    
211                                    if (cause instanceof SanitizerException) {
212                                            SessionErrors.add(actionRequest, SanitizerException.class);
213                                    }
214                                    else {
215                                            throw e;
216                                    }
217                            }
218                    }
219            }
220    
221            @Override
222            public ActionForward render(
223                            ActionMapping actionMapping, ActionForm actionForm,
224                            PortletConfig portletConfig, RenderRequest renderRequest,
225                            RenderResponse renderResponse)
226                    throws Exception {
227    
228                    try {
229                            ActionUtil.getEntry(renderRequest);
230    
231                            if (PropsValues.BLOGS_PINGBACK_ENABLED) {
232                                    BlogsEntry entry = (BlogsEntry)renderRequest.getAttribute(
233                                            WebKeys.BLOGS_ENTRY);
234    
235                                    if ((entry != null) && entry.isAllowPingbacks()) {
236                                            HttpServletResponse response =
237                                                    PortalUtil.getHttpServletResponse(renderResponse);
238    
239                                            response.addHeader(
240                                                    "X-Pingback",
241                                                    PortalUtil.getPortalURL(renderRequest) +
242                                                            "/xmlrpc/pingback");
243                                    }
244                            }
245                    }
246                    catch (Exception e) {
247                            if (e instanceof NoSuchEntryException ||
248                                    e instanceof PrincipalException) {
249    
250                                    SessionErrors.add(renderRequest, e.getClass());
251    
252                                    return actionMapping.findForward("portlet.blogs.error");
253                            }
254                            else {
255                                    throw e;
256                            }
257                    }
258    
259                    return actionMapping.findForward(
260                            getForward(renderRequest, "portlet.blogs.edit_entry"));
261            }
262    
263            protected void deleteEntries(ActionRequest actionRequest) throws Exception {
264                    long entryId = ParamUtil.getLong(actionRequest, "entryId");
265    
266                    if (entryId > 0) {
267                            BlogsEntryServiceUtil.deleteEntry(entryId);
268                    }
269                    else {
270                            long[] deleteEntryIds = StringUtil.split(
271                                    ParamUtil.getString(actionRequest, "deleteEntryIds"), 0L);
272    
273                            for (int i = 0; i < deleteEntryIds.length; i++) {
274                                    BlogsEntryServiceUtil.deleteEntry(deleteEntryIds[i]);
275                            }
276                    }
277            }
278    
279            protected String getSaveAndContinueRedirect(
280                            PortletConfig portletConfig, ActionRequest actionRequest,
281                            BlogsEntry entry, String redirect)
282                    throws Exception {
283    
284                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
285                            WebKeys.THEME_DISPLAY);
286    
287                    String backURL = ParamUtil.getString(actionRequest, "backURL");
288    
289                    boolean preview = ParamUtil.getBoolean(actionRequest, "preview");
290    
291                    PortletURLImpl portletURL = new PortletURLImpl(
292                            actionRequest, portletConfig.getPortletName(),
293                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
294    
295                    String portletName = portletConfig.getPortletName();
296    
297                    if (portletName.equals(PortletKeys.BLOGS_ADMIN)) {
298                            portletURL.setParameter("struts_action", "/blogs_admin/edit_entry");
299                    }
300                    else {
301                            portletURL.setParameter("struts_action", "/blogs/edit_entry");
302                    }
303    
304                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
305                    portletURL.setParameter("redirect", redirect, false);
306                    portletURL.setParameter("backURL", backURL, false);
307                    portletURL.setParameter(
308                            "groupId", String.valueOf(entry.getGroupId()), false);
309                    portletURL.setParameter(
310                            "entryId", String.valueOf(entry.getEntryId()), false);
311                    portletURL.setParameter("preview", String.valueOf(preview), false);
312                    portletURL.setWindowState(actionRequest.getWindowState());
313    
314                    return portletURL.toString();
315            }
316    
317            protected void subscribe(ActionRequest actionRequest) throws Exception {
318                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
319                            WebKeys.THEME_DISPLAY);
320    
321                    BlogsEntryServiceUtil.subscribe(themeDisplay.getScopeGroupId());
322            }
323    
324            protected void unsubscribe(ActionRequest actionRequest) throws Exception {
325                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
326                            WebKeys.THEME_DISPLAY);
327    
328                    BlogsEntryServiceUtil.unsubscribe(themeDisplay.getScopeGroupId());
329            }
330    
331            protected Object[] updateEntry(ActionRequest actionRequest)
332                    throws Exception {
333    
334                    long entryId = ParamUtil.getLong(actionRequest, "entryId");
335    
336                    String title = ParamUtil.getString(actionRequest, "title");
337                    String description = ParamUtil.getString(actionRequest, "description");
338                    String content = ParamUtil.getString(actionRequest, "content");
339    
340                    int displayDateMonth = ParamUtil.getInteger(
341                            actionRequest, "displayDateMonth");
342                    int displayDateDay = ParamUtil.getInteger(
343                            actionRequest, "displayDateDay");
344                    int displayDateYear = ParamUtil.getInteger(
345                            actionRequest, "displayDateYear");
346                    int displayDateHour = ParamUtil.getInteger(
347                            actionRequest, "displayDateHour");
348                    int displayDateMinute = ParamUtil.getInteger(
349                            actionRequest, "displayDateMinute");
350                    int displayDateAmPm = ParamUtil.getInteger(
351                            actionRequest, "displayDateAmPm");
352    
353                    if (displayDateAmPm == Calendar.PM) {
354                            displayDateHour += 12;
355                    }
356    
357                    boolean allowPingbacks = ParamUtil.getBoolean(
358                            actionRequest, "allowPingbacks");
359                    boolean allowTrackbacks = ParamUtil.getBoolean(
360                            actionRequest, "allowTrackbacks");
361                    String[] trackbacks = StringUtil.split(
362                            ParamUtil.getString(actionRequest, "trackbacks"));
363    
364                    boolean smallImage = false;
365                    String smallImageURL = null;
366                    String smallImageFileName = null;
367                    InputStream smallImageInputStream = null;
368    
369                    BlogsEntry entry = null;
370                    String oldUrlTitle = null;
371    
372                    try {
373                            boolean ajax = ParamUtil.getBoolean(actionRequest, "ajax");
374    
375                            if (!ajax) {
376                                    smallImage = ParamUtil.getBoolean(actionRequest, "smallImage");
377                                    smallImageURL = ParamUtil.getString(
378                                            actionRequest, "smallImageURL");
379    
380                                    if (smallImage && Validator.isNull(smallImageURL)) {
381                                            boolean attachments = ParamUtil.getBoolean(
382                                                    actionRequest, "attachments");
383    
384                                            if (attachments) {
385                                                    UploadPortletRequest uploadPortletRequest =
386                                                            PortalUtil.getUploadPortletRequest(actionRequest);
387    
388                                                    smallImageFileName = uploadPortletRequest.getFileName(
389                                                            "smallFile");
390                                                    smallImageInputStream =
391                                                            uploadPortletRequest.getFileAsStream("smallFile");
392                                            }
393                                    }
394                            }
395    
396                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
397                                    BlogsEntry.class.getName(), actionRequest);
398    
399                            entry = null;
400                            oldUrlTitle = StringPool.BLANK;
401    
402                            if (entryId <= 0) {
403    
404                                    // Add entry
405    
406                                    entry = BlogsEntryServiceUtil.addEntry(
407                                            title, description, content, displayDateMonth,
408                                            displayDateDay, displayDateYear, displayDateHour,
409                                            displayDateMinute, allowPingbacks, allowTrackbacks,
410                                            trackbacks, smallImage, smallImageURL, smallImageFileName,
411                                            smallImageInputStream, serviceContext);
412    
413                                    AssetPublisherUtil.addAndStoreSelection(
414                                            actionRequest, BlogsEntry.class.getName(),
415                                            entry.getEntryId(), -1);
416                            }
417                            else {
418    
419                                    // Update entry
420    
421                                    entry = BlogsEntryLocalServiceUtil.getEntry(entryId);
422    
423                                    String tempOldUrlTitle = entry.getUrlTitle();
424    
425                                    entry = BlogsEntryServiceUtil.updateEntry(
426                                            entryId, title, description, content, displayDateMonth,
427                                            displayDateDay, displayDateYear, displayDateHour,
428                                            displayDateMinute, allowPingbacks, allowTrackbacks,
429                                            trackbacks, smallImage, smallImageURL, smallImageFileName,
430                                            smallImageInputStream, serviceContext);
431    
432                                    if (!tempOldUrlTitle.equals(entry.getUrlTitle())) {
433                                            oldUrlTitle = tempOldUrlTitle;
434                                    }
435    
436                                    AssetPublisherUtil.addAndStoreSelection(
437                                            actionRequest, BlogsEntry.class.getName(),
438                                            entry.getEntryId(), -1);
439                            }
440                    }
441                    finally {
442                            StreamUtil.cleanUp(smallImageInputStream);
443                    }
444    
445                    return new Object[] {entry, oldUrlTitle};
446            }
447    
448    }