]> git.basschouten.com Git - openhab-addons.git/blob
7cccf4269ce0f796e7f9ed14c4d1c294b6ce9454
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.ArrayList;
21 import java.util.Calendar;
22 import java.util.GregorianCalendar;
23 import java.util.List;
24 import java.util.Objects;
25 import java.util.TimeZone;
26
27 import org.eclipse.jdt.annotation.NonNullByDefault;
28 import org.eclipse.jdt.annotation.Nullable;
29 import org.openhab.binding.astro.internal.config.AstroChannelConfig;
30 import org.openhab.core.library.types.DateTimeType;
31 import org.openhab.core.library.types.DecimalType;
32 import org.openhab.core.library.types.StringType;
33 import org.openhab.core.thing.ChannelUID;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.UnDefType;
36
37 /**
38  * Methods to get the value from a property of an object.
39  *
40  * @author Gerhard Riegler - Initial contribution
41  * @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
42  * @author Christoph Weitkamp - Introduced UoM
43  */
44 @NonNullByDefault
45 public class PropertyUtils {
46
47     /** Constructor */
48     private PropertyUtils() {
49         throw new IllegalAccessError("Non-instantiable");
50     }
51
52     /**
53      * Returns the state of the channel.
54      */
55     public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance, ZoneId zoneId)
56             throws Exception {
57         Object value = getPropertyValue(channelUID, instance);
58         if (value == null) {
59             return UnDefType.UNDEF;
60         } else if (value instanceof State) {
61             return (State) value;
62         } else if (value instanceof Calendar) {
63             Calendar cal = (Calendar) value;
64             GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal, config);
65             cal.setTimeZone(TimeZone.getTimeZone(zoneId));
66             ZonedDateTime zoned = gregorianCal.toZonedDateTime().withFixedOffsetZone();
67             return new DateTimeType(zoned);
68         } else if (value instanceof Number) {
69             BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
70             return new DecimalType(decimalValue);
71         } else if (value instanceof String || value instanceof Enum) {
72             return new StringType(value.toString());
73         } else {
74             throw new IllegalStateException("Unsupported value type " + value.getClass().getSimpleName());
75         }
76     }
77
78     /**
79      * Returns the property value from the object instance, nested properties are possible. If the propertyName is for
80      * example rise.start, the methods getRise().getStart() are called.
81      */
82     private static @Nullable Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception {
83         ArrayList<String> properties = new ArrayList<>(List.of(channelUID.getId().split("#")));
84         return getPropertyValue(instance, properties);
85     }
86
87     /**
88      * Iterates through the nested properties and returns the getter value.
89      */
90     @SuppressWarnings("all")
91     private static @Nullable Object getPropertyValue(Object instance, List<String> properties) throws Exception {
92         String propertyName = properties.remove(0);
93         Method m = instance.getClass().getMethod(toGetterString(propertyName), null);
94         Object result = m.invoke(instance, (Object[]) null);
95         if (!properties.isEmpty()) {
96             Objects.requireNonNull(result);
97             return getPropertyValue(result, properties);
98         }
99         return result;
100     }
101
102     /**
103      * Converts the string to a getter property.
104      */
105     private static String toGetterString(String str) {
106         StringBuilder sb = new StringBuilder();
107         sb.append("get");
108         sb.append(Character.toTitleCase(str.charAt(0)));
109         sb.append(str.substring(1));
110         return sb.toString();
111     }
112 }