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