org.eclipse.smarthome.binding.astro.internal.util.PropertyUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.smarthome.binding.astro.internal.util.PropertyUtils.java

Source

/**
 * Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.smarthome.binding.astro.internal.util;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.binding.astro.internal.config.AstroChannelConfig;
import org.eclipse.smarthome.core.i18n.TimeZoneProvider;
import org.eclipse.smarthome.core.library.types.DateTimeType;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.StringType;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.core.types.UnDefType;

/**
 * Methods to get the value from a property of an object.
 *
 * @author Gerhard Riegler - Initial contribution
 * @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
 * @author Christoph Weitkamp - Introduced UoM
 */
public class PropertyUtils {

    /** Constructor */
    private PropertyUtils() {
        throw new IllegalAccessError("Non-instantiable");
    }

    private static TimeZoneProvider timeZoneProvider;

    /**
     * Returns the state of the channel.
     */
    public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance)
            throws Exception {
        Object value = getPropertyValue(channelUID, instance);
        if (value == null) {
            return UnDefType.UNDEF;
        } else if (value instanceof State) {
            return (State) value;
        } else if (value instanceof Calendar) {
            Calendar cal = (Calendar) value;
            GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal, config);
            cal.setTimeZone(TimeZone.getTimeZone(timeZoneProvider.getTimeZone()));
            ZonedDateTime zoned = gregorianCal.toZonedDateTime().withFixedOffsetZone();
            return new DateTimeType(zoned);
        } else if (value instanceof Number) {
            BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
            return new DecimalType(decimalValue);
        } else if (value instanceof String || value instanceof Enum) {
            return new StringType(value.toString());
        } else {
            throw new IllegalStateException("Unsupported value type " + value.getClass().getSimpleName());
        }
    }

    public static void setTimeZone(TimeZoneProvider zone) {
        PropertyUtils.timeZoneProvider = zone;
    }

    public static void unsetTimeZone() {
        PropertyUtils.timeZoneProvider = null;
    }

    /**
     * Returns the property value from the object instance, nested properties are possible. If the propertyName is for
     * example rise.start, the methods getRise().getStart() are called.
     */
    public static Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception {
        String[] properties = StringUtils.split(channelUID.getId(), "#");
        return getPropertyValue(instance, properties, 0);
    }

    /**
     * Iterates through the nested properties and returns the getter value.
     */
    @SuppressWarnings("all")
    private static Object getPropertyValue(Object instance, String[] properties, int nestedIndex) throws Exception {
        String propertyName = properties[nestedIndex];
        Method m = instance.getClass().getMethod(toGetterString(propertyName), null);
        Object result = m.invoke(instance, (Object[]) null);
        if (nestedIndex + 1 < properties.length) {
            return getPropertyValue(result, properties, nestedIndex + 1);
        }
        return result;
    }

    /**
     * Converts the string to a getter property.
     */
    private static String toGetterString(String str) {
        StringBuilder sb = new StringBuilder();
        sb.append("get");
        sb.append(Character.toTitleCase(str.charAt(0)));
        sb.append(str.substring(1));
        return sb.toString();
    }

}