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.sanitizer.SanitizerException;
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.PortalUtil;
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(actionRequest, false);
088                            }
089                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
090                                    deletePage(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                                             e instanceof SanitizerException) {
140    
141                                    SessionErrors.add(actionRequest, e.getClass());
142                            }
143                            else if (e instanceof AssetCategoryException ||
144                                             e instanceof AssetTagException) {
145    
146                                    SessionErrors.add(actionRequest, e.getClass(), e);
147                            }
148                            else {
149                                    Throwable cause = e.getCause();
150    
151                                    if (cause instanceof SanitizerException) {
152                                            SessionErrors.add(actionRequest, SanitizerException.class);
153                                    }
154                                    else {
155                                            throw e;
156                                    }
157                            }
158                    }
159            }
160    
161            @Override
162            public ActionForward render(
163                            ActionMapping actionMapping, ActionForm actionForm,
164                            PortletConfig portletConfig, RenderRequest renderRequest,
165                            RenderResponse renderResponse)
166                    throws Exception {
167    
168                    try {
169                            ActionUtil.getNode(renderRequest);
170    
171                            if (!SessionErrors.contains(
172                                            renderRequest, DuplicatePageException.class.getName())) {
173    
174                                    getPage(renderRequest);
175                            }
176                    }
177                    catch (Exception e) {
178                            if (e instanceof NoSuchNodeException ||
179                                    e instanceof PageTitleException ||
180                                    e instanceof PrincipalException) {
181    
182                                    SessionErrors.add(renderRequest, e.getClass());
183    
184                                    return actionMapping.findForward("portlet.wiki.error");
185                            }
186                            else if (e instanceof NoSuchPageException) {
187    
188                                    // Let edit_page.jsp handle this case
189    
190                            }
191                            else {
192                                    throw e;
193                            }
194                    }
195    
196                    return actionMapping.findForward(
197                            getForward(renderRequest, "portlet.wiki.edit_page"));
198            }
199    
200            protected void deletePage(ActionRequest actionRequest, boolean moveToTrash)
201                    throws Exception {
202    
203                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
204                    String title = ParamUtil.getString(actionRequest, "title");
205                    double version = ParamUtil.getDouble(actionRequest, "version");
206    
207                    WikiPage wikiPage = null;
208    
209                    if (moveToTrash) {
210                            if (version > 0) {
211                                    wikiPage = WikiPageServiceUtil.movePageToTrash(
212                                            nodeId, title, version);
213                            }
214                            else {
215                                    wikiPage = WikiPageServiceUtil.movePageToTrash(nodeId, title);
216                            }
217                    }
218                    else {
219                            if (version > 0) {
220                                    WikiPageServiceUtil.discardDraft(nodeId, title, version);
221                            }
222                            else {
223                                    WikiPageServiceUtil.deletePage(nodeId, title);
224                            }
225                    }
226    
227                    if (moveToTrash && (wikiPage != null)) {
228                            Map<String, String[]> data = new HashMap<String, String[]>();
229    
230                            data.put(
231                                    "deleteEntryClassName",
232                                    new String[] {WikiPage.class.getName()});
233                            data.put(
234                                    "deleteEntryTitle",
235                                    new String[] {TrashUtil.getOriginalTitle(wikiPage.getTitle())});
236                            data.put(
237                                    "restoreEntryIds",
238                                    new String[] {String.valueOf(wikiPage.getResourcePrimKey())});
239    
240                            SessionMessages.add(
241                                    actionRequest,
242                                    PortalUtil.getPortletId(actionRequest) +
243                                            SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA, data);
244    
245                            hideDefaultSuccessMessage(actionRequest);
246                    }
247            }
248    
249            protected void getPage(RenderRequest renderRequest) throws Exception {
250                    long nodeId = ParamUtil.getLong(renderRequest, "nodeId");
251                    String title = ParamUtil.getString(renderRequest, "title");
252                    double version = ParamUtil.getDouble(renderRequest, "version");
253                    boolean removeRedirect = ParamUtil.getBoolean(
254                            renderRequest, "removeRedirect");
255    
256                    if (nodeId == 0) {
257                            WikiNode node = (WikiNode)renderRequest.getAttribute(
258                                    WebKeys.WIKI_NODE);
259    
260                            if (node != null) {
261                                    nodeId = node.getNodeId();
262                            }
263                    }
264    
265                    WikiPage page = null;
266    
267                    if (Validator.isNull(title)) {
268                            renderRequest.setAttribute(WebKeys.WIKI_PAGE, page);
269    
270                            return;
271                    }
272    
273                    try {
274                            if (version == 0) {
275                                    page = WikiPageServiceUtil.getPage(nodeId, title, null);
276                            }
277                            else {
278                                    page = WikiPageServiceUtil.getPage(nodeId, title, version);
279                            }
280                    }
281                    catch (NoSuchPageException nspe1) {
282                            try {
283                                    page = WikiPageServiceUtil.getPage(nodeId, title, false);
284                            }
285                            catch (NoSuchPageException nspe2) {
286                                    if (title.equals(WikiPageConstants.FRONT_PAGE) &&
287                                            (version == 0)) {
288    
289                                            ServiceContext serviceContext = new ServiceContext();
290    
291                                            page = WikiPageServiceUtil.addPage(
292                                                    nodeId, title, null, WikiPageConstants.NEW, true,
293                                                    serviceContext);
294                                    }
295                                    else {
296                                            throw nspe2;
297                                    }
298                            }
299                    }
300    
301                    if (removeRedirect) {
302                            page.setContent(StringPool.BLANK);
303                            page.setRedirectTitle(StringPool.BLANK);
304                    }
305    
306                    renderRequest.setAttribute(WebKeys.WIKI_PAGE, page);
307            }
308    
309            protected String getSaveAndContinueRedirect(
310                            ActionRequest actionRequest, ActionResponse actionResponse,
311                            WikiPage page, String redirect)
312                    throws Exception {
313    
314                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
315                            WebKeys.THEME_DISPLAY);
316    
317                    Layout layout = themeDisplay.getLayout();
318    
319                    PortletURLImpl portletURL = new StrutsActionPortletURL(
320                            (PortletResponseImpl)actionResponse, themeDisplay.getPlid(),
321                            PortletRequest.RENDER_PHASE);
322    
323                    portletURL.setParameter("struts_action", "/wiki/edit_page");
324                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
325                    portletURL.setParameter("redirect", redirect, false);
326                    portletURL.setParameter(
327                            "groupId", String.valueOf(layout.getGroupId()), false);
328                    portletURL.setParameter(
329                            "nodeId", String.valueOf(page.getNodeId()), false);
330                    portletURL.setParameter("title", page.getTitle(), false);
331                    portletURL.setWindowState(actionRequest.getWindowState());
332    
333                    return portletURL.toString();
334            }
335    
336            @Override
337            protected boolean isCheckMethodOnProcessAction() {
338                    return _CHECK_METHOD_ON_PROCESS_ACTION;
339            }
340    
341            protected void restorePage(ActionRequest actionRequest) throws Exception {
342                    long[] restoreEntryIds = StringUtil.split(
343                            ParamUtil.getString(actionRequest, "restoreEntryIds"), 0L);
344    
345                    for (long restoreEntryId : restoreEntryIds) {
346                            WikiPageServiceUtil.restorePageFromTrash(restoreEntryId);
347                    }
348            }
349    
350            protected void revertPage(ActionRequest actionRequest) throws Exception {
351                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
352                    String title = ParamUtil.getString(actionRequest, "title");
353                    double version = ParamUtil.getDouble(actionRequest, "version");
354    
355                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
356                            WikiPage.class.getName(), actionRequest);
357    
358                    WikiPageServiceUtil.revertPage(nodeId, title, version, serviceContext);
359            }
360    
361            protected void subscribePage(ActionRequest actionRequest) throws Exception {
362                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
363                    String title = ParamUtil.getString(actionRequest, "title");
364    
365                    WikiPageServiceUtil.subscribePage(nodeId, title);
366            }
367    
368            protected void unsubscribePage(ActionRequest actionRequest)
369                    throws Exception {
370    
371                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
372                    String title = ParamUtil.getString(actionRequest, "title");
373    
374                    WikiPageServiceUtil.unsubscribePage(nodeId, title);
375            }
376    
377            protected WikiPage updatePage(ActionRequest actionRequest)
378                    throws Exception {
379    
380                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
381    
382                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
383                    String title = ParamUtil.getString(actionRequest, "title");
384                    double version = ParamUtil.getDouble(actionRequest, "version");
385    
386                    String content = ParamUtil.getString(actionRequest, "content");
387                    String summary = ParamUtil.getString(actionRequest, "summary");
388                    boolean minorEdit = ParamUtil.getBoolean(actionRequest, "minorEdit");
389                    String format = ParamUtil.getString(actionRequest, "format");
390                    String parentTitle = ParamUtil.getString(actionRequest, "parentTitle");
391                    String redirectTitle = null;
392                    boolean copyPageAttachments = ParamUtil.getBoolean(
393                            actionRequest, "copyPageAttachments");
394    
395                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
396                            WikiPage.class.getName(), actionRequest);
397    
398                    WikiPage page = null;
399    
400                    if (cmd.equals(Constants.UPDATE)) {
401                            page = WikiPageServiceUtil.updatePage(
402                                    nodeId, title, version, content, summary, minorEdit, format,
403                                    parentTitle, redirectTitle, serviceContext);
404                    }
405                    else {
406                            page = WikiPageServiceUtil.addPage(
407                                    nodeId, title, content, summary, minorEdit, format, parentTitle,
408                                    redirectTitle, serviceContext);
409    
410                            if (copyPageAttachments) {
411                                    long templateNodeId = ParamUtil.getLong(
412                                            actionRequest, "templateNodeId");
413                                    String templateTitle = ParamUtil.getString(
414                                            actionRequest, "templateTitle");
415    
416                                    WikiPageServiceUtil.copyPageAttachments(
417                                            templateNodeId, templateTitle, page.getNodeId(),
418                                            page.getTitle());
419                            }
420                    }
421    
422                    return page;
423            }
424    
425            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
426    
427    }