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.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.ListUtil;
021    import com.liferay.portal.kernel.util.ProxyFactory;
022    import com.liferay.portal.kernel.util.Tuple;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.kernel.xml.Document;
025    import com.liferay.portal.kernel.xml.DocumentException;
026    import com.liferay.portal.kernel.xml.DocumentType;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portal.util.JavaFieldsParser;
030    import com.liferay.portlet.social.model.SocialAchievement;
031    import com.liferay.portlet.social.model.SocialActivityCounterConstants;
032    import com.liferay.portlet.social.model.SocialActivityCounterDefinition;
033    import com.liferay.portlet.social.model.SocialActivityDefinition;
034    import com.liferay.portlet.social.model.SocialActivityProcessor;
035    
036    import java.util.ArrayList;
037    import java.util.Collections;
038    import java.util.HashMap;
039    import java.util.LinkedHashSet;
040    import java.util.List;
041    import java.util.Map;
042    import java.util.Set;
043    
044    /**
045     * @author Zsolt Berentey
046     */
047    public class SocialConfigurationImpl implements SocialConfiguration {
048    
049            @Override
050            public List<String> getActivityCounterNames() {
051                    return getActivityCounterNames(
052                            SocialActivityCounterConstants.TYPE_ALL, false);
053            }
054    
055            @Override
056            public List<String> getActivityCounterNames(boolean transientCounter) {
057                    return getActivityCounterNames(
058                            SocialActivityCounterConstants.TYPE_ALL, transientCounter);
059            }
060    
061            @Override
062            public List<String> getActivityCounterNames(int ownerType) {
063                    return getActivityCounterNames(ownerType, false);
064            }
065    
066            @Override
067            public List<String> getActivityCounterNames(
068                    int ownerType, boolean transientCounter) {
069    
070                    Set<String> activityCounterNames = new LinkedHashSet<String>();
071    
072                    for (Map<Integer, SocialActivityDefinition> activityDefinitions :
073                                    _activityDefinitions.values()) {
074    
075                            for (SocialActivityDefinition activityDefinition :
076                                            activityDefinitions.values()) {
077    
078                                    for (SocialActivityCounterDefinition activityCounterDefinition :
079                                                    activityDefinition.getActivityCounterDefinitions()) {
080    
081                                            if ((activityCounterDefinition.isTransient() ==
082                                                            transientCounter) &&
083                                                    ((ownerType ==
084                                                            SocialActivityCounterConstants.TYPE_ALL) ||
085                                                     (ownerType ==
086                                                            activityCounterDefinition.getOwnerType()))) {
087    
088                                                    activityCounterNames.add(
089                                                            activityCounterDefinition.getName());
090                                            }
091                                    }
092                            }
093                    }
094    
095                    return new ArrayList<String>(activityCounterNames);
096            }
097    
098            @Override
099            public SocialActivityDefinition getActivityDefinition(
100                    String modelName, int activityType) {
101    
102                    Map<Integer, SocialActivityDefinition> activityDefinitions =
103                            _activityDefinitions.get(modelName);
104    
105                    if (activityDefinitions == null) {
106                            return null;
107                    }
108    
109                    return activityDefinitions.get(activityType);
110            }
111    
112            @Override
113            public List<SocialActivityDefinition> getActivityDefinitions(
114                    String modelName) {
115    
116                    Map<Integer, SocialActivityDefinition> activityDefinitions =
117                            _activityDefinitions.get(modelName);
118    
119                    if (activityDefinitions == null) {
120                            return Collections.emptyList();
121                    }
122    
123                    return ListUtil.fromCollection(activityDefinitions.values());
124            }
125    
126            @Override
127            public String[] getActivityModelNames() {
128                    Set<String> activityModelNames = _activityDefinitions.keySet();
129    
130                    return activityModelNames.toArray(
131                            new String[activityModelNames.size()]);
132            }
133    
134            @Override
135            public List<Object> read(ClassLoader classLoader, String[] xmls)
136                    throws Exception {
137    
138                    List<Object> objects = new ArrayList<Object>();
139    
140                    for (String xml : xmls) {
141                            _read(classLoader, xml, objects);
142                    }
143    
144                    return objects;
145            }
146    
147            @Override
148            public void removeActivityDefinition(
149                    SocialActivityDefinition activityDefinition) {
150    
151                    Map<Integer, SocialActivityDefinition> activityDefinitions =
152                            _activityDefinitions.get(activityDefinition.getModelName());
153    
154                    if (activityDefinitions != null) {
155                            activityDefinitions.remove(activityDefinition.getActivityType());
156                    }
157            }
158    
159            private void _read(
160                            ClassLoader classLoader, String xml, List<Object> objects)
161                    throws Exception {
162    
163                    if (xml == null) {
164                            return;
165                    }
166    
167                    xml = JavaFieldsParser.parse(classLoader, xml);
168    
169                    Document document = SAXReaderUtil.read(xml);
170    
171                    DocumentType documentType = document.getDocumentType();
172    
173                    String publicId = documentType.getPublicId();
174    
175                    if (!publicId.equals("-//Liferay//DTD Social 6.1.0//EN") &&
176                            !publicId.equals("-//Liferay//DTD Social 6.2.0//EN") &&
177                            !publicId.equals("-//Liferay//DTD Social 7.0.0//EN")) {
178    
179                            throw new DocumentException(
180                                    "Unsupported document type " + publicId);
181                    }
182    
183                    Element rootElement = document.getRootElement();
184    
185                    List<Element> activityElements = rootElement.elements("activity");
186    
187                    for (Element activityElement : activityElements) {
188                            _readActivity(classLoader, objects, activityElement);
189                    }
190            }
191    
192            private void _readAchievement(
193                            ClassLoader classLoader, List<Object> objects,
194                            SocialActivityDefinition activityDefinition,
195                            Element achievementElement)
196                    throws Exception {
197    
198                    String achievementClassName = GetterUtil.getString(
199                            achievementElement.elementText("achievement-class"));
200    
201                    SocialAchievement achievement =
202                            (SocialAchievement)ProxyFactory.newInstance(
203                                    classLoader, SocialAchievement.class, achievementClassName);
204    
205                    String name = GetterUtil.getString(
206                            achievementElement.elementText("name"));
207    
208                    achievement.setName(name);
209    
210                    String icon = GetterUtil.getString(
211                            achievementElement.elementText("icon"));
212    
213                    achievement.setIcon(icon);
214    
215                    List<Element> propertyElements = achievementElement.elements(
216                            "property");
217    
218                    for (Element propertyElement : propertyElements) {
219                            _readAchievementProperty(achievement, propertyElement);
220                    }
221    
222                    achievement.initialize(activityDefinition);
223    
224                    List<SocialAchievement> achievements =
225                            activityDefinition.getAchievements();
226    
227                    achievements.add(achievement);
228    
229                    Tuple tuple = new Tuple(activityDefinition, achievement);
230    
231                    objects.add(tuple);
232            }
233    
234            private void _readAchievementProperty(
235                    SocialAchievement achievement, Element propertyElement) {
236    
237                    String name = GetterUtil.getString(propertyElement.elementText("name"));
238                    String value = GetterUtil.getString(
239                            propertyElement.elementText("value"));
240    
241                    achievement.setProperty(name, value);
242            }
243    
244            private void _readActivity(
245                            ClassLoader classLoader, Element activityElement,
246                            SocialActivityDefinition activityDefinition)
247                    throws Exception {
248    
249                    boolean logActivity = GetterUtil.getBoolean(
250                            activityElement.elementText("log-activity"));
251    
252                    activityDefinition.setLogActivity(logActivity);
253    
254                    boolean countersEnabled = GetterUtil.getBoolean(
255                            activityElement.elementText("counters-enabled"), true);
256    
257                    activityDefinition.setCountersEnabled(countersEnabled);
258    
259                    if (!countersEnabled) {
260                            return;
261                    }
262    
263                    String languageKey = GetterUtil.getString(
264                            activityElement.elementText("language-key"));
265    
266                    activityDefinition.setLanguageKey(languageKey);
267    
268                    String processorClassName = GetterUtil.getString(
269                            activityElement.elementText("processor-class"));
270    
271                    if (Validator.isNotNull(processorClassName)) {
272                            SocialActivityProcessor activityProcessor =
273                                    (SocialActivityProcessor)ProxyFactory.newInstance(
274                                            classLoader, SocialActivityProcessor.class,
275                                            processorClassName);
276    
277                            activityDefinition.setActivityProcessor(activityProcessor);
278                    }
279    
280                    _readActivityContribution(activityElement, activityDefinition);
281                    _readActivityParticipation(activityElement, activityDefinition);
282            }
283    
284            private void _readActivity(
285                            ClassLoader classLoader, List<Object> objects,
286                            Element activityElement)
287                    throws Exception {
288    
289                    String modelName = GetterUtil.getString(
290                            activityElement.elementText("model-name"));
291    
292                    Map<Integer, SocialActivityDefinition> activityDefinitions =
293                            _activityDefinitions.get(modelName);
294    
295                    if (activityDefinitions == null) {
296                            activityDefinitions =
297                                    new HashMap<Integer, SocialActivityDefinition>();
298    
299                            _activityDefinitions.put(modelName, activityDefinitions);
300                    }
301    
302                    int activityType = GetterUtil.getInteger(
303                            activityElement.elementText("activity-type"));
304    
305                    SocialActivityDefinition activityDefinition = activityDefinitions.get(
306                            activityType);
307    
308                    if (activityDefinition == null) {
309                            activityDefinition = new SocialActivityDefinition();
310    
311                            activityDefinition.setModelName(modelName);
312                            activityDefinition.setActivityType(activityType);
313    
314                            _readActivity(classLoader, activityElement, activityDefinition);
315    
316                            activityDefinitions.put(activityType, activityDefinition);
317    
318                            objects.add(activityDefinition);
319                    }
320    
321                    List<Element> counterElements = activityElement.elements("counter");
322    
323                    for (Element counterElement : counterElements) {
324                            _readCounter(objects, activityDefinition, counterElement);
325                    }
326    
327                    List<Element> achievementElements = activityElement.elements(
328                            "achievement");
329    
330                    for (Element achievementElement : achievementElements) {
331                            _readAchievement(
332                                    classLoader, objects, activityDefinition, achievementElement);
333                    }
334            }
335    
336            private void _readActivityContribution(
337                    Element activityElement, SocialActivityDefinition activityDefinition) {
338    
339                    Element contributionValueElement = activityElement.element(
340                            "contribution-value");
341                    Element contributionLimitElement = activityElement.element(
342                            "contribution-limit");
343    
344                    if ((contributionValueElement == null) &&
345                            (contributionLimitElement == null)) {
346    
347                            return;
348                    }
349    
350                    SocialActivityCounterDefinition activityCounterDefinition =
351                            new SocialActivityCounterDefinition();
352    
353                    activityCounterDefinition.setName(
354                            SocialActivityCounterConstants.NAME_CONTRIBUTION);
355                    activityCounterDefinition.setOwnerType(
356                            SocialActivityCounterConstants.TYPE_CREATOR);
357    
358                    int increment = 0;
359    
360                    if (contributionValueElement != null) {
361                            increment = GetterUtil.getInteger(
362                                    contributionValueElement.getText());
363                    }
364    
365                    activityCounterDefinition.setIncrement(increment);
366    
367                    if (contributionLimitElement != null) {
368                            String limitEnabled = contributionLimitElement.attributeValue(
369                                    "enabled");
370    
371                            if (Validator.isNotNull(limitEnabled)) {
372                                    activityCounterDefinition.setLimitEnabled(
373                                            GetterUtil.getBoolean(limitEnabled));
374                            }
375    
376                            String limitPeriod = contributionLimitElement.attributeValue(
377                                    "period");
378    
379                            if (Validator.isNotNull(limitPeriod)) {
380                                    activityCounterDefinition.setLimitPeriod(limitPeriod);
381                            }
382    
383                            int limitValue = GetterUtil.getInteger(
384                                    contributionLimitElement.getText());
385    
386                            activityCounterDefinition.setLimitValue(limitValue);
387                    }
388    
389                    activityDefinition.addCounter(activityCounterDefinition);
390    
391                    SocialActivityCounterDefinition popularityActivityCounterDefinition =
392                            new SocialActivityCounterDefinition();
393    
394                    popularityActivityCounterDefinition.setName(
395                            SocialActivityCounterConstants.NAME_POPULARITY);
396                    popularityActivityCounterDefinition.setOwnerType(
397                            SocialActivityCounterConstants.TYPE_ASSET);
398                    popularityActivityCounterDefinition.setIncrement(
399                            activityCounterDefinition.getIncrement());
400                    popularityActivityCounterDefinition.setLimitEnabled(
401                            activityCounterDefinition.isLimitEnabled());
402                    popularityActivityCounterDefinition.setLimitPeriod(
403                            activityCounterDefinition.getLimitPeriod());
404                    popularityActivityCounterDefinition.setLimitValue(
405                            activityCounterDefinition.getLimitValue());
406    
407                    activityDefinition.addCounter(popularityActivityCounterDefinition);
408            }
409    
410            private void _readActivityParticipation(
411                    Element activityElement, SocialActivityDefinition activityDefinition) {
412    
413                    Element participationValueElement = activityElement.element(
414                            "participation-value");
415                    Element participationLimitElement = activityElement.element(
416                            "participation-limit");
417    
418                    if ((participationValueElement == null) &&
419                            (participationLimitElement == null)) {
420    
421                            return;
422                    }
423    
424                    SocialActivityCounterDefinition activityCounterDefinition =
425                            new SocialActivityCounterDefinition();
426    
427                    activityCounterDefinition.setName(
428                            SocialActivityCounterConstants.NAME_PARTICIPATION);
429                    activityCounterDefinition.setOwnerType(
430                            SocialActivityCounterConstants.TYPE_ACTOR);
431    
432                    int increment = 0;
433    
434                    if (participationValueElement != null) {
435                            increment = GetterUtil.getInteger(
436                                    participationValueElement.getText());
437                    }
438    
439                    activityCounterDefinition.setIncrement(increment);
440    
441                    if (participationLimitElement != null) {
442                            String limitEnabled = participationLimitElement.attributeValue(
443                                    "enabled");
444    
445                            if (Validator.isNotNull(limitEnabled)) {
446                                    activityCounterDefinition.setLimitEnabled(
447                                            GetterUtil.getBoolean(limitEnabled));
448                            }
449    
450                            String limitPeriod = participationLimitElement.attributeValue(
451                                    "period");
452    
453                            if (Validator.isNotNull(limitPeriod)) {
454                                    activityCounterDefinition.setLimitPeriod(limitPeriod);
455                            }
456    
457                            int limitValue = GetterUtil.getInteger(
458                                    participationLimitElement.getText());
459    
460                            activityCounterDefinition.setLimitValue(limitValue);
461                    }
462    
463                    activityDefinition.addCounter(activityCounterDefinition);
464            }
465    
466            private void _readCounter(
467                    List<Object> objects, SocialActivityDefinition activityDefinition,
468                    Element counterElement) {
469    
470                    SocialActivityCounterDefinition activityCounterDefinition =
471                            new SocialActivityCounterDefinition();
472    
473                    int increment = GetterUtil.getInteger(
474                            counterElement.elementText("increment"), 1);
475    
476                    activityCounterDefinition.setIncrement(increment);
477    
478                    boolean enabled = GetterUtil.getBoolean(
479                            counterElement.elementText("enabled"), true);
480    
481                    activityCounterDefinition.setEnabled(enabled);
482    
483                    String name = GetterUtil.getString(counterElement.elementText("name"));
484    
485                    activityCounterDefinition.setName(name);
486    
487                    String ownerType = GetterUtil.getString(
488                            counterElement.elementText("owner-type"));
489    
490                    activityCounterDefinition.setOwnerType(ownerType);
491    
492                    if (activityCounterDefinition.getOwnerType() == 0) {
493                            if (_log.isWarnEnabled()) {
494                                    _log.warn(
495                                            "Invalid owner type " + ownerType + " for model " +
496                                                    activityDefinition.getModelName());
497                            }
498    
499                            return;
500                    }
501    
502                    activityDefinition.addCounter(activityCounterDefinition);
503    
504                    Tuple tuple = new Tuple(activityDefinition, activityCounterDefinition);
505    
506                    objects.add(tuple);
507            }
508    
509            private static final Log _log = LogFactoryUtil.getLog(
510                    SocialConfigurationImpl.class);
511    
512            private final Map<String, Map<Integer, SocialActivityDefinition>>
513                    _activityDefinitions =
514                            new HashMap<String, Map<Integer, SocialActivityDefinition>>();
515    
516    }