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.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.ArrayList;
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            public SimpleRuleHandler() {
074                    _propertyNames = new ArrayList<String>(10);
075    
076                    _propertyNames.add(PROPERTY_OS);
077                    _propertyNames.add(PROPERTY_SCREEN_PHYSICAL_WIDTH_MAX);
078                    _propertyNames.add(PROPERTY_SCREEN_PHYSICAL_WIDTH_MIN);
079                    _propertyNames.add(PROPERTY_SCREEN_PHYSICAL_HEIGHT_MAX);
080                    _propertyNames.add(PROPERTY_SCREEN_PHYSICAL_HEIGHT_MIN);
081                    _propertyNames.add(PROPERTY_SCREEN_RESOLUTION_WIDTH_MAX);
082                    _propertyNames.add(PROPERTY_SCREEN_RESOLUTION_WIDTH_MIN);
083                    _propertyNames.add(PROPERTY_SCREEN_RESOLUTION_HEIGHT_MAX);
084                    _propertyNames.add(PROPERTY_SCREEN_RESOLUTION_HEIGHT_MIN);
085                    _propertyNames.add(PROPERTY_TABLET);
086    
087                    _propertyNames = Collections.unmodifiableCollection(_propertyNames);
088            }
089    
090            @Override
091            public boolean evaluateRule(MDRRule mdrRule, ThemeDisplay themeDisplay) {
092                    Device device = themeDisplay.getDevice();
093    
094                    if (device == null) {
095                            if (_log.isDebugEnabled()) {
096                                    _log.debug(
097                                            "Rule evaluation is not possible because the information " +
098                                                    "about the device is not available");
099                            }
100    
101                            return false;
102                    }
103    
104                    if (!isValidMultiValue(mdrRule, PROPERTY_OS, device.getOS())) {
105                            return false;
106                    }
107    
108                    if (!isValidBooleanValue(mdrRule, PROPERTY_TABLET, device.isTablet())) {
109                            return false;
110                    }
111    
112                    Dimensions screenPhysicalSize = device.getScreenPhysicalSize();
113    
114                    if (!isValidRangeValue(
115                                    mdrRule, PROPERTY_SCREEN_PHYSICAL_HEIGHT_MAX,
116                                    PROPERTY_SCREEN_PHYSICAL_HEIGHT_MIN,
117                                    screenPhysicalSize.getHeight())) {
118    
119                            return false;
120                    }
121    
122                    if (!isValidRangeValue(
123                                    mdrRule, PROPERTY_SCREEN_PHYSICAL_WIDTH_MAX,
124                                    PROPERTY_SCREEN_PHYSICAL_WIDTH_MIN,
125                                    screenPhysicalSize.getWidth())) {
126    
127                            return false;
128                    }
129    
130                    Dimensions screenResolution = device.getScreenResolution();
131    
132                    if (!isValidRangeValue(
133                                    mdrRule, PROPERTY_SCREEN_RESOLUTION_HEIGHT_MAX,
134                                    PROPERTY_SCREEN_RESOLUTION_HEIGHT_MIN,
135                                    screenResolution.getHeight())) {
136    
137                            return false;
138                    }
139    
140                    if (!isValidRangeValue(
141                                    mdrRule, PROPERTY_SCREEN_RESOLUTION_WIDTH_MAX,
142                                    PROPERTY_SCREEN_RESOLUTION_WIDTH_MIN,
143                                    screenResolution.getWidth())) {
144    
145                            return false;
146                    }
147    
148                    return true;
149            }
150    
151            @Override
152            public Collection<String> getPropertyNames() {
153                    return _propertyNames;
154            }
155    
156            @Override
157            public String getType() {
158                    return getHandlerType();
159            }
160    
161            protected StringBundler getLogStringBundler(
162                    MDRRule mdrRule, String value, boolean valid) {
163    
164                    StringBundler sb = new StringBundler();
165    
166                    sb.append("Rule ");
167                    sb.append(mdrRule.getNameCurrentValue());
168                    sb.append(" with the value ");
169                    sb.append(value);
170                    sb.append(" is ");
171    
172                    if (!valid) {
173                            sb.append("not ");
174                    }
175    
176                    return sb;
177            }
178    
179            protected boolean isValidBooleanValue(
180                    MDRRule mdrRule, String property, boolean value) {
181    
182                    UnicodeProperties typeSettingsProperties =
183                            mdrRule.getTypeSettingsProperties();
184    
185                    String validValueString = typeSettingsProperties.get(property);
186    
187                    if (Validator.isNull(validValueString)) {
188                            return true;
189                    }
190    
191                    boolean ruleValue = GetterUtil.getBoolean(validValueString);
192    
193                    if (ruleValue != value) {
194                            logBooleanValue(mdrRule, property, value, false);
195    
196                            return false;
197                    }
198    
199                    logBooleanValue(mdrRule, property, value, true);
200    
201                    return true;
202            }
203    
204            protected boolean isValidMultiValue(
205                    MDRRule mdrRule, String property, String value) {
206    
207                    UnicodeProperties typeSettingsProperties =
208                            mdrRule.getTypeSettingsProperties();
209    
210                    String validValueString = typeSettingsProperties.get(property);
211    
212                    if (Validator.isNull(validValueString)) {
213                            return true;
214                    }
215    
216                    String[] validValues = StringUtil.split(validValueString);
217    
218                    if (!ArrayUtil.contains(validValues, value)) {
219                            logMultiValue(mdrRule, property, value, validValues, false);
220    
221                            return false;
222                    }
223    
224                    logMultiValue(mdrRule, property, value, validValues, true);
225    
226                    return true;
227            }
228    
229            protected boolean isValidRangeValue(
230                    MDRRule mdrRule, String maxProperty, String minProperty, float value) {
231    
232                    UnicodeProperties typeSettingsProperties =
233                            mdrRule.getTypeSettingsProperties();
234    
235                    String max = typeSettingsProperties.get(maxProperty);
236                    String min = typeSettingsProperties.get(minProperty);
237    
238                    if (Validator.isNull(max) && Validator.isNull(min)) {
239                            logRangeValue(
240                                    mdrRule, maxProperty, minProperty, value, max, min, true);
241    
242                            return true;
243                    }
244    
245                    if (Validator.isNotNull(max)) {
246                            float maxFloat = GetterUtil.getFloat(max);
247    
248                            if (value > maxFloat) {
249                                    logRangeValue(
250                                            mdrRule, maxProperty, minProperty, value, max, min, false);
251    
252                                    return false;
253                            }
254    
255                            logRangeValue(
256                                    mdrRule, maxProperty, minProperty, value, max, min, true);
257                    }
258    
259                    if (Validator.isNotNull(min)) {
260                            float minFloat = GetterUtil.getFloat(min);
261    
262                            if (value < minFloat) {
263                                    logRangeValue(
264                                            mdrRule, maxProperty, minProperty, value, max, min, false);
265    
266                                    return false;
267                            }
268    
269                            logRangeValue(
270                                    mdrRule, maxProperty, minProperty, value, max, min, true);
271                    }
272    
273                    return true;
274            }
275    
276            protected void logBooleanValue(
277                    MDRRule mdrRule, String property, boolean value, boolean valid) {
278    
279                    if (!_log.isDebugEnabled()) {
280                            return;
281                    }
282    
283                    StringBundler sb = getLogStringBundler(
284                            mdrRule, String.valueOf(value), valid);
285    
286                    sb.append("the value configured for the property ");
287                    sb.append(property);
288    
289                    _log.debug(sb.toString());
290            }
291    
292            protected void logMultiValue(
293                    MDRRule mdrRule, String property, String value, String[] validValues,
294                    boolean valid) {
295    
296                    if (!_log.isDebugEnabled()) {
297                            return;
298                    }
299    
300                    StringBundler sb = getLogStringBundler(mdrRule, value, valid);
301    
302                    sb.append("among the allowed values of ");
303                    sb.append(StringUtil.merge(validValues));
304                    sb.append(" for the property \"");
305                    sb.append(property);
306                    sb.append("\"");
307    
308                    _log.debug(sb.toString());
309            }
310    
311            protected void logRangeValue(
312                    MDRRule mdrRule, String maxProperty, String minProperty, float value,
313                    String max, String min, boolean valid) {
314    
315                    if (!_log.isDebugEnabled()) {
316                            return;
317                    }
318    
319                    StringBundler sb = getLogStringBundler(
320                            mdrRule, String.valueOf(value), valid);
321    
322                    sb.append("within the allowed range");
323    
324                    if (Validator.isNotNull(max) && Validator.isNotNull(min)) {
325                            sb.append(" of ");
326                            sb.append(min);
327                            sb.append(" and ");
328                            sb.append(max);
329                            sb.append(" for the minimum property \"");
330                            sb.append(minProperty);
331                            sb.append("\" and the maximum property \"");
332                            sb.append(maxProperty);
333                            sb.append("\"");
334                    }
335    
336                    _log.debug(sb.toString());
337            }
338    
339            private static Log _log = LogFactoryUtil.getLog(SimpleRuleHandler.class);
340    
341            private Collection<String> _propertyNames;
342    
343    }