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.portlet.social.model;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.json.JSONException;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
024    import com.liferay.portal.kernel.trash.TrashHandler;
025    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
026    import com.liferay.portal.kernel.util.HtmlUtil;
027    import com.liferay.portal.kernel.util.HttpUtil;
028    import com.liferay.portal.kernel.util.StringBundler;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.StringUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.model.User;
034    import com.liferay.portal.security.permission.ActionKeys;
035    import com.liferay.portal.security.permission.PermissionChecker;
036    import com.liferay.portal.service.GroupLocalServiceUtil;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portal.service.UserLocalServiceUtil;
039    import com.liferay.portal.theme.ThemeDisplay;
040    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
041    import com.liferay.portlet.asset.model.AssetRenderer;
042    import com.liferay.portlet.asset.model.AssetRendererFactory;
043    import com.liferay.portlet.social.service.SocialActivityLocalServiceUtil;
044    import com.liferay.portlet.social.service.SocialActivitySetLocalServiceUtil;
045    import com.liferay.portlet.social.service.persistence.SocialActivityUtil;
046    import com.liferay.portlet.trash.util.TrashUtil;
047    
048    import java.util.List;
049    
050    import javax.portlet.PortletURL;
051    import javax.portlet.WindowState;
052    
053    /**
054     * @author Brian Wing Shun Chan
055     * @author Ryan Park
056     */
057    public abstract class BaseSocialActivityInterpreter
058            implements SocialActivityInterpreter {
059    
060            @Override
061            public String getSelector() {
062                    return StringPool.BLANK;
063            }
064    
065            @Override
066            public boolean hasPermission(
067                            PermissionChecker permissionChecker, SocialActivity activity,
068                            String actionId, ServiceContext serviceContext)
069                    throws Exception {
070    
071                    return hasPermissions(
072                            permissionChecker, activity, actionId, serviceContext);
073            }
074    
075            @Override
076            public SocialActivityFeedEntry interpret(
077                    SocialActivity activity, ServiceContext serviceContext) {
078    
079                    try {
080                            return doInterpret(activity, serviceContext);
081                    }
082                    catch (Exception e) {
083                            _log.error("Unable to interpret activity", e);
084                    }
085    
086                    return null;
087            }
088    
089            @Override
090            public SocialActivityFeedEntry interpret(
091                    SocialActivitySet activitySet, ServiceContext serviceContext) {
092    
093                    try {
094                            return doInterpret(activitySet, serviceContext);
095                    }
096                    catch (Exception e) {
097                            _log.error("Unable to interpret activity set", e);
098                    }
099    
100                    return null;
101            }
102    
103            @Override
104            public void updateActivitySet(long activityId) throws PortalException {
105                    SocialActivity activity = SocialActivityUtil.fetchByPrimaryKey(
106                            activityId);
107    
108                    if ((activity == null) || (activity.getActivitySetId() > 0)) {
109                            return;
110                    }
111    
112                    long activitySetId = getActivitySetId(activityId);
113    
114                    if (activitySetId > 0) {
115                            SocialActivitySetLocalServiceUtil.incrementActivityCount(
116                                    activitySetId, activityId);
117                    }
118                    else {
119                            SocialActivitySetLocalServiceUtil.addActivitySet(activityId);
120                    }
121            }
122    
123            protected String addNoSuchEntryRedirect(
124                            String url, String className, long classPK,
125                            ServiceContext serviceContext)
126                    throws Exception {
127    
128                    String viewEntryURL = getViewEntryURL(
129                            className, classPK, serviceContext);
130    
131                    if (Validator.isNotNull(viewEntryURL)) {
132                            return viewEntryURL;
133                    }
134    
135                    return HttpUtil.setParameter(url, "noSuchEntryRedirect", viewEntryURL);
136            }
137    
138            protected String buildLink(String link, String text) {
139                    StringBundler sb = new StringBundler(5);
140    
141                    sb.append("<a href=\"");
142                    sb.append(link);
143                    sb.append("\">");
144                    sb.append(text);
145                    sb.append("</a>");
146    
147                    return sb.toString();
148            }
149    
150            /**
151             * @deprecated As of 6.2.0
152             */
153            @Deprecated
154            protected String cleanContent(String content) {
155                    return StringUtil.shorten(HtmlUtil.extractText(content), 200);
156            }
157    
158            protected SocialActivityFeedEntry doInterpret(
159                            SocialActivity activity, ServiceContext serviceContext)
160                    throws Exception {
161    
162                    ThemeDisplay themeDisplay = serviceContext.getThemeDisplay();
163    
164                    SocialActivityFeedEntry socialActivityFeedEntry = doInterpret(
165                            activity, themeDisplay);
166    
167                    if (socialActivityFeedEntry !=
168                                    _deprecatedMarkerSocialActivityFeedEntry) {
169    
170                            return socialActivityFeedEntry;
171                    }
172    
173                    PermissionChecker permissionChecker =
174                            themeDisplay.getPermissionChecker();
175    
176                    if (!hasPermissions(
177                                    permissionChecker, activity, ActionKeys.VIEW, serviceContext)) {
178    
179                            return null;
180                    }
181    
182                    String link = getLink(activity, serviceContext);
183    
184                    String title = getTitle(activity, serviceContext);
185    
186                    if (Validator.isNull(title)) {
187                            return null;
188                    }
189    
190                    String body = getBody(activity, serviceContext);
191    
192                    return new SocialActivityFeedEntry(link, title, body);
193            }
194    
195            /**
196             * @deprecated As of 6.2.0
197             */
198            @Deprecated
199            protected SocialActivityFeedEntry doInterpret(
200                            SocialActivity activity, ThemeDisplay themeDisplay)
201                    throws Exception {
202    
203                    return _deprecatedMarkerSocialActivityFeedEntry;
204            }
205    
206            protected SocialActivityFeedEntry doInterpret(
207                            SocialActivitySet activitySet, ServiceContext serviceContext)
208                    throws Exception {
209    
210                    List<SocialActivity> activities =
211                            SocialActivityLocalServiceUtil.getActivitySetActivities(
212                                    activitySet.getActivitySetId(), 0, 1);
213    
214                    if (!activities.isEmpty()) {
215                            SocialActivity activity = activities.get(0);
216    
217                            return doInterpret(activity, serviceContext);
218                    }
219    
220                    return null;
221            }
222    
223            protected long getActivitySetId(long activityId) {
224                    return 0;
225            }
226    
227            protected String getBody(
228                            SocialActivity activity, ServiceContext serviceContext)
229                    throws Exception {
230    
231                    return StringPool.BLANK;
232            }
233    
234            protected String getEntryTitle(
235                            SocialActivity activity, ServiceContext serviceContext)
236                    throws Exception {
237    
238                    return activity.getExtraDataValue("title", serviceContext.getLocale());
239            }
240    
241            protected String getGroupName(long groupId, ServiceContext serviceContext) {
242                    try {
243                            if (groupId <= 0) {
244                                    return StringPool.BLANK;
245                            }
246    
247                            Group group = GroupLocalServiceUtil.getGroup(groupId);
248    
249                            String groupName = group.getDescriptiveName();
250    
251                            if (group.getGroupId() == serviceContext.getScopeGroupId()) {
252                                    return HtmlUtil.escape(groupName);
253                            }
254    
255                            String groupDisplayURL = StringPool.BLANK;
256    
257                            if (group.hasPublicLayouts()) {
258                                    groupDisplayURL = group.getDisplayURL(
259                                            serviceContext.getThemeDisplay(), false);
260                            }
261                            else if (group.hasPrivateLayouts()) {
262                                    groupDisplayURL = group.getDisplayURL(
263                                            serviceContext.getThemeDisplay(), true);
264                            }
265                            else {
266                                    return HtmlUtil.escape(groupName);
267                            }
268    
269                            groupName =
270                                    "<a class=\"group\" href=\"" + groupDisplayURL + "\">" +
271                                            HtmlUtil.escape(groupName) + "</a>";
272    
273                            return groupName;
274                    }
275                    catch (Exception e) {
276                            return StringPool.BLANK;
277                    }
278            }
279    
280            /**
281             * @deprecated As of 6.2.0, replaced by {@link #getGroupName(long,
282             *             ServiceContext)}
283             */
284            @Deprecated
285            protected String getGroupName(long groupId, ThemeDisplay themeDisplay) {
286                    try {
287                            if (groupId <= 0) {
288                                    return StringPool.BLANK;
289                            }
290    
291                            Group group = GroupLocalServiceUtil.getGroup(groupId);
292    
293                            String groupName = group.getDescriptiveName();
294    
295                            if (group.getGroupId() == themeDisplay.getScopeGroupId()) {
296                                    return HtmlUtil.escape(groupName);
297                            }
298    
299                            String groupDisplayURL = StringPool.BLANK;
300    
301                            if (group.hasPublicLayouts()) {
302                                    groupDisplayURL = group.getDisplayURL(themeDisplay, false);
303                            }
304                            else if (group.hasPrivateLayouts()) {
305                                    groupDisplayURL = group.getDisplayURL(themeDisplay, true);
306                            }
307                            else {
308                                    return HtmlUtil.escape(groupName);
309                            }
310    
311                            groupName =
312                                    "<a class=\"group\" href=\"" + groupDisplayURL + "\">" +
313                                            HtmlUtil.escape(groupName) + "</a>";
314    
315                            return groupName;
316                    }
317                    catch (Exception e) {
318                            return StringPool.BLANK;
319                    }
320            }
321    
322            protected String getJSONValue(String json, String key) {
323                    return getJSONValue(json, key, StringPool.BLANK);
324            }
325    
326            protected String getJSONValue(
327                    String json, String key, String defaultValue) {
328    
329                    if (Validator.isNull(json)) {
330                            return defaultValue;
331                    }
332    
333                    try {
334                            JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
335                                    json);
336    
337                            String value = extraDataJSONObject.getString(key);
338    
339                            if (Validator.isNotNull(value)) {
340                                    return value;
341                            }
342                    }
343                    catch (JSONException jsone) {
344                            _log.error("Unable to create a JSON object from " + json);
345                    }
346    
347                    return defaultValue;
348            }
349    
350            protected String getLink(
351                            SocialActivity activity, ServiceContext serviceContext)
352                    throws Exception {
353    
354                    String className = activity.getClassName();
355                    long classPK = activity.getClassPK();
356    
357                    String viewEntryInTrashURL = getViewEntryInTrashURL(
358                            className, classPK, serviceContext);
359    
360                    if (viewEntryInTrashURL != null) {
361                            return viewEntryInTrashURL;
362                    }
363    
364                    String path = getPath(activity, serviceContext);
365    
366                    if (Validator.isNull(path)) {
367                            return null;
368                    }
369    
370                    path = addNoSuchEntryRedirect(path, className, classPK, serviceContext);
371    
372                    if (!path.startsWith(StringPool.SLASH)) {
373                            return path;
374                    }
375    
376                    return serviceContext.getPortalURL() + serviceContext.getPathMain() +
377                            path;
378            }
379    
380            protected String getPath(
381                            SocialActivity activity, ServiceContext serviceContext)
382                    throws Exception {
383    
384                    return StringPool.BLANK;
385            }
386    
387            protected String getTitle(
388                            SocialActivity activity, ServiceContext serviceContext)
389                    throws Exception {
390    
391                    String groupName = StringPool.BLANK;
392    
393                    if (activity.getGroupId() != serviceContext.getScopeGroupId()) {
394                            groupName = getGroupName(activity.getGroupId(), serviceContext);
395                    }
396    
397                    String titlePattern = getTitlePattern(groupName, activity);
398    
399                    if (Validator.isNull(titlePattern)) {
400                            return null;
401                    }
402    
403                    String link = getLink(activity, serviceContext);
404    
405                    String entryTitle = getEntryTitle(activity, serviceContext);
406    
407                    Object[] titleArguments = getTitleArguments(
408                            groupName, activity, link, entryTitle, serviceContext);
409    
410                    return serviceContext.translate(titlePattern, titleArguments);
411            }
412    
413            protected Object[] getTitleArguments(
414                            String groupName, SocialActivity activity, String link,
415                            String title, ServiceContext serviceContext)
416                    throws Exception {
417    
418                    String userName = getUserName(activity.getUserId(), serviceContext);
419    
420                    return new Object[] {groupName, userName, wrapLink(link, title)};
421            }
422    
423            protected String getTitlePattern(String groupName, SocialActivity activity)
424                    throws Exception {
425    
426                    return StringPool.BLANK;
427            }
428    
429            protected String getUserName(long userId, ServiceContext serviceContext) {
430                    try {
431                            if (userId <= 0) {
432                                    return StringPool.BLANK;
433                            }
434    
435                            User user = UserLocalServiceUtil.getUserById(userId);
436    
437                            if (user.getUserId() == serviceContext.getUserId()) {
438                                    return HtmlUtil.escape(user.getFirstName());
439                            }
440    
441                            String userName = user.getFullName();
442    
443                            Group group = user.getGroup();
444    
445                            if (group.getGroupId() == serviceContext.getScopeGroupId()) {
446                                    return HtmlUtil.escape(userName);
447                            }
448    
449                            String userDisplayURL = user.getDisplayURL(
450                                    serviceContext.getThemeDisplay());
451    
452                            userName =
453                                    "<a class=\"user\" href=\"" + userDisplayURL + "\">" +
454                                            HtmlUtil.escape(userName) + "</a>";
455    
456                            return userName;
457                    }
458                    catch (Exception e) {
459                            return StringPool.BLANK;
460                    }
461            }
462    
463            /**
464             * @deprecated As of 6.2.0, replaced by {@link #getUserName(long,
465             *             ServiceContext)}
466             */
467            @Deprecated
468            protected String getUserName(long userId, ThemeDisplay themeDisplay) {
469                    try {
470                            if (userId <= 0) {
471                                    return StringPool.BLANK;
472                            }
473    
474                            User user = UserLocalServiceUtil.getUserById(userId);
475    
476                            if (user.getUserId() == themeDisplay.getUserId()) {
477                                    return HtmlUtil.escape(user.getFirstName());
478                            }
479    
480                            String userName = user.getFullName();
481    
482                            Group group = user.getGroup();
483    
484                            if (group.getGroupId() == themeDisplay.getScopeGroupId()) {
485                                    return HtmlUtil.escape(userName);
486                            }
487    
488                            String userDisplayURL = user.getDisplayURL(themeDisplay);
489    
490                            userName =
491                                    "<a class=\"user\" href=\"" + userDisplayURL + "\">" +
492                                            HtmlUtil.escape(userName) + "</a>";
493    
494                            return userName;
495                    }
496                    catch (Exception e) {
497                            return StringPool.BLANK;
498                    }
499            }
500    
501            /**
502             * @deprecated As of 6.2.0, replaced by {@link #getJSONValue(String, String,
503             *             String)}
504             */
505            @Deprecated
506            protected String getValue(String json, String key, String defaultValue) {
507                    return getJSONValue(json, key, defaultValue);
508            }
509    
510            protected String getViewEntryInTrashURL(
511                            String className, long classPK, ServiceContext serviceContext)
512                    throws Exception {
513    
514                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
515                            className);
516    
517                    if ((trashHandler != null) && trashHandler.isInTrash(classPK)) {
518                            PortletURL portletURL = TrashUtil.getViewContentURL(
519                                    serviceContext.getRequest(), className, classPK);
520    
521                            if (portletURL == null) {
522                                    return null;
523                            }
524    
525                            return portletURL.toString();
526                    }
527    
528                    return null;
529            }
530    
531            protected String getViewEntryURL(
532                            String className, long classPK, ServiceContext serviceContext)
533                    throws Exception {
534    
535                    AssetRendererFactory<?> assetRendererFactory =
536                            AssetRendererFactoryRegistryUtil.getAssetRendererFactoryByClassName(
537                                    className);
538    
539                    if (assetRendererFactory == null) {
540                            return null;
541                    }
542    
543                    LiferayPortletResponse liferayPortletResponse =
544                            serviceContext.getLiferayPortletResponse();
545    
546                    if (liferayPortletResponse == null) {
547                            return null;
548                    }
549    
550                    if (classPK == 0) {
551                            PortletURL portletURL = assetRendererFactory.getURLView(
552                                    liferayPortletResponse, WindowState.MAXIMIZED);
553    
554                            return portletURL.toString();
555                    }
556    
557                    AssetRenderer<?> assetRenderer = assetRendererFactory.getAssetRenderer(
558                            classPK);
559    
560                    if (assetRenderer == null) {
561                            return null;
562                    }
563    
564                    return assetRenderer.getURLView(
565                            liferayPortletResponse, WindowState.MAXIMIZED);
566            }
567    
568            protected boolean hasPermissions(
569                            PermissionChecker permissionChecker, SocialActivity activity,
570                            String actionId, ServiceContext serviceContext)
571                    throws Exception {
572    
573                    return false;
574            }
575    
576            protected String wrapLink(String link, String title) {
577                    title = HtmlUtil.escape(title);
578    
579                    if (link == null) {
580                            return title;
581                    }
582    
583                    return buildLink(link, title);
584            }
585    
586            protected String wrapLink(
587                    String link, String key, ServiceContext serviceContext) {
588    
589                    String title = serviceContext.translate(HtmlUtil.escape(key));
590    
591                    if (link == null) {
592                            return title;
593                    }
594    
595                    return buildLink(link, title);
596            }
597    
598            private static final Log _log = LogFactoryUtil.getLog(
599                    BaseSocialActivityInterpreter.class);
600    
601            private final SocialActivityFeedEntry
602                    _deprecatedMarkerSocialActivityFeedEntry = new SocialActivityFeedEntry(
603                            StringPool.BLANK, StringPool.BLANK);
604    
605    }