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