001    /**
002     * Copyright (c) 2000-present 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.portal.comment.action;
016    
017    import com.liferay.portal.kernel.comment.Comment;
018    import com.liferay.portal.kernel.comment.CommentManagerUtil;
019    import com.liferay.portal.kernel.comment.DiscussionPermission;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
023    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
024    import com.liferay.portal.kernel.spring.osgi.OSGiBeanProperties;
025    import com.liferay.portal.kernel.struts.BaseStrutsAction;
026    import com.liferay.portal.kernel.struts.StrutsAction;
027    import com.liferay.portal.kernel.util.Constants;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.Function;
030    import com.liferay.portal.kernel.util.ParamUtil;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.util.WebKeys;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.model.User;
036    import com.liferay.portal.security.auth.PrincipalException;
037    import com.liferay.portal.security.auth.PrincipalThreadLocal;
038    import com.liferay.portal.service.ServiceContext;
039    import com.liferay.portal.service.ServiceContextFunction;
040    import com.liferay.portal.service.UserLocalServiceUtil;
041    import com.liferay.portal.servlet.NamespaceServletRequest;
042    import com.liferay.portal.theme.ThemeDisplay;
043    import com.liferay.portal.util.PortalUtil;
044    import com.liferay.portlet.messageboards.exception.DiscussionMaxCommentsException;
045    import com.liferay.portlet.messageboards.exception.MessageBodyException;
046    import com.liferay.portlet.messageboards.exception.NoSuchMessageException;
047    import com.liferay.portlet.messageboards.exception.RequiredMessageException;
048    
049    import java.io.IOException;
050    
051    import javax.servlet.http.HttpServletRequest;
052    import javax.servlet.http.HttpServletResponse;
053    
054    /**
055     * @author Adolfo P??rez
056     */
057    @OSGiBeanProperties(
058            property = "path=/portal/comment/edit_discussion",
059            service = StrutsAction.class
060    )
061    public class EditDiscussionStrutsAction extends BaseStrutsAction {
062    
063            @Override
064            public String execute(
065                            HttpServletRequest request, HttpServletResponse response)
066                    throws Exception {
067    
068                    String namespace = ParamUtil.getString(request, "namespace");
069    
070                    HttpServletRequest namespacedRequest = new NamespaceServletRequest(
071                            request, StringPool.BLANK, namespace);
072    
073                    String cmd = ParamUtil.getString(namespacedRequest, Constants.CMD);
074    
075                    try {
076                            String redirect = PortalUtil.escapeRedirect(
077                                    ParamUtil.getString(request, "redirect"));
078    
079                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
080                                    long commentId = updateComment(namespacedRequest);
081    
082                                    boolean ajax = ParamUtil.getBoolean(request, "ajax", true);
083    
084                                    if (ajax) {
085                                            String randomNamespace = ParamUtil.getString(
086                                                    namespacedRequest, "randomNamespace");
087    
088                                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
089    
090                                            jsonObject.put("commentId", commentId);
091                                            jsonObject.put("randomNamespace", randomNamespace);
092    
093                                            writeJSON(namespacedRequest, response, jsonObject);
094    
095                                            return null;
096                                    }
097                            }
098                            else if (cmd.equals(Constants.DELETE)) {
099                                    deleteComment(namespacedRequest);
100                            }
101                            else if (cmd.equals(Constants.SUBSCRIBE_TO_COMMENTS)) {
102                                    subscribeToComments(namespacedRequest, true);
103                            }
104                            else if (cmd.equals(Constants.UNSUBSCRIBE_FROM_COMMENTS)) {
105                                    subscribeToComments(namespacedRequest, false);
106                            }
107    
108                            if (Validator.isNotNull(redirect)) {
109                                    response.sendRedirect(redirect);
110                            }
111                    }
112                    catch (DiscussionMaxCommentsException | MessageBodyException |
113                               NoSuchMessageException | PrincipalException |
114                               RequiredMessageException e) {
115    
116                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
117    
118                            jsonObject.putException(e);
119    
120                            writeJSON(namespacedRequest, response, jsonObject);
121                    }
122    
123                    return null;
124            }
125    
126            protected void deleteComment(HttpServletRequest request) throws Exception {
127                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
128                            WebKeys.THEME_DISPLAY);
129    
130                    long commentId = ParamUtil.getLong(request, "commentId");
131    
132                    DiscussionPermission discussionPermission = getDiscussionPermission(
133                            themeDisplay);
134    
135                    discussionPermission.checkDeletePermission(commentId);
136    
137                    CommentManagerUtil.deleteComment(commentId);
138            }
139    
140            protected void subscribeToComments(
141                            HttpServletRequest request, boolean subscribe)
142                    throws Exception {
143    
144                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
145                            WebKeys.THEME_DISPLAY);
146    
147                    String className = ParamUtil.getString(request, "className");
148                    long classPK = ParamUtil.getLong(request, "classPK");
149    
150                    if (subscribe) {
151                            CommentManagerUtil.subscribeDiscussion(
152                                    themeDisplay.getUserId(), themeDisplay.getScopeGroupId(),
153                                    className, classPK);
154                    }
155                    else {
156                            CommentManagerUtil.unsubscribeDiscussion(
157                                    themeDisplay.getUserId(), className, classPK);
158                    }
159            }
160    
161            protected long updateComment(HttpServletRequest request) throws Exception {
162                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
163                            WebKeys.THEME_DISPLAY);
164    
165                    long commentId = ParamUtil.getLong(request, "commentId");
166    
167                    String className = ParamUtil.getString(request, "className");
168                    long classPK = ParamUtil.getLong(request, "classPK");
169                    long parentCommentId = ParamUtil.getLong(request, "parentCommentId");
170                    String subject = ParamUtil.getString(request, "subject");
171                    String body = ParamUtil.getString(request, "body");
172    
173                    Function<String, ServiceContext> serviceContextFunction =
174                            new ServiceContextFunction(request);
175    
176                    DiscussionPermission discussionPermission = getDiscussionPermission(
177                            themeDisplay);
178    
179                    if (commentId <= 0) {
180    
181                            // Add message
182    
183                            User user = null;
184    
185                            if (themeDisplay.isSignedIn()) {
186                                    user = themeDisplay.getUser();
187                            }
188                            else {
189                                    String emailAddress = ParamUtil.getString(
190                                            request, "emailAddress");
191    
192                                    user = UserLocalServiceUtil.fetchUserByEmailAddress(
193                                            themeDisplay.getCompanyId(), emailAddress);
194    
195                                    if ((user == null) ||
196                                            (user.getStatus() != WorkflowConstants.STATUS_INCOMPLETE)) {
197    
198                                            return 0;
199                                    }
200                            }
201    
202                            String name = PrincipalThreadLocal.getName();
203    
204                            PrincipalThreadLocal.setName(user.getUserId());
205    
206                            try {
207                                    discussionPermission.checkAddPermission(
208                                            themeDisplay.getCompanyId(), themeDisplay.getScopeGroupId(),
209                                            className, classPK);
210    
211                                    commentId = CommentManagerUtil.addComment(
212                                            user.getUserId(), className, classPK, user.getFullName(),
213                                            parentCommentId, subject, body, serviceContextFunction);
214                            }
215                            finally {
216                                    PrincipalThreadLocal.setName(name);
217                            }
218                    }
219                    else {
220    
221                            // Update message
222    
223                            if (Validator.isNull(className) || (classPK == 0)) {
224                                    Comment comment = CommentManagerUtil.fetchComment(commentId);
225    
226                                    if (comment != null) {
227                                            className = comment.getClassName();
228                                            classPK = comment.getClassPK();
229                                    }
230                            }
231    
232                            discussionPermission.checkUpdatePermission(commentId);
233    
234                            commentId = CommentManagerUtil.updateComment(
235                                    themeDisplay.getUserId(), className, classPK, commentId,
236                                    subject, body, serviceContextFunction);
237                    }
238    
239                    // Subscription
240    
241                    boolean subscribe = ParamUtil.getBoolean(request, "subscribe");
242    
243                    if (subscribe) {
244                            CommentManagerUtil.subscribeDiscussion(
245                                    themeDisplay.getUserId(), themeDisplay.getScopeGroupId(),
246                                    className, classPK);
247                    }
248    
249                    return commentId;
250            }
251    
252            protected void writeJSON(
253                            HttpServletRequest request, HttpServletResponse response,
254                            Object json)
255                    throws IOException {
256    
257                    String contentType = ContentTypes.APPLICATION_JSON;
258    
259                    if (BrowserSnifferUtil.isIe(request)) {
260                            contentType = ContentTypes.TEXT_HTML;
261                    }
262    
263                    response.setContentType(contentType);
264    
265                    ServletResponseUtil.write(response, json.toString());
266    
267                    response.flushBuffer();
268            }
269    
270            private DiscussionPermission getDiscussionPermission(
271                            ThemeDisplay themeDisplay)
272                    throws PrincipalException {
273    
274                    DiscussionPermission discussionPermission =
275                            CommentManagerUtil.getDiscussionPermission(
276                                    themeDisplay.getPermissionChecker());
277    
278                    if (discussionPermission == null) {
279                            throw new PrincipalException("Discussion permission is null");
280                    }
281    
282                    return discussionPermission;
283            }
284    
285    }