]> git.basschouten.com Git - openhab-addons.git/blob
e2cf730ffe095916812225c5308956ad2ddb3db0
[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             if (result != null) {
95                 return getPropertyValue(result, properties, nestedIndex + 1);
96             } else {
97                 throw new NullPointerException();
98             }
99         }
100         return result;
101     }
102
103     /**
104      * Converts the string to a getter property.
105      */
106     private static String toGetterString(String str) {
107         StringBuilder sb = new StringBuilder();
108         sb.append("get");
109         sb.append(Character.toTitleCase(str.charAt(0)));
110         sb.append(str.substring(1));
111         return sb.toString();
112     }
113 }