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.portal.mobile.device.rulegroup.rule.impl;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.mobile.device.Device;
020    import com.liferay.portal.kernel.mobile.device.Dimensions;
021    import com.liferay.portal.kernel.mobile.device.rulegroup.rule.RuleHandler;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.StringBundler;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.util.UnicodeProperties;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.theme.ThemeDisplay;
029    import com.liferay.portlet.mobiledevicerules.model.MDRRule;
030    
031    import java.util.Arrays;
032    import java.util.Collection;
033    import java.util.Collections;
034    
035    /**
036     * @author Edward Han
037     * @author Milen Daynkov
038     */
039    public class SimpleRuleHandler implements RuleHandler {
040    
041            public static final String PROPERTY_OS = "os";
042    
043            public static final String PROPERTY_SCREEN_PHYSICAL_HEIGHT_MAX =
044                    "screen-physical-height-max";
045    
046            public static final String PROPERTY_SCREEN_PHYSICAL_HEIGHT_MIN =
047                    "screen-physical-height-min";
048    
049            public static final String PROPERTY_SCREEN_PHYSICAL_WIDTH_MAX =
050                    "screen-physical-width-max";
051    
052            public static final String PROPERTY_SCREEN_PHYSICAL_WIDTH_MIN =
053                    "screen-physical-width-min";
054    
055            public static final String PROPERTY_SCREEN_RESOLUTION_HEIGHT_MAX =
056                    "screen-resolution-height-max";
057    
058            public static final String PROPERTY_SCREEN_RESOLUTION_HEIGHT_MIN =
059                    "screen-resolution-height-min";
060    
061            public static final String PROPERTY_SCREEN_RESOLUTION_WIDTH_MAX =
062                    "screen-resolution-width-max";
063    
064            public static final String PROPERTY_SCREEN_RESOLUTION_WIDTH_MIN =
065                    "screen-resolution-width-min";
066    
067            public static final String PROPERTY_TABLET = "tablet";
068    
069            public static String getHandlerType() {
070                    return SimpleRuleHandler.class.getName();
071            }
072    
073            @Override
074            public boolean evaluateRule(MDRRule mdrRule, ThemeDisplay themeDisplay) {
075                    Device device = themeDisplay.getDevice();
076    
077                    if (device == null) {
078                            if (_log.isDebugEnabled()) {
079                                    _log.debug(
080                                            "Rule evaluation is not possible because the information " +
081                                                    "about the device is not available");
082                            }
083    
084                            return false;
085                    }
086    
087                    if (!isValidMultiValue(mdrRule, PROPERTY_OS, device.getOS())) {
088                            return false;
089                    }
090    
091                    if (!isValidBooleanValue(mdrRule, PROPERTY_TABLET, device.isTablet())) {
092                            return false;
093                    }
094    
095                    Dimensions screenPhysicalSize = device.getScreenPhysicalSize();
096    
097                    if (!isValidRangeValue(
098                                    mdrRule, PROPERTY_SCREEN_PHYSICAL_HEIGHT_MAX,
099                                    PROPERTY_SCREEN_PHYSICAL_HEIGHT_MIN,
100                                    screenPhysicalSize.getHeight())) {
101    
102                            return false;
103                    }
104    
105                    if (!isValidRangeValue(
106                                    mdrRule, PROPERTY_SCREEN_PHYSICAL_WIDTH_MAX,
107                                    PROPERTY_SCREEN_PHYSICAL_WIDTH_MIN,
108                                    screenPhysicalSize.getWidth())) {
109    
110                            return false;
111                    }
112    
113                    Dimensions screenResolution = device.getScreenResolution();
114    
115                    if (!isValidRangeValue(
116                                    mdrRule, PROPERTY_SCREEN_RESOLUTION_HEIGHT_MAX,
117                                    PROPERTY_SCREEN_RESOLUTION_HEIGHT_MIN,
118                                    screenResolution.getHeight())) {
119    
120                            return false;
121                    }
122    
123                    if (!isValidRangeValue(
124                                    mdrRule, PROPERTY_SCREEN_RESOLUTION_WIDTH_MAX,
125                                    PROPERTY_SCREEN_RESOLUTION_WIDTH_MIN,
126                                    screenResolution.getWidth())) {
127    
128                            return false;
129                    }
130    
131                    return true;
132            }
133    
134            @Override
135            public Collection<String> getPropertyNames() {
136                    return _propertyNames;
137            }
138    
139            @Override
140            public String getType() {
141                    return getHandlerType();
142            }
143    
144            protected StringBundler getLogStringBundler(
145                    MDRRule mdrRule, String value, boolean valid) {
146    
147                    StringBundler sb = new StringBundler();
148    
149                    sb.append("Rule ");
150                    sb.append(mdrRule.getNameCurrentValue());
151                    sb.append(" with the value ");
152                    sb.append(value);
153                    sb.append(" is ");
154    
155                    if (!valid) {
156                            sb.append("not ");
157                    }
158    
159                    return sb;
160            }
161    
162            protected boolean isValidBooleanValue(
163                    MDRRule mdrRule, String property, boolean value) {
164    
165                    UnicodeProperties typeSettingsProperties =
166                            mdrRule.getTypeSettingsProperties();
167    
168                    String validValueString = typeSettingsProperties.get(property);
169    
170                    if (Validator.isNull(validValueString)) {
171                            return true;
172                    }
173    
174                    boolean ruleValue = GetterUtil.getBoolean(validValueString);
175    
176                    if (ruleValue != value) {
177                            logBooleanValue(mdrRule, property, value, false);
178    
179                            return false;
180                    }
181    
182                    logBooleanValue(mdrRule, property, value, true);
183    
184                    return true;
185            }
186    
187            protected boolean isValidMultiValue(
188                    MDRRule mdrRule, String property, String value) {
189    
190                    UnicodeProperties typeSettingsProperties =
191                            mdrRule.getTypeSettingsProperties();
192    
193                    String validValueString = typeSettingsProperties.get(property);
194    
195                    if (Validator.isNull(validValueString)) {
196                            return true;
197                    }
198    
199                    String[] validValues = StringUtil.split(validValueString);
200    
201                    if (!ArrayUtil.contains(validValues, value)) {
202                            logMultiValue(mdrRule, property, value, validValues, false);
203    
204                            return false;
205                    }
206    
207                    logMultiValue(mdrRule, property, value, validValues, true);
208    
209                    return true;
210            }
211    
212            protected boolean isValidRangeValue(
213                    MDRRule mdrRule, String maxProperty, String minProperty, float value) {
214    
215                    UnicodeProperties typeSettingsProperties =
216                            mdrRule.getTypeSettingsProperties();
217    
218                    String max = typeSettingsProperties.get(maxProperty);
219                    String min = typeSettingsProperties.get(minProperty);
220    
221                    if (Validator.isNull(max) && Validator.isNull(min)) {
222                            logRangeValue(
223                                    mdrRule, maxProperty, minProperty, value, max, min, true);
224    
225                            return true;
226                    }
227    
228                    if (Validator.isNotNull(max)) {
229                            float maxFloat = GetterUtil.getFloat(max);
230    
231                            if (value > maxFloat) {
232                                    logRangeValue(
233                                            mdrRule, maxProperty, minProperty, value, max, min, false);
234    
235                                    return false;
236                            }
237    
238                            logRangeValue(
239                                    mdrRule, maxProperty, minProperty, value, max, min, true);
240                    }
241    
242                    if (Validator.isNotNull(min)) {
243                            float minFloat = GetterUtil.getFloat(min);
244    
245                            if (value < minFloat) {
246                                    logRangeValue(
247                                            mdrRule, maxProperty, minProperty, value, max, min, false);
248    
249                                    return false;
250                            }
251    
252                            logRangeValue(
253                                    mdrRule, maxProperty, minProperty, value, max, min, true);
254                    }
255    
256                    return true;
257            }
258    
259            protected void logBooleanValue(
260                    MDRRule mdrRule, String property, boolean value, boolean valid) {
261    
262                    if (!_log.isDebugEnabled()) {
263                            return;
264                    }
265    
266                    StringBundler sb = getLogStringBundler(
267                            mdrRule, String.valueOf(value), valid);
268    
269                    sb.append("the value configured for the property ");
270                    sb.append(property);
271    
272                    _log.debug(sb.toString());
273            }
274    
275            protected void logMultiValue(
276                    MDRRule mdrRule, String property, String value, String[] validValues,
277                    boolean valid) {
278    
279                    if (!_log.isDebugEnabled()) {
280                            return;
281                    }
282    
283                    StringBundler sb = getLogStringBundler(mdrRule, value, valid);
284    
285                    sb.append("among the allowed values of ");
286                    sb.append(StringUtil.merge(validValues));
287                    sb.append(" for the property \"");
288                    sb.append(property);
289                    sb.append("\"");
290    
291                    _log.debug(sb.toString());
292            }
293    
294            protected void logRangeValue(
295                    MDRRule mdrRule, String maxProperty, String minProperty, float value,
296                    String max, String min, boolean valid) {
297    
298                    if (!_log.isDebugEnabled()) {
299                            return;
300                    }
301    
302                    StringBundler sb = getLogStringBundler(
303                            mdrRule, String.valueOf(value), valid);
304    
305                    sb.append("within the allowed range");
306    
307                    if (Validator.isNotNull(max) && Validator.isNotNull(min)) {
308                            sb.append(" of ");
309                            sb.append(min);
310                            sb.append(" and ");
311                            sb.append(max);
312                            sb.append(" for the minimum property \"");
313                            sb.append(minProperty);
314                            sb.append("\" and the maximum property \"");
315                            sb.append(maxProperty);
316                            sb.append("\"");
317                    }
318    
319                    _log.debug(sb.toString());
320            }
321    
322            private static final Log _log = LogFactoryUtil.getLog(
323                    SimpleRuleHandler.class);
324    
325            private final Collection<String> _propertyNames =
326                    Collections.unmodifiableCollection(
327                            Arrays.asList(
328                                    PROPERTY_OS, PROPERTY_SCREEN_PHYSICAL_WIDTH_MAX,
329                                    PROPERTY_SCREEN_PHYSICAL_WIDTH_MIN,
330                                    PROPERTY_SCREEN_PHYSICAL_HEIGHT_MAX,
331                                    PROPERTY_SCREEN_PHYSICAL_HEIGHT_MIN,
332                                    PROPERTY_SCREEN_RESOLUTION_WIDTH_MAX,
333                                    PROPERTY_SCREEN_RESOLUTION_WIDTH_MIN,
334                                    PROPERTY_SCREEN_RESOLUTION_HEIGHT_MAX,
335                                    PROPERTY_SCREEN_RESOLUTION_HEIGHT_MIN, PROPERTY_TABLET));
336    
337    }