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