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.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.service.ServiceContext;
021    import com.liferay.portal.kernel.theme.ThemeDisplay;
022    import com.liferay.portal.kernel.util.PortalUtil;
023    import com.liferay.portal.kernel.util.WebKeys;
024    import com.liferay.portal.util.PropsValues;
025    import com.liferay.portlet.social.service.base.SocialActivityInterpreterLocalServiceBaseImpl;
026    import com.liferay.registry.Filter;
027    import com.liferay.registry.Registry;
028    import com.liferay.registry.RegistryUtil;
029    import com.liferay.registry.ServiceReference;
030    import com.liferay.registry.ServiceRegistration;
031    import com.liferay.registry.ServiceTracker;
032    import com.liferay.registry.ServiceTrackerCustomizer;
033    import com.liferay.registry.collections.ServiceRegistrationMap;
034    import com.liferay.registry.collections.ServiceRegistrationMapImpl;
035    import com.liferay.social.kernel.model.SocialActivity;
036    import com.liferay.social.kernel.model.SocialActivityFeedEntry;
037    import com.liferay.social.kernel.model.SocialActivityInterpreter;
038    import com.liferay.social.kernel.model.SocialActivitySet;
039    import com.liferay.social.kernel.model.impl.SocialActivityInterpreterImpl;
040    import com.liferay.social.kernel.model.impl.SocialRequestInterpreterImpl;
041    
042    import java.util.ArrayList;
043    import java.util.HashMap;
044    import java.util.List;
045    import java.util.Map;
046    
047    import javax.servlet.http.HttpServletRequest;
048    
049    /**
050     * The social activity interpreter local service. Activity interpreters are
051     * classes responsible for translating activity records into human readable
052     * form. This service holds a list of interpreters and provides methods to add
053     * or remove items from this list.
054     *
055     * <p>
056     * Activity interpreters use the language files to get text fragments based on
057     * the activity's type and the type of asset on which the activity was done.
058     * Interpreters are created for specific asset types and are only capable of
059     * translating activities done on assets of those types. As an example, there is
060     * an interpreter BlogsActivityInterpreter that can only translate activity
061     * records for blog entries.
062     * </p>
063     *
064     * @author Brian Wing Shun Chan
065     */
066    public class SocialActivityInterpreterLocalServiceImpl
067            extends SocialActivityInterpreterLocalServiceBaseImpl {
068    
069            /**
070             * Adds the activity interpreter to the list of available interpreters.
071             *
072             * @param activityInterpreter the activity interpreter
073             */
074            @Override
075            public void addActivityInterpreter(
076                    SocialActivityInterpreter activityInterpreter) {
077    
078                    Registry registry = RegistryUtil.getRegistry();
079    
080                    Map<String, Object> properties = new HashMap<>();
081    
082                    SocialActivityInterpreterImpl activityInterpreterImpl =
083                            (SocialActivityInterpreterImpl)activityInterpreter;
084    
085                    properties.put(
086                            "javax.portlet.name", activityInterpreterImpl.getPortletId());
087    
088                    ServiceRegistration<SocialActivityInterpreter> serviceRegistration =
089                            registry.registerService(
090                                    SocialActivityInterpreter.class, activityInterpreter,
091                                    properties);
092    
093                    _serviceRegistrations.put(activityInterpreter, serviceRegistration);
094            }
095    
096            @Override
097            public void afterPropertiesSet() {
098                    Registry registry = RegistryUtil.getRegistry();
099    
100                    Filter filter = registry.getFilter(
101                            "(&(javax.portlet.name=*)(objectClass=" +
102                                    SocialActivityInterpreter.class.getName() + "))");
103    
104                    _serviceTracker = registry.trackServices(
105                            filter, new SocialActivityInterpreterServiceTrackerCustomizer());
106    
107                    _serviceTracker.open();
108            }
109    
110            /**
111             * Removes the activity interpreter from the list of available interpreters.
112             *
113             * @param activityInterpreter the activity interpreter
114             */
115            @Override
116            public void deleteActivityInterpreter(
117                    SocialActivityInterpreter activityInterpreter) {
118    
119                    ServiceRegistration<SocialActivityInterpreter> serviceRegistration =
120                            _serviceRegistrations.remove(activityInterpreter);
121    
122                    if (serviceRegistration != null) {
123                            serviceRegistration.unregister();
124                    }
125            }
126    
127            @Override
128            public Map<String, List<SocialActivityInterpreter>>
129                    getActivityInterpreters() {
130    
131                    return _activityInterpreters;
132            }
133    
134            @Override
135            public List<SocialActivityInterpreter> getActivityInterpreters(
136                    String selector) {
137    
138                    return _activityInterpreters.get(selector);
139            }
140    
141            /**
142             * Creates a human readable activity feed entry for the activity using an
143             * available compatible activity interpreter.
144             *
145             * <p>
146             * This method finds the appropriate interpreter for the activity by going
147             * through the available interpreters and asking them if they can handle the
148             * asset type of the activity.
149             * </p>
150             *
151             * @param  selector the context in which the activity interpreter is used
152             * @param  activity the activity to be translated to human readable form
153             * @param  serviceContext the service context to be applied
154             * @return the activity feed that is a human readable form of the activity
155             *         record or <code>null</code> if a compatible interpreter is not
156             *         found
157             */
158            @Override
159            public SocialActivityFeedEntry interpret(
160                    String selector, SocialActivity activity,
161                    ServiceContext serviceContext) {
162    
163                    HttpServletRequest request = serviceContext.getRequest();
164    
165                    if (request == null) {
166                            return null;
167                    }
168    
169                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
170                            WebKeys.THEME_DISPLAY);
171    
172                    try {
173                            if (activity.getUserId() == themeDisplay.getDefaultUserId()) {
174                                    return null;
175                            }
176                    }
177                    catch (Exception e) {
178                            _log.error(e, e);
179                    }
180    
181                    if (activity.getMirrorActivityId() > 0) {
182                            SocialActivity mirrorActivity = null;
183    
184                            try {
185                                    mirrorActivity = socialActivityLocalService.getActivity(
186                                            activity.getMirrorActivityId());
187                            }
188                            catch (Exception e) {
189                            }
190    
191                            if (mirrorActivity != null) {
192                                    activity = mirrorActivity;
193                            }
194                    }
195    
196                    List<SocialActivityInterpreter> activityInterpreters =
197                            _activityInterpreters.get(selector);
198    
199                    if (activityInterpreters == null) {
200                            return null;
201                    }
202    
203                    String className = PortalUtil.getClassName(activity.getClassNameId());
204    
205                    for (int i = 0; i < activityInterpreters.size(); i++) {
206                            SocialActivityInterpreterImpl activityInterpreter =
207                                    (SocialActivityInterpreterImpl)activityInterpreters.get(i);
208    
209                            if (activityInterpreter.hasClassName(className)) {
210                                    SocialActivityFeedEntry activityFeedEntry =
211                                            activityInterpreter.interpret(activity, serviceContext);
212    
213                                    if (activityFeedEntry != null) {
214                                            activityFeedEntry.setPortletId(
215                                                    activityInterpreter.getPortletId());
216    
217                                            return activityFeedEntry;
218                                    }
219                            }
220                    }
221    
222                    return null;
223            }
224    
225            @Override
226            public SocialActivityFeedEntry interpret(
227                    String selector, SocialActivitySet activitySet,
228                    ServiceContext serviceContext) {
229    
230                    HttpServletRequest request = serviceContext.getRequest();
231    
232                    if (request == null) {
233                            return null;
234                    }
235    
236                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
237                            WebKeys.THEME_DISPLAY);
238    
239                    try {
240                            if (activitySet.getUserId() == themeDisplay.getDefaultUserId()) {
241                                    return null;
242                            }
243                    }
244                    catch (Exception e) {
245                            _log.error(e, e);
246                    }
247    
248                    List<SocialActivityInterpreter> activityInterpreters =
249                            _activityInterpreters.get(selector);
250    
251                    if (activityInterpreters == null) {
252                            return null;
253                    }
254    
255                    String className = PortalUtil.getClassName(
256                            activitySet.getClassNameId());
257    
258                    for (int i = 0; i < activityInterpreters.size(); i++) {
259                            SocialActivityInterpreterImpl activityInterpreter =
260                                    (SocialActivityInterpreterImpl)activityInterpreters.get(i);
261    
262                            if (activityInterpreter.hasClassName(className)) {
263                                    SocialActivityFeedEntry activityFeedEntry =
264                                            activityInterpreter.interpret(activitySet, serviceContext);
265    
266                                    if (activityFeedEntry != null) {
267                                            activityFeedEntry.setPortletId(
268                                                    activityInterpreter.getPortletId());
269    
270                                            return activityFeedEntry;
271                                    }
272                            }
273                    }
274    
275                    return null;
276            }
277    
278            @Override
279            public void updateActivitySet(long activityId) throws PortalException {
280                    if (!PropsValues.SOCIAL_ACTIVITY_SETS_BUNDLING_ENABLED) {
281                            socialActivitySetLocalService.addActivitySet(activityId);
282    
283                            return;
284                    }
285    
286                    List<SocialActivityInterpreter> activityInterpreters =
287                            _activityInterpreters.get(
288                                    PropsValues.SOCIAL_ACTIVITY_SETS_SELECTOR);
289    
290                    if (activityInterpreters != null) {
291                            SocialActivity activity =
292                                    socialActivityPersistence.findByPrimaryKey(activityId);
293    
294                            String className = PortalUtil.getClassName(
295                                    activity.getClassNameId());
296    
297                            for (int i = 0; i < activityInterpreters.size(); i++) {
298                                    SocialActivityInterpreterImpl activityInterpreter =
299                                            (SocialActivityInterpreterImpl)activityInterpreters.get(i);
300    
301                                    if (activityInterpreter.hasClassName(className)) {
302                                            activityInterpreter.updateActivitySet(activityId);
303    
304                                            return;
305                                    }
306                            }
307                    }
308            }
309    
310            private static final Log _log = LogFactoryUtil.getLog(
311                    SocialActivityInterpreterLocalServiceImpl.class);
312    
313            private final Map<String, List<SocialActivityInterpreter>>
314                    _activityInterpreters = new HashMap<>();
315            private final ServiceRegistrationMap<SocialActivityInterpreter>
316                    _serviceRegistrations = new ServiceRegistrationMapImpl<>();
317            private ServiceTracker<SocialActivityInterpreter, SocialActivityInterpreter>
318                    _serviceTracker;
319    
320            private class SocialActivityInterpreterServiceTrackerCustomizer
321                    implements ServiceTrackerCustomizer
322                            <SocialActivityInterpreter, SocialActivityInterpreter> {
323    
324                    @Override
325                    public SocialActivityInterpreter addingService(
326                            ServiceReference<SocialActivityInterpreter> serviceReference) {
327    
328                            Registry registry = RegistryUtil.getRegistry();
329    
330                            SocialActivityInterpreter activityInterpreter = registry.getService(
331                                    serviceReference);
332    
333                            String portletId = (String)serviceReference.getProperty(
334                                    "javax.portlet.name");
335    
336                            if (!(activityInterpreter instanceof
337                                            SocialRequestInterpreterImpl)) {
338    
339                                    activityInterpreter = new SocialActivityInterpreterImpl(
340                                            portletId, activityInterpreter);
341                            }
342    
343                            List<SocialActivityInterpreter> activityInterpreters =
344                                    _activityInterpreters.get(activityInterpreter.getSelector());
345    
346                            if (activityInterpreters == null) {
347                                    activityInterpreters = new ArrayList<>();
348                            }
349    
350                            activityInterpreters.add(activityInterpreter);
351    
352                            _activityInterpreters.put(
353                                    activityInterpreter.getSelector(), activityInterpreters);
354    
355                            return activityInterpreter;
356                    }
357    
358                    @Override
359                    public void modifiedService(
360                            ServiceReference<SocialActivityInterpreter> serviceReference,
361                            SocialActivityInterpreter activityInterpreter) {
362                    }
363    
364                    @Override
365                    public void removedService(
366                            ServiceReference<SocialActivityInterpreter> serviceReference,
367                            SocialActivityInterpreter activityInterpreter) {
368    
369                            Registry registry = RegistryUtil.getRegistry();
370    
371                            registry.ungetService(serviceReference);
372    
373                            List<SocialActivityInterpreter> activityInterpreters =
374                                    _activityInterpreters.get(activityInterpreter.getSelector());
375    
376                            if (activityInterpreters == null) {
377                                    return;
378                            }
379    
380                            activityInterpreters.remove(activityInterpreter);
381                    }
382    
383            }
384    
385    }