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