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