]> git.basschouten.com Git - openhab-addons.git/blob
41dc016d5a7bac30e9fc0500488c5814edade3a5
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.astro.internal.util;
14
15 import java.lang.reflect.Method;
16 import java.math.BigDecimal;
17 import java.math.RoundingMode;
18 import java.time.ZoneId;
19 import java.time.ZonedDateTime;
20 import java.util.Calendar;
21 import java.util.GregorianCalendar;
22 import java.util.TimeZone;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.astro.internal.config.AstroChannelConfig;
27 import org.openhab.core.library.types.DateTimeType;
28 import org.openhab.core.library.types.DecimalType;
29 import org.openhab.core.library.types.StringType;
30 import org.openhab.core.thing.ChannelUID;
31 import org.openhab.core.types.State;
32 import org.openhab.core.types.UnDefType;
33
34 /**
35  * Methods to get the value from a property of an object.
36  *
37  * @author Gerhard Riegler - Initial contribution
38  * @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
39  * @author Christoph Weitkamp - Introduced UoM
40  */
41 @NonNullByDefault
42 public class PropertyUtils {
43
44     /** Constructor */
45     private PropertyUtils() {
46         throw new IllegalAccessError("Non-instantiable");
47     }
48
49     /**
50      * Returns the state of the channel.
51      */
52     public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance, ZoneId zoneId)
53             throws Exception {
54         Object value = getPropertyValue(channelUID, instance);
55         if (value == null) {
56             return UnDefType.UNDEF;
57         } else if (value instanceof State) {
58             return (State) value;
59         } else if (value instanceof Calendar) {
60             Calendar cal = (Calendar) value;
61             GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal, config);
62             cal.setTimeZone(TimeZone.getTimeZone(zoneId));
63             ZonedDateTime zoned = gregorianCal.toZonedDateTime().withFixedOffsetZone();
64             return new DateTimeType(zoned);
65         } else if (value instanceof Number) {
66             BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
67             return new DecimalType(decimalValue);
68         } else if (value instanceof String || value instanceof Enum) {
69             return new StringType(value.toString());
70         } else {
71             throw new IllegalStateException("Unsupported value type " + value.getClass().getSimpleName());
72         }
73     }
74
75     /**
76      * Returns the property value from the object instance, nested properties are possible. If the propertyName is for
77      * example rise.start, the methods getRise().getStart() are called.
78      */
79     public static @Nullable Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception {
80         String[] properties = channelUID.getId().split("#");
81         return getPropertyValue(instance, properties, 0);
82     }
83
84     /**
85      * Iterates through the nested properties and returns the getter value.
86      */
87     @SuppressWarnings("all")
88     private static @Nullable Object getPropertyValue(Object instance, String[] properties, int nestedIndex)
89             throws Exception {
90         String propertyName = properties[nestedIndex];
91         Method m = instance.getClass().getMethod(toGetterString(propertyName), null);
92         Object result = m.invoke(instance, (Object[]) null);
93         if (nestedIndex + 1 < properties.length) {
94             return getPropertyValue(result, properties, nestedIndex + 1);
95         }
96         return result;
97     }
98
99     /**
100      * Converts the string to a getter property.
101      */
102     private static String toGetterString(String str) {
103         StringBuilder sb = new StringBuilder();
104         sb.append("get");
105         sb.append(Character.toTitleCase(str.charAt(0)));
106         sb.append(str.substring(1));
107         return sb.toString();
108     }
109 }