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.portal.mobile.device.rulegroup;
016    
017    import com.liferay.portal.kernel.bean.BeanReference;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.mobile.device.rulegroup.RuleGroupProcessor;
023    import com.liferay.portal.kernel.mobile.device.rulegroup.rule.RuleHandler;
024    import com.liferay.portal.model.Layout;
025    import com.liferay.portal.model.LayoutSet;
026    import com.liferay.portal.theme.ThemeDisplay;
027    import com.liferay.portlet.mobiledevicerules.model.MDRRule;
028    import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroup;
029    import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroupInstance;
030    import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupInstanceLocalService;
031    import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupLocalService;
032    import com.liferay.portlet.mobiledevicerules.util.RuleGroupInstancePriorityComparator;
033    
034    import java.util.Collection;
035    import java.util.Collections;
036    import java.util.HashMap;
037    import java.util.List;
038    import java.util.Map;
039    
040    /**
041     * @author Edward Han
042     */
043    public class DefaultRuleGroupProcessorImpl implements RuleGroupProcessor {
044    
045            @Override
046            public MDRRuleGroupInstance evaluateRuleGroups(ThemeDisplay themeDisplay)
047                    throws SystemException {
048    
049                    Layout layout = themeDisplay.getLayout();
050    
051                    MDRRuleGroupInstance mdrRuleGroupInstance = evaluateRuleGroupInstances(
052                            Layout.class.getName(), layout.getPlid(), themeDisplay);
053    
054                    if (mdrRuleGroupInstance != null) {
055                            return mdrRuleGroupInstance;
056                    }
057    
058                    LayoutSet layoutSet = themeDisplay.getLayoutSet();
059    
060                    mdrRuleGroupInstance = evaluateRuleGroupInstances(
061                            LayoutSet.class.getName(), layoutSet.getLayoutSetId(),
062                            themeDisplay);
063    
064                    return mdrRuleGroupInstance;
065            }
066    
067            @Override
068            public RuleHandler getRuleHandler(String ruleType) {
069                    return _ruleHandlers.get(ruleType);
070            }
071    
072            @Override
073            public Collection<RuleHandler> getRuleHandlers() {
074                    return Collections.unmodifiableCollection(_ruleHandlers.values());
075            }
076    
077            @Override
078            public Collection<String> getRuleHandlerTypes() {
079                    return _ruleHandlers.keySet();
080            }
081    
082            @Override
083            public void registerRuleHandler(RuleHandler ruleHandler) {
084                    RuleHandler oldRuleHandler = _ruleHandlers.put(
085                            ruleHandler.getType(), ruleHandler);
086    
087                    if ((oldRuleHandler != null) && _log.isWarnEnabled()) {
088                            _log.warn(
089                                    "Replacing existing rule handler type " +
090                                            ruleHandler.getType());
091                    }
092            }
093    
094            public void setMDRRuleGroupInstanceLocalService(
095                    MDRRuleGroupInstanceLocalService mdrRuleGroupInstanceLocalService) {
096    
097                    _mdrRuleGroupInstanceLocalService = mdrRuleGroupInstanceLocalService;
098            }
099    
100            public void setMDRRuleGroupLocalService(
101                    MDRRuleGroupLocalService mdrRuleGroupLocalService) {
102    
103                    _mdrRuleGroupLocalService = mdrRuleGroupLocalService;
104            }
105    
106            public void setRuleHandlers(Collection<RuleHandler> ruleHandlers) {
107                    for (RuleHandler ruleHandler : ruleHandlers) {
108                            registerRuleHandler(ruleHandler);
109                    }
110            }
111    
112            @Override
113            public RuleHandler unregisterRuleHandler(String ruleType) {
114                    return _ruleHandlers.remove(ruleType);
115            }
116    
117            protected boolean evaluateRule(MDRRule rule, ThemeDisplay themeDisplay) {
118                    RuleHandler ruleHandler = _ruleHandlers.get(rule.getType());
119    
120                    if (ruleHandler != null) {
121                            return ruleHandler.evaluateRule(rule, themeDisplay);
122                    }
123                    else if (_log.isWarnEnabled()) {
124                            _log.warn("No rule handler registered for type " + rule.getType());
125                    }
126    
127                    return false;
128            }
129    
130            protected MDRRuleGroupInstance evaluateRuleGroupInstances(
131                            String className, long classPK, ThemeDisplay themeDisplay)
132                    throws SystemException {
133    
134                    List<MDRRuleGroupInstance> mdrRuleGroupInstances =
135                            _mdrRuleGroupInstanceLocalService.getRuleGroupInstances(
136                                    className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
137                                    new RuleGroupInstancePriorityComparator());
138    
139                    for (MDRRuleGroupInstance mdrRuleGroupInstance :
140                                    mdrRuleGroupInstances) {
141    
142                            MDRRuleGroup mdrRuleGroup =
143                                    _mdrRuleGroupLocalService.fetchRuleGroup(
144                                            mdrRuleGroupInstance.getRuleGroupId());
145    
146                            if (mdrRuleGroup == null) {
147                                    if (_log.isWarnEnabled()) {
148                                            _log.warn(
149                                                    "Rule group instance " +
150                                                            mdrRuleGroupInstance.getRuleGroupInstanceId() +
151                                                                    " has invalid rule group");
152                                    }
153    
154                                    continue;
155                            }
156    
157                            Collection<MDRRule> mdrRules = mdrRuleGroup.getRules();
158    
159                            for (MDRRule mdrRule : mdrRules) {
160                                    if (evaluateRule(mdrRule, themeDisplay)) {
161                                            return mdrRuleGroupInstance;
162                                    }
163                            }
164                    }
165    
166                    return null;
167            }
168    
169            private static Log _log = LogFactoryUtil.getLog(
170                    DefaultRuleGroupProcessorImpl.class);
171    
172            @BeanReference(type = MDRRuleGroupInstanceLocalService.class)
173            private MDRRuleGroupInstanceLocalService _mdrRuleGroupInstanceLocalService;
174    
175            @BeanReference(type = MDRRuleGroupLocalService.class)
176            private MDRRuleGroupLocalService _mdrRuleGroupLocalService;
177    
178            private Map<String, RuleHandler> _ruleHandlers =
179                    new HashMap<String, RuleHandler>();
180    
181    }