001    /**
002     * Copyright (c) 2000-2012 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.wiki.action;
016    
017    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
018    import com.liferay.portal.kernel.servlet.SessionErrors;
019    import com.liferay.portal.kernel.servlet.SessionMessages;
020    import com.liferay.portal.kernel.util.Constants;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.StringUtil;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.model.Layout;
027    import com.liferay.portal.security.auth.PrincipalException;
028    import com.liferay.portal.service.ServiceContext;
029    import com.liferay.portal.service.ServiceContextFactory;
030    import com.liferay.portal.struts.PortletAction;
031    import com.liferay.portal.struts.StrutsActionPortletURL;
032    import com.liferay.portal.theme.ThemeDisplay;
033    import com.liferay.portal.util.WebKeys;
034    import com.liferay.portlet.PortletResponseImpl;
035    import com.liferay.portlet.PortletURLImpl;
036    import com.liferay.portlet.asset.AssetCategoryException;
037    import com.liferay.portlet.asset.AssetTagException;
038    import com.liferay.portlet.wiki.DuplicatePageException;
039    import com.liferay.portlet.wiki.NoSuchNodeException;
040    import com.liferay.portlet.wiki.NoSuchPageException;
041    import com.liferay.portlet.wiki.PageContentException;
042    import com.liferay.portlet.wiki.PageTitleException;
043    import com.liferay.portlet.wiki.PageVersionException;
044    import com.liferay.portlet.wiki.model.WikiNode;
045    import com.liferay.portlet.wiki.model.WikiPage;
046    import com.liferay.portlet.wiki.model.WikiPageConstants;
047    import com.liferay.portlet.wiki.service.WikiPageLocalServiceUtil;
048    import com.liferay.portlet.wiki.service.WikiPageServiceUtil;
049    
050    import java.util.HashMap;
051    import java.util.Map;
052    
053    import javax.portlet.ActionRequest;
054    import javax.portlet.ActionResponse;
055    import javax.portlet.PortletConfig;
056    import javax.portlet.PortletRequest;
057    import javax.portlet.RenderRequest;
058    import javax.portlet.RenderResponse;
059    
060    import org.apache.struts.action.ActionForm;
061    import org.apache.struts.action.ActionForward;
062    import org.apache.struts.action.ActionMapping;
063    
064    /**
065     * @author Brian Wing Shun Chan
066     * @author Jorge Ferrer
067     */
068    public class EditPageAction extends PortletAction {
069    
070            @Override
071            public void processAction(
072                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
073                            ActionRequest actionRequest, ActionResponse actionResponse)
074                    throws Exception {
075    
076                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
077    
078                    WikiPage page = null;
079    
080                    try {
081                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
082                                    page = updatePage(actionRequest);
083                            }
084                            else if (cmd.equals(Constants.DELETE)) {
085                                    deletePage(
086                                            (LiferayPortletConfig)portletConfig, actionRequest, false);
087                            }
088                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
089                                    deletePage(
090                                            (LiferayPortletConfig)portletConfig, actionRequest, true);
091                            }
092                            else if (cmd.equals(Constants.RESTORE)) {
093                                    restorePage(actionRequest);
094                            }
095                            else if (cmd.equals(Constants.REVERT)) {
096                                    revertPage(actionRequest);
097                            }
098                            else if (cmd.equals(Constants.SUBSCRIBE)) {
099                                    subscribePage(actionRequest);
100                            }
101                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
102                                    unsubscribePage(actionRequest);
103                            }
104    
105                            if (Validator.isNotNull(cmd)) {
106                                    String redirect = ParamUtil.getString(
107                                            actionRequest, "redirect");
108    
109                                    int workflowAction = ParamUtil.getInteger(
110                                            actionRequest, "workflowAction",
111                                            WorkflowConstants.ACTION_PUBLISH);
112    
113                                    if (page != null) {
114                                            if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
115                                                    redirect = getSaveAndContinueRedirect(
116                                                            actionRequest, actionResponse, page, redirect);
117                                            }
118                                            else if (redirect.endsWith("title=")) {
119                                                    redirect += page.getTitle();
120                                            }
121                                    }
122    
123                                    sendRedirect(actionRequest, actionResponse, redirect);
124                            }
125                    }
126                    catch (Exception e) {
127                            if (e instanceof NoSuchNodeException ||
128                                    e instanceof NoSuchPageException ||
129                                    e instanceof PrincipalException) {
130    
131                                    SessionErrors.add(actionRequest, e.getClass());
132    
133                                    setForward(actionRequest, "portlet.wiki.error");
134                            }
135                            else if (e instanceof DuplicatePageException ||
136                                             e instanceof PageContentException ||
137                                             e instanceof PageVersionException ||
138                                             e instanceof PageTitleException) {
139    
140                                    SessionErrors.add(actionRequest, e.getClass());
141                            }
142                            else if (e instanceof AssetCategoryException ||
143                                             e instanceof AssetTagException) {
144    
145                                    SessionErrors.add(actionRequest, e.getClass(), e);
146                            }
147                            else {
148                                    throw e;
149                            }
150                    }
151            }
152    
153            @Override
154            public ActionForward render(
155                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
156                            RenderRequest renderRequest, RenderResponse renderResponse)
157                    throws Exception {
158    
159                    try {
160                            ActionUtil.getNode(renderRequest);
161    
162                            if (!SessionErrors.contains(
163                                            renderRequest, DuplicatePageException.class.getName())) {
164    
165                                    getPage(renderRequest);
166                            }
167                    }
168                    catch (Exception e) {
169                            if (e instanceof NoSuchNodeException ||
170                                    e instanceof PageTitleException ||
171                                    e instanceof PrincipalException) {
172    
173                                    SessionErrors.add(renderRequest, e.getClass());
174    
175                                    return mapping.findForward("portlet.wiki.error");
176                            }
177                            else if (e instanceof NoSuchPageException) {
178    
179                                    // Let edit_page.jsp handle this case
180    
181                            }
182                            else {
183                                    throw e;
184                            }
185                    }
186    
187                    return mapping.findForward(
188                            getForward(renderRequest, "portlet.wiki.edit_page"));
189            }
190    
191            protected void deletePage(
192                            LiferayPortletConfig liferayPortletConfig,
193                            ActionRequest actionRequest, boolean moveToTrash)
194                    throws Exception {
195    
196                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
197                    String title = ParamUtil.getString(actionRequest, "title");
198                    double version = ParamUtil.getDouble(actionRequest, "version");
199    
200                    WikiPage wikiPage = null;
201    
202                    if (moveToTrash) {
203                            if (version > 0) {
204                                    wikiPage = WikiPageLocalServiceUtil.getPage(
205                                            nodeId, title, version);
206    
207                                    WikiPageServiceUtil.movePageToTrash(nodeId, title, version);
208                            }
209                            else {
210                                    wikiPage = WikiPageLocalServiceUtil.getPage(nodeId, title);
211    
212                                    WikiPageServiceUtil.movePageToTrash(nodeId, title);
213                            }
214                    }
215                    else {
216                            if (version > 0) {
217                                    WikiPageServiceUtil.deletePage(nodeId, title, version);
218                            }
219                            else {
220                                    WikiPageServiceUtil.deletePage(nodeId, title);
221                            }
222                    }
223    
224                    if (moveToTrash) {
225                            Map<String, String[]> data = new HashMap<String, String[]>();
226    
227                            data.put(
228                                    "restoreEntryIds",
229                                    new String[]{String.valueOf(wikiPage.getResourcePrimKey())});
230    
231                            SessionMessages.add(
232                                    actionRequest,
233                                    liferayPortletConfig.getPortletId() +
234                                            SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA, data);
235    
236                            SessionMessages.add(
237                                    actionRequest,
238                                    liferayPortletConfig.getPortletId() +
239                                            SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_SUCCESS_MESSAGE);
240                    }
241            }
242    
243            protected void getPage(RenderRequest renderRequest) throws Exception {
244                    long nodeId = ParamUtil.getLong(renderRequest, "nodeId");
245                    String title = ParamUtil.getString(renderRequest, "title");
246                    double version = ParamUtil.getDouble(renderRequest, "version");
247                    boolean removeRedirect = ParamUtil.getBoolean(
248                            renderRequest, "removeRedirect");
249    
250                    if (nodeId == 0) {
251                            WikiNode node = (WikiNode)renderRequest.getAttribute(
252                                    WebKeys.WIKI_NODE);
253    
254                            if (node != null) {
255                                    nodeId = node.getNodeId();
256                            }
257                    }
258    
259                    WikiPage page = null;
260    
261                    if (Validator.isNotNull(title)) {
262                            try {
263                                    if (version == 0) {
264                                            page = WikiPageServiceUtil.getPage(nodeId, title, null);
265                                    }
266                                    else {
267                                            page = WikiPageServiceUtil.getPage(nodeId, title, version);
268                                    }
269                            }
270                            catch (NoSuchPageException nspe1) {
271                                    try {
272                                            page = WikiPageServiceUtil.getPage(nodeId, title, false);
273                                    }
274                                    catch (NoSuchPageException nspe2) {
275                                            if (title.equals(WikiPageConstants.FRONT_PAGE) &&
276                                                    (version == 0)) {
277    
278                                                    ServiceContext serviceContext = new ServiceContext();
279    
280                                                    page = WikiPageServiceUtil.addPage(
281                                                            nodeId, title, null, WikiPageConstants.NEW, true,
282                                                            serviceContext);
283                                            }
284                                            else {
285                                                    throw nspe2;
286                                            }
287                                    }
288                            }
289    
290                            if (removeRedirect) {
291                                    page.setContent(StringPool.BLANK);
292                                    page.setRedirectTitle(StringPool.BLANK);
293                            }
294                    }
295    
296                    renderRequest.setAttribute(WebKeys.WIKI_PAGE, page);
297            }
298    
299            protected String getSaveAndContinueRedirect(
300                            ActionRequest actionRequest, ActionResponse actionResponse,
301                            WikiPage page, String redirect)
302                    throws Exception {
303    
304                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
305                            WebKeys.THEME_DISPLAY);
306    
307                    Layout layout = themeDisplay.getLayout();
308    
309                    String originalRedirect = ParamUtil.getString(
310                            actionRequest, "originalRedirect");
311    
312                    PortletURLImpl portletURL = new StrutsActionPortletURL(
313                            (PortletResponseImpl)actionResponse, themeDisplay.getPlid(),
314                            PortletRequest.RENDER_PHASE);
315    
316                    portletURL.setParameter("struts_action", "/wiki/edit_page");
317                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
318                    portletURL.setParameter("redirect", redirect, false);
319                    portletURL.setParameter("originalRedirect", originalRedirect, false);
320                    portletURL.setParameter(
321                            "groupId", String.valueOf(layout.getGroupId()), false);
322                    portletURL.setParameter(
323                            "nodeId", String.valueOf(page.getNodeId()), false);
324                    portletURL.setParameter("title", page.getTitle(), false);
325    
326                    return portletURL.toString();
327            }
328    
329            @Override
330            protected boolean isCheckMethodOnProcessAction() {
331                    return _CHECK_METHOD_ON_PROCESS_ACTION;
332            }
333    
334            protected void restorePage(ActionRequest actionRequest) throws Exception {
335                    long[] restoreEntryIds = StringUtil.split(
336                            ParamUtil.getString(actionRequest, "restoreEntryIds"), 0L);
337    
338                    for (long restoreEntryId : restoreEntryIds) {
339                            WikiPageServiceUtil.restorePageFromTrash(restoreEntryId);
340                    }
341            }
342    
343            protected void revertPage(ActionRequest actionRequest) throws Exception {
344                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
345                    String title = ParamUtil.getString(actionRequest, "title");
346                    double version = ParamUtil.getDouble(actionRequest, "version");
347    
348                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
349                            WikiPage.class.getName(), actionRequest);
350    
351                    WikiPageServiceUtil.revertPage(nodeId, title, version, serviceContext);
352            }
353    
354            protected void subscribePage(ActionRequest actionRequest) throws Exception {
355                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
356                    String title = ParamUtil.getString(actionRequest, "title");
357    
358                    WikiPageServiceUtil.subscribePage(nodeId, title);
359            }
360    
361            protected void unsubscribePage(ActionRequest actionRequest)
362                    throws Exception {
363    
364                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
365                    String title = ParamUtil.getString(actionRequest, "title");
366    
367                    WikiPageServiceUtil.unsubscribePage(nodeId, title);
368            }
369    
370            protected WikiPage updatePage(ActionRequest actionRequest)
371                    throws Exception {
372    
373                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
374    
375                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
376                    String title = ParamUtil.getString(actionRequest, "title");
377                    double version = ParamUtil.getDouble(actionRequest, "version");
378    
379                    String content = ParamUtil.getString(actionRequest, "content");
380                    String summary = ParamUtil.getString(actionRequest, "summary");
381                    boolean minorEdit = ParamUtil.getBoolean(actionRequest, "minorEdit");
382                    String format = ParamUtil.getString(actionRequest, "format");
383                    String parentTitle = ParamUtil.getString(actionRequest, "parentTitle");
384                    String redirectTitle = null;
385    
386                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
387                            WikiPage.class.getName(), actionRequest);
388    
389                    WikiPage page = null;
390    
391                    if (cmd.equals(Constants.ADD)) {
392                            page = WikiPageServiceUtil.addPage(
393                                    nodeId, title, content, summary, minorEdit, format, parentTitle,
394                                    redirectTitle, serviceContext);
395                    }
396                    else {
397                            page = WikiPageServiceUtil.updatePage(
398                                    nodeId, title, version, content, summary, minorEdit, format,
399                                    parentTitle, redirectTitle, serviceContext);
400                    }
401    
402                    return page;
403            }
404    
405            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
406    
407    }