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.WikiPageLocalServiceUtil;
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 mapping, ActionForm form, PortletConfig portletConfig,
074                            ActionRequest actionRequest, 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 mapping, ActionForm form, PortletConfig portletConfig,
165                            RenderRequest renderRequest, 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 mapping.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 mapping.findForward(
197                            getForward(renderRequest, "portlet.wiki.edit_page"));
198            }
199    
200            protected void deletePage(
201                            LiferayPortletConfig liferayPortletConfig,
202                            ActionRequest actionRequest, boolean moveToTrash)
203                    throws Exception {
204    
205                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
206                    String title = ParamUtil.getString(actionRequest, "title");
207                    double version = ParamUtil.getDouble(actionRequest, "version");
208    
209                    WikiPage wikiPage = null;
210    
211                    if (moveToTrash) {
212                            if (version > 0) {
213                                    wikiPage = WikiPageLocalServiceUtil.getPage(
214                                            nodeId, title, version);
215    
216                                    WikiPageServiceUtil.movePageToTrash(nodeId, title, version);
217                            }
218                            else {
219                                    wikiPage = WikiPageLocalServiceUtil.getPage(nodeId, title);
220    
221                                    WikiPageServiceUtil.movePageToTrash(nodeId, title);
222                            }
223                    }
224                    else {
225                            if (version > 0) {
226                                    WikiPageServiceUtil.discardDraft(nodeId, title, version);
227                            }
228                            else {
229                                    WikiPageServiceUtil.deletePage(nodeId, title);
230                            }
231                    }
232    
233                    if (moveToTrash) {
234                            Map<String, String[]> data = new HashMap<String, String[]>();
235    
236                            data.put(
237                                    "restoreEntryIds",
238                                    new String[] {String.valueOf(wikiPage.getResourcePrimKey())});
239    
240                            SessionMessages.add(
241                                    actionRequest,
242                                    liferayPortletConfig.getPortletId() +
243                                            SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA, data);
244    
245                            SessionMessages.add(
246                                    actionRequest,
247                                    liferayPortletConfig.getPortletId() +
248                                            SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_SUCCESS_MESSAGE);
249                    }
250            }
251    
252            protected void getPage(RenderRequest renderRequest) throws Exception {
253                    long nodeId = ParamUtil.getLong(renderRequest, "nodeId");
254                    String title = ParamUtil.getString(renderRequest, "title");
255                    double version = ParamUtil.getDouble(renderRequest, "version");
256                    boolean removeRedirect = ParamUtil.getBoolean(
257                            renderRequest, "removeRedirect");
258    
259                    if (nodeId == 0) {
260                            WikiNode node = (WikiNode)renderRequest.getAttribute(
261                                    WebKeys.WIKI_NODE);
262    
263                            if (node != null) {
264                                    nodeId = node.getNodeId();
265                            }
266                    }
267    
268                    WikiPage page = null;
269    
270                    if (Validator.isNotNull(title)) {
271                            try {
272                                    if (version == 0) {
273                                            page = WikiPageServiceUtil.getPage(nodeId, title, null);
274                                    }
275                                    else {
276                                            page = WikiPageServiceUtil.getPage(nodeId, title, version);
277                                    }
278                            }
279                            catch (NoSuchPageException nspe1) {
280                                    try {
281                                            page = WikiPageServiceUtil.getPage(nodeId, title, false);
282                                    }
283                                    catch (NoSuchPageException nspe2) {
284                                            if (title.equals(WikiPageConstants.FRONT_PAGE) &&
285                                                    (version == 0)) {
286    
287                                                    ServiceContext serviceContext = new ServiceContext();
288    
289                                                    page = WikiPageServiceUtil.addPage(
290                                                            nodeId, title, null, WikiPageConstants.NEW, true,
291                                                            serviceContext);
292                                            }
293                                            else {
294                                                    throw nspe2;
295                                            }
296                                    }
297                            }
298    
299                            if (removeRedirect) {
300                                    page.setContent(StringPool.BLANK);
301                                    page.setRedirectTitle(StringPool.BLANK);
302                            }
303                    }
304    
305                    renderRequest.setAttribute(WebKeys.WIKI_PAGE, page);
306            }
307    
308            protected String getSaveAndContinueRedirect(
309                            ActionRequest actionRequest, ActionResponse actionResponse,
310                            WikiPage page, String redirect)
311                    throws Exception {
312    
313                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
314                            WebKeys.THEME_DISPLAY);
315    
316                    Layout layout = themeDisplay.getLayout();
317    
318                    String originalRedirect = ParamUtil.getString(
319                            actionRequest, "originalRedirect");
320    
321                    PortletURLImpl portletURL = new StrutsActionPortletURL(
322                            (PortletResponseImpl)actionResponse, themeDisplay.getPlid(),
323                            PortletRequest.RENDER_PHASE);
324    
325                    portletURL.setParameter("struts_action", "/wiki/edit_page");
326                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
327                    portletURL.setParameter("redirect", redirect, false);
328                    portletURL.setParameter("originalRedirect", originalRedirect, false);
329                    portletURL.setParameter(
330                            "groupId", String.valueOf(layout.getGroupId()), false);
331                    portletURL.setParameter(
332                            "nodeId", String.valueOf(page.getNodeId()), false);
333                    portletURL.setParameter("title", page.getTitle(), false);
334                    portletURL.setWindowState(actionRequest.getWindowState());
335    
336                    return portletURL.toString();
337            }
338    
339            @Override
340            protected boolean isCheckMethodOnProcessAction() {
341                    return _CHECK_METHOD_ON_PROCESS_ACTION;
342            }
343    
344            protected void restorePage(ActionRequest actionRequest) throws Exception {
345                    long[] restoreEntryIds = StringUtil.split(
346                            ParamUtil.getString(actionRequest, "restoreEntryIds"), 0L);
347    
348                    for (long restoreEntryId : restoreEntryIds) {
349                            WikiPageServiceUtil.restorePageFromTrash(restoreEntryId);
350                    }
351            }
352    
353            protected void revertPage(ActionRequest actionRequest) throws Exception {
354                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
355                    String title = ParamUtil.getString(actionRequest, "title");
356                    double version = ParamUtil.getDouble(actionRequest, "version");
357    
358                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
359                            WikiPage.class.getName(), actionRequest);
360    
361                    WikiPageServiceUtil.revertPage(nodeId, title, version, serviceContext);
362            }
363    
364            protected void subscribePage(ActionRequest actionRequest) throws Exception {
365                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
366                    String title = ParamUtil.getString(actionRequest, "title");
367    
368                    WikiPageServiceUtil.subscribePage(nodeId, title);
369            }
370    
371            protected void unsubscribePage(ActionRequest actionRequest)
372                    throws Exception {
373    
374                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
375                    String title = ParamUtil.getString(actionRequest, "title");
376    
377                    WikiPageServiceUtil.unsubscribePage(nodeId, title);
378            }
379    
380            protected WikiPage updatePage(ActionRequest actionRequest)
381                    throws Exception {
382    
383                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
384    
385                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
386                    String title = ParamUtil.getString(actionRequest, "title");
387                    double version = ParamUtil.getDouble(actionRequest, "version");
388    
389                    String content = ParamUtil.getString(actionRequest, "content");
390                    String summary = ParamUtil.getString(actionRequest, "summary");
391                    boolean minorEdit = ParamUtil.getBoolean(actionRequest, "minorEdit");
392                    String format = ParamUtil.getString(actionRequest, "format");
393                    String parentTitle = ParamUtil.getString(actionRequest, "parentTitle");
394                    String redirectTitle = null;
395    
396                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
397                            WikiPage.class.getName(), actionRequest);
398    
399                    WikiPage page = null;
400    
401                    if (cmd.equals(Constants.ADD)) {
402                            page = WikiPageServiceUtil.addPage(
403                                    nodeId, title, content, summary, minorEdit, format, parentTitle,
404                                    redirectTitle, serviceContext);
405                    }
406                    else {
407                            page = WikiPageServiceUtil.updatePage(
408                                    nodeId, title, version, content, summary, minorEdit, format,
409                                    parentTitle, redirectTitle, serviceContext);
410                    }
411    
412                    return page;
413            }
414    
415            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
416    
417    }