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.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.security.auth.PrincipalException;
025    import com.liferay.portal.service.ServiceContext;
026    import com.liferay.portal.service.ServiceContextFactory;
027    import com.liferay.portal.struts.PortletAction;
028    import com.liferay.portal.theme.ThemeDisplay;
029    import com.liferay.portal.util.WebKeys;
030    import com.liferay.portlet.wiki.DuplicateNodeNameException;
031    import com.liferay.portlet.wiki.NoSuchNodeException;
032    import com.liferay.portlet.wiki.NodeNameException;
033    import com.liferay.portlet.wiki.RequiredNodeException;
034    import com.liferay.portlet.wiki.model.WikiNode;
035    import com.liferay.portlet.wiki.service.WikiNodeLocalServiceUtil;
036    import com.liferay.portlet.wiki.service.WikiNodeServiceUtil;
037    import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
038    import com.liferay.portlet.wiki.util.WikiCacheUtil;
039    
040    import java.util.HashMap;
041    import java.util.Map;
042    
043    import javax.portlet.ActionRequest;
044    import javax.portlet.ActionResponse;
045    import javax.portlet.PortletConfig;
046    import javax.portlet.PortletPreferences;
047    import javax.portlet.RenderRequest;
048    import javax.portlet.RenderResponse;
049    
050    import org.apache.struts.action.ActionForm;
051    import org.apache.struts.action.ActionForward;
052    import org.apache.struts.action.ActionMapping;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     */
057    public class EditNodeAction extends PortletAction {
058    
059            @Override
060            public void processAction(
061                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
062                            ActionRequest actionRequest, ActionResponse actionResponse)
063                    throws Exception {
064    
065                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
066    
067                    try {
068                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
069                                    updateNode(actionRequest);
070                            }
071                            else if (cmd.equals(Constants.DELETE)) {
072                                    deleteNode(
073                                            (LiferayPortletConfig)portletConfig, actionRequest, false);
074                            }
075                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
076                                    deleteNode(
077                                            (LiferayPortletConfig)portletConfig, actionRequest, true);
078                            }
079                            else if (cmd.equals(Constants.RESTORE)) {
080                                    restoreNode(actionRequest);
081                            }
082                            else if (cmd.equals(Constants.SUBSCRIBE)) {
083                                    subscribeNode(actionRequest);
084                            }
085                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
086                                    unsubscribeNode(actionRequest);
087                            }
088    
089                            sendRedirect(actionRequest, actionResponse);
090                    }
091                    catch (Exception e) {
092                            if (e instanceof NoSuchNodeException ||
093                                    e instanceof PrincipalException) {
094    
095                                    SessionErrors.add(actionRequest, e.getClass());
096    
097                                    setForward(actionRequest, "portlet.wiki.error");
098                            }
099                            else if (e instanceof DuplicateNodeNameException ||
100                                             e instanceof NodeNameException) {
101    
102                                    SessionErrors.add(actionRequest, e.getClass());
103                            }
104                            else {
105                                    throw e;
106                            }
107                    }
108            }
109    
110            @Override
111            public ActionForward render(
112                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
113                            RenderRequest renderRequest, RenderResponse renderResponse)
114                    throws Exception {
115    
116                    try {
117                            long nodeId = ParamUtil.getLong(renderRequest, "nodeId");
118    
119                            if (nodeId > 0) {
120                                    ActionUtil.getNode(renderRequest);
121                            }
122                    }
123                    catch (Exception e) {
124                            if (e instanceof NoSuchNodeException ||
125                                    e instanceof PrincipalException) {
126    
127                                    SessionErrors.add(renderRequest, e.getClass());
128    
129                                    return mapping.findForward("portlet.wiki.error");
130                            }
131                            else {
132                                    throw e;
133                            }
134                    }
135    
136                    return mapping.findForward(
137                            getForward(renderRequest, "portlet.wiki.edit_node"));
138            }
139    
140            protected void deleteNode(
141                            LiferayPortletConfig liferayPortletConfig,
142                            ActionRequest actionRequest, boolean moveToTrash)
143                    throws Exception {
144    
145                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
146                            WebKeys.THEME_DISPLAY);
147    
148                    int nodeCount = WikiNodeLocalServiceUtil.getNodesCount(
149                            themeDisplay.getScopeGroupId());
150    
151                    if (nodeCount == 1) {
152                            SessionErrors.add(actionRequest, RequiredNodeException.class);
153    
154                            return;
155                    }
156    
157                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
158    
159                    String oldName = getNodeName(nodeId);
160    
161                    WikiCacheThreadLocal.setClearCache(false);
162    
163                    if (moveToTrash) {
164                            WikiNodeServiceUtil.moveNodeToTrash(nodeId);
165                    }
166                    else {
167                            WikiNodeServiceUtil.deleteNode(nodeId);
168                    }
169    
170                    WikiCacheUtil.clearCache(nodeId);
171    
172                    WikiCacheThreadLocal.setClearCache(true);
173    
174                    updatePreferences(actionRequest, oldName, StringPool.BLANK);
175    
176                    if (moveToTrash) {
177                            Map<String, String[]> data = new HashMap<String, String[]>();
178    
179                            data.put("restoreEntryIds", new String[] {String.valueOf(nodeId)});
180    
181                            SessionMessages.add(
182                                    actionRequest,
183                                    liferayPortletConfig.getPortletId() +
184                                            SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA, data);
185    
186                            SessionMessages.add(
187                                    actionRequest,
188                                    liferayPortletConfig.getPortletId() +
189                                            SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_SUCCESS_MESSAGE);
190                    }
191            }
192    
193            protected String getNodeName(long nodeId) throws Exception {
194                    WikiNode node = WikiNodeServiceUtil.getNode(nodeId);
195    
196                    return node.getName();
197            }
198    
199            protected void restoreNode(ActionRequest actionRequest) throws Exception {
200                    long[] restoreEntryIds = StringUtil.split(
201                            ParamUtil.getString(actionRequest, "restoreEntryIds"), 0L);
202    
203                    for (long restoreEntryId : restoreEntryIds) {
204                            WikiNodeServiceUtil.restoreNodeFromTrash(restoreEntryId);
205                    }
206            }
207    
208            protected void subscribeNode(ActionRequest actionRequest) throws Exception {
209                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
210    
211                    WikiNodeServiceUtil.subscribeNode(nodeId);
212            }
213    
214            protected void unsubscribeNode(ActionRequest actionRequest)
215                    throws Exception {
216    
217                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
218    
219                    WikiNodeServiceUtil.unsubscribeNode(nodeId);
220            }
221    
222            protected void updateNode(ActionRequest actionRequest) throws Exception {
223                    long nodeId = ParamUtil.getLong(actionRequest, "nodeId");
224    
225                    String name = ParamUtil.getString(actionRequest, "name");
226                    String description = ParamUtil.getString(actionRequest, "description");
227    
228                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
229                            WikiNode.class.getName(), actionRequest);
230    
231                    if (nodeId <= 0) {
232    
233                            // Add node
234    
235                            WikiNodeServiceUtil.addNode(name, description, serviceContext);
236                    }
237                    else {
238    
239                            // Update node
240    
241                            String oldName = getNodeName(nodeId);
242    
243                            WikiNodeServiceUtil.updateNode(
244                                    nodeId, name, description, serviceContext);
245    
246                            updatePreferences(actionRequest, oldName, name);
247                    }
248            }
249    
250            protected void updatePreferences(
251                            ActionRequest actionRequest, String oldName, String newName)
252                    throws Exception {
253    
254                    PortletPreferences preferences = actionRequest.getPreferences();
255    
256                    String hiddenNodes = preferences.getValue(
257                            "hiddenNodes", StringPool.BLANK);
258                    String visibleNodes = preferences.getValue(
259                            "visibleNodes", StringPool.BLANK);
260    
261                    String regex = oldName + ",?";
262    
263                    preferences.setValue(
264                            "hiddenNodes", hiddenNodes.replaceFirst(regex, newName));
265                    preferences.setValue(
266                            "visibleNodes",
267                            visibleNodes.replaceFirst(regex, newName));
268    
269                    preferences.store();
270            }
271    
272    }