001    /**
002     * Copyright (c) 2000-2013 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.UniqueList;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.xml.Document;
026    import com.liferay.portal.kernel.xml.DocumentException;
027    import com.liferay.portal.kernel.xml.DocumentType;
028    import com.liferay.portal.kernel.xml.Element;
029    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
030    import com.liferay.portal.util.JavaFieldsParser;
031    import com.liferay.portlet.social.model.SocialAchievement;
032    import com.liferay.portlet.social.model.SocialActivityCounterConstants;
033    import com.liferay.portlet.social.model.SocialActivityCounterDefinition;
034    import com.liferay.portlet.social.model.SocialActivityDefinition;
035    import com.liferay.portlet.social.model.SocialActivityProcessor;
036    
037    import java.util.ArrayList;
038    import java.util.Collections;
039    import java.util.HashMap;
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                    List<String> activityCounterNames = new UniqueList<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 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 = UnsecureSAXReaderUtil.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    
178                            throw new DocumentException(
179                                    "Unsupported document type " + publicId);
180                    }
181    
182                    Element rootElement = document.getRootElement();
183    
184                    List<Element> activityElements = rootElement.elements("activity");
185    
186                    for (Element activityElement : activityElements) {
187                            _readActivity(classLoader, objects, activityElement);
188                    }
189            }
190    
191            private void _readAchievement(
192                            ClassLoader classLoader, List<Object> objects,
193                            SocialActivityDefinition activityDefinition,
194                            Element achievementElement)
195                    throws Exception {
196    
197                    String achievementClassName = GetterUtil.getString(
198                            achievementElement.elementText("achievement-class"));
199    
200                    SocialAchievement achievement =
201                            (SocialAchievement)ProxyFactory.newInstance(
202                                    classLoader, SocialAchievement.class, achievementClassName);
203    
204                    String name = GetterUtil.getString(
205                            achievementElement.elementText("name"));
206    
207                    achievement.setName(name);
208    
209                    String icon = GetterUtil.getString(
210                            achievementElement.elementText("icon"));
211    
212                    achievement.setIcon(icon);
213    
214                    List<Element> propertyElements = achievementElement.elements(
215                            "property");
216    
217                    for (Element propertyElement : propertyElements) {
218                            _readAchievementProperty(achievement, propertyElement);
219                    }
220    
221                    achievement.initialize(activityDefinition);
222    
223                    List<SocialAchievement> achievements =
224                            activityDefinition.getAchievements();
225    
226                    achievements.add(achievement);
227    
228                    Tuple tuple = new Tuple(activityDefinition, achievement);
229    
230                    objects.add(tuple);
231            }
232    
233            private void _readAchievementProperty(
234                    SocialAchievement achievement, Element propertyElement) {
235    
236                    String name = GetterUtil.getString(propertyElement.elementText("name"));
237                    String value = GetterUtil.getString(
238                            propertyElement.elementText("value"));
239    
240                    achievement.setProperty(name, value);
241            }
242    
243            private void _readActivity(
244                            ClassLoader classLoader, Element activityElement,
245                            SocialActivityDefinition activityDefinition)
246                    throws Exception {
247    
248                    boolean logActivity = GetterUtil.getBoolean(
249                            activityElement.elementText("log-activity"));
250    
251                    activityDefinition.setLogActivity(logActivity);
252    
253                    boolean countersEnabled = GetterUtil.getBoolean(
254                            activityElement.elementText("counters-enabled"), true);
255    
256                    activityDefinition.setCountersEnabled(countersEnabled);
257    
258                    if (!countersEnabled) {
259                            return;
260                    }
261    
262                    String languageKey = GetterUtil.getString(
263                            activityElement.elementText("language-key"));
264    
265                    activityDefinition.setLanguageKey(languageKey);
266    
267                    String processorClassName = GetterUtil.getString(
268                            activityElement.elementText("processor-class"));
269    
270                    if (Validator.isNotNull(processorClassName)) {
271                            SocialActivityProcessor activityProcessor =
272                                    (SocialActivityProcessor)ProxyFactory.newInstance(
273                                            classLoader, SocialActivityProcessor.class,
274                                            processorClassName);
275    
276                            activityDefinition.setActivityProcessor(activityProcessor);
277                    }
278    
279                    _readActivityContribution(activityElement, activityDefinition);
280                    _readActivityParticipation(activityElement, activityDefinition);
281            }
282    
283            private void _readActivity(
284                            ClassLoader classLoader, List<Object> objects,
285                            Element activityElement)
286                    throws Exception {
287    
288                    String modelName = GetterUtil.getString(
289                            activityElement.elementText("model-name"));
290    
291                    Map<Integer, SocialActivityDefinition> activityDefinitions =
292                            _activityDefinitions.get(modelName);
293    
294                    if (activityDefinitions == null) {
295                            activityDefinitions =
296                                    new HashMap<Integer, SocialActivityDefinition>();
297    
298                            _activityDefinitions.put(modelName, activityDefinitions);
299                    }
300    
301                    int activityType = GetterUtil.getInteger(
302                            activityElement.elementText("activity-type"));
303    
304                    SocialActivityDefinition activityDefinition = activityDefinitions.get(
305                            activityType);
306    
307                    if (activityDefinition == null) {
308                            activityDefinition = new SocialActivityDefinition();
309    
310                            activityDefinition.setModelName(modelName);
311                            activityDefinition.setActivityType(activityType);
312    
313                            _readActivity(classLoader, activityElement, activityDefinition);
314    
315                            activityDefinitions.put(activityType, activityDefinition);
316    
317                            objects.add(activityDefinition);
318                    }
319    
320                    List<Element> counterElements = activityElement.elements("counter");
321    
322                    for (Element counterElement : counterElements) {
323                            _readCounter(objects, activityDefinition, counterElement);
324                    }
325    
326                    List<Element> achievementElements = activityElement.elements(
327                            "achievement");
328    
329                    for (Element achievementElement : achievementElements) {
330                            _readAchievement(
331                                    classLoader, objects, activityDefinition, achievementElement);
332                    }
333            }
334    
335            private void _readActivityContribution(
336                    Element activityElement, SocialActivityDefinition activityDefinition) {
337    
338                    Element contributionValueElement = activityElement.element(
339                            "contribution-value");
340                    Element contributionLimitElement = activityElement.element(
341                            "contribution-limit");
342    
343                    if ((contributionValueElement == null) &&
344                            (contributionLimitElement == null)) {
345    
346                            return;
347                    }
348    
349                    SocialActivityCounterDefinition activityCounterDefinition =
350                            new SocialActivityCounterDefinition();
351    
352                    activityCounterDefinition.setName(
353                            SocialActivityCounterConstants.NAME_CONTRIBUTION);
354                    activityCounterDefinition.setOwnerType(
355                            SocialActivityCounterConstants.TYPE_CREATOR);
356    
357                    int increment = 0;
358    
359                    if (contributionValueElement != null) {
360                            increment = GetterUtil.getInteger(
361                                    contributionValueElement.getText());
362                    }
363    
364                    activityCounterDefinition.setIncrement(increment);
365    
366                    if (contributionLimitElement != null) {
367                            String limitEnabled = contributionLimitElement.attributeValue(
368                                    "enabled");
369    
370                            if (Validator.isNotNull(limitEnabled)) {
371                                    activityCounterDefinition.setLimitEnabled(
372                                            GetterUtil.getBoolean(limitEnabled));
373                            }
374    
375                            String limitPeriod = contributionLimitElement.attributeValue(
376                                    "period");
377    
378                            if (Validator.isNotNull(limitPeriod)) {
379                                    activityCounterDefinition.setLimitPeriod(limitPeriod);
380                            }
381    
382                            int limitValue = GetterUtil.getInteger(
383                                    contributionLimitElement.getText());
384    
385                            activityCounterDefinition.setLimitValue(limitValue);
386                    }
387    
388                    activityDefinition.addCounter(activityCounterDefinition);
389    
390                    SocialActivityCounterDefinition popularityActivityCounterDefinition =
391                            new SocialActivityCounterDefinition();
392    
393                    popularityActivityCounterDefinition.setName(
394                            SocialActivityCounterConstants.NAME_POPULARITY);
395                    popularityActivityCounterDefinition.setOwnerType(
396                            SocialActivityCounterConstants.TYPE_ASSET);
397                    popularityActivityCounterDefinition.setIncrement(
398                            activityCounterDefinition.getIncrement());
399                    popularityActivityCounterDefinition.setLimitEnabled(
400                            activityCounterDefinition.isLimitEnabled());
401                    popularityActivityCounterDefinition.setLimitPeriod(
402                            activityCounterDefinition.getLimitPeriod());
403                    popularityActivityCounterDefinition.setLimitValue(
404                            activityCounterDefinition.getLimitValue());
405    
406                    activityDefinition.addCounter(popularityActivityCounterDefinition);
407            }
408    
409            private void _readActivityParticipation(
410                    Element activityElement, SocialActivityDefinition activityDefinition) {
411    
412                    Element participationValueElement = activityElement.element(
413                            "participation-value");
414                    Element participationLimitElement = activityElement.element(
415                            "participation-limit");
416    
417                    if ((participationValueElement == null) &&
418                            (participationLimitElement == null)) {
419    
420                            return;
421                    }
422    
423                    SocialActivityCounterDefinition activityCounterDefinition =
424                            new SocialActivityCounterDefinition();
425    
426                    activityCounterDefinition.setName(
427                            SocialActivityCounterConstants.NAME_PARTICIPATION);
428                    activityCounterDefinition.setOwnerType(
429                            SocialActivityCounterConstants.TYPE_ACTOR);
430    
431                    int increment = 0;
432    
433                    if (participationValueElement != null) {
434                            increment = GetterUtil.getInteger(
435                                    participationValueElement.getText());
436                    }
437    
438                    activityCounterDefinition.setIncrement(increment);
439    
440                    if (participationLimitElement != null) {
441                            String limitEnabled = participationLimitElement.attributeValue(
442                                    "enabled");
443    
444                            if (Validator.isNotNull(limitEnabled)) {
445                                    activityCounterDefinition.setLimitEnabled(
446                                            GetterUtil.getBoolean(limitEnabled));
447                            }
448    
449                            String limitPeriod = participationLimitElement.attributeValue(
450                                    "period");
451    
452                            if (Validator.isNotNull(limitPeriod)) {
453                                    activityCounterDefinition.setLimitPeriod(limitPeriod);
454                            }
455    
456                            int limitValue = GetterUtil.getInteger(
457                                    participationLimitElement.getText());
458    
459                            activityCounterDefinition.setLimitValue(limitValue);
460                    }
461    
462                    activityDefinition.addCounter(activityCounterDefinition);
463            }
464    
465            private void _readCounter(
466                    List<Object> objects, SocialActivityDefinition activityDefinition,
467                    Element counterElement) {
468    
469                    SocialActivityCounterDefinition activityCounterDefinition =
470                            new SocialActivityCounterDefinition();
471    
472                    int increment = GetterUtil.getInteger(
473                            counterElement.elementText("increment"), 1);
474    
475                    activityCounterDefinition.setIncrement(increment);
476    
477                    boolean enabled = GetterUtil.getBoolean(
478                            counterElement.elementText("enabled"), true);
479    
480                    activityCounterDefinition.setEnabled(enabled);
481    
482                    String name = GetterUtil.getString(counterElement.elementText("name"));
483    
484                    activityCounterDefinition.setName(name);
485    
486                    String ownerType = GetterUtil.getString(
487                            counterElement.elementText("owner-type"));
488    
489                    activityCounterDefinition.setOwnerType(ownerType);
490    
491                    if (activityCounterDefinition.getOwnerType() == 0) {
492                            if (_log.isWarnEnabled()) {
493                                    _log.warn(
494                                            "Invalid owner type " + ownerType + " for model " +
495                                                    activityDefinition.getModelName());
496                            }
497    
498                            return;
499                    }
500    
501                    activityDefinition.addCounter(activityCounterDefinition);
502    
503                    Tuple tuple = new Tuple(activityDefinition, activityCounterDefinition);
504    
505                    objects.add(tuple);
506            }
507    
508            private static Log _log = LogFactoryUtil.getLog(
509                    SocialConfigurationImpl.class);
510    
511            private Map<String, Map<Integer, SocialActivityDefinition>>
512                    _activityDefinitions =
513                            new HashMap<String, Map<Integer, SocialActivityDefinition>>();
514    
515    }