All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.hansolo.toolbox.unit.Converter Maven / Gradle / Ivy

Go to download

Toolbox contains a collection of useful tools incl. events, properties, helper classes etc.

There is a newer version: 21.0.15
Show newest version
/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright 2016-2021 Gerrit Grunwald.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.hansolo.toolbox.unit;

import eu.hansolo.toolbox.Helper;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static eu.hansolo.toolbox.Constants.COLON;
import static eu.hansolo.toolbox.Constants.CURLY_BRACKET_CLOSE;
import static eu.hansolo.toolbox.Constants.CURLY_BRACKET_OPEN;
import static eu.hansolo.toolbox.Constants.QUOTES;


public class Converter {
    public static final  String[]                          ABBREVIATIONS      = { "k", "M", "G", "T", "P", "E", "Z", "Y" };
    public static final  int                               MAX_NO_OF_DECIMALS = 12;
    private static final EnumMap BASE_UNITS         = new EnumMap<>(Category.class) {
        {
            put(Category.ACCELERATION, UnitDefinition.METER_PER_SQUARE_SECOND);
            put(Category.ANGLE, UnitDefinition.RADIAN);
            put(Category.AREA, UnitDefinition.SQUARE_METER);
            put(Category.CURRENT, UnitDefinition.AMPERE);
            put(Category.DATA, UnitDefinition.BIT);
            put(Category.ELECTRIC_CHARGE, UnitDefinition.ELEMENTARY_CHARGE);
            put(Category.ENERGY, UnitDefinition.JOULE);
            put(Category.FORCE, UnitDefinition.NEWTON);
            put(Category.HUMIDITY, UnitDefinition.PERCENTAGE);
            put(Category.LENGTH, UnitDefinition.METER);
            put(Category.LUMINANCE, UnitDefinition.CANDELA_SQUARE_METER);
            put(Category.LUMINOUS_FLUX, UnitDefinition.LUX);
            put(Category.MASS, UnitDefinition.KILOGRAM);
            put(Category.PRESSURE, UnitDefinition.PASCAL);
            put(Category.SPEED, UnitDefinition.METER_PER_SECOND);
            put(Category.TEMPERATURE, UnitDefinition.KELVIN);
            put(Category.TEMPERATURE_GRADIENT, UnitDefinition.KELVIN_PER_SECOND);
            put(Category.TIME, UnitDefinition.SECOND);
            put(Category.TORQUE, UnitDefinition.NEWTON_METER);
            put(Category.VOLUME, UnitDefinition.CUBIC_METER);
            put(Category.VOLTAGE, UnitDefinition.VOLT);
            put(Category.WORK, UnitDefinition.WATT);
            put(Category.BLOOD_GLUCOSE, UnitDefinition.MILLIMOL_PER_LITER);
        }
    };
    private              UnitDefinition                    baseUnitDefinition;
    private              Unit                              bean;
    private              Locale                            locale;
    private              int                               decimals;
    private              String                            formatString;


    // ******************** Constructors **************************************
    public Converter(final Category category) {
        this(category, BASE_UNITS.get(category));
    }
    public Converter(final Category category, final UnitDefinition baseUnitDefinition) {
        this.baseUnitDefinition = baseUnitDefinition;
        this.bean               = BASE_UNITS.get(category).UNIT;
        this.locale             = Locale.US;
        this.decimals           = 2;
        this.formatString       = "%.2f";
    }


    // ******************** Methods *******************************************
    public Category getCategory() { return bean.getCategory(); }

    public UnitDefinition getBaseUnitDefinition() { return baseUnitDefinition; }
    public void setBaseUnitDefinition(final UnitDefinition baseUnitDefinition) {
        if (baseUnitDefinition.UNIT.getCategory() == getCategory()) { this.baseUnitDefinition = baseUnitDefinition; }
    }

    public BigDecimal getFactor() { return bean.getFactor(); }

    public BigDecimal getOffset() { return bean.getOffset(); }

    public String getUnitName() { return bean.getUnitName(); }

    public String getUnitShort() { return bean.getUnitShort(); }

    public Locale getLocale() { return locale; }
    public void setLocale(final Locale locale) { this.locale = locale; }

    public int getDecimals() { return decimals; }
    public void setDecimals(final int decimals) {
        if (decimals < 0 ) {
            this.decimals = 0;
        } else if (decimals > MAX_NO_OF_DECIMALS) {
            this.decimals = MAX_NO_OF_DECIMALS;
        } else {
            this.decimals = decimals;
        }
        formatString = new StringBuilder("%.").append(this.decimals).append("f").toString();
    }

    public String getFormatString() { return formatString; }

    public final boolean isActive() { return bean.isActive(); }
    public final void setActive(final boolean active) { bean.setActive(active); }

    public final double convert(final double value, final UnitDefinition unitDefinition) {
        if (unitDefinition.UNIT.getCategory() != getCategory()) { throw new IllegalArgumentException("units have to be of the same type"); }
        return ((((value + baseUnitDefinition.UNIT.getOffset().doubleValue()) * baseUnitDefinition.UNIT.getFactor().doubleValue()) + bean.getOffset().doubleValue()) * bean.getFactor().doubleValue()) / unitDefinition.UNIT
        .getFactor().doubleValue() - unitDefinition.UNIT.getOffset().doubleValue();
    }

    public final String convertToString(final double value, final UnitDefinition unitDefinition) {
        return String.join(" ", String.format(locale, formatString, convert(value, unitDefinition)), unitDefinition.UNIT.getUnitShort());
    }

    public final double convertToBaseUnit(final double value, final UnitDefinition unitDefinition) {
        return ((((value + unitDefinition.UNIT.getOffset().doubleValue()) * unitDefinition.UNIT.getFactor().doubleValue()) + bean.getOffset().doubleValue()) * bean.getFactor().doubleValue()) / baseUnitDefinition.UNIT
        .getFactor().doubleValue() - baseUnitDefinition.UNIT.getOffset().doubleValue();
    }

    public final Pattern getPattern() {
        final StringBuilder PATTERN_BUILDER = new StringBuilder();
        PATTERN_BUILDER.append("^([-+]?\\d*\\.?\\d*)\\s?(");

        for (UnitDefinition unitDefinition : UnitDefinition.values()) {
            PATTERN_BUILDER.append(unitDefinition.UNIT.getUnitShort().replace("*", "\\*")).append("|");
        }

        PATTERN_BUILDER.deleteCharAt(PATTERN_BUILDER.length() - 1);

        //PATTERN_BUILDER.append("){1}$");
        PATTERN_BUILDER.append(")?$");

        return Pattern.compile(PATTERN_BUILDER.toString());
    }

    public final List getAvailableUnits(final Category category) {
        return getAllUnitDefinitions().get(category).stream().map(unitDefinition -> unitDefinition.UNIT).toList();
    }

    public final EnumMap> getAllUnitDefinitions() {
        final EnumMap> UNIT_TYPES    = new EnumMap<>(Category.class);
        final ArrayList                          CATEGORY_LIST = new ArrayList<>(Category.values().length);
        CATEGORY_LIST.addAll(Arrays.asList(Category.values()));
        CATEGORY_LIST.forEach(category -> UNIT_TYPES.put(category, new ArrayList<>()));
        for (UnitDefinition unitDefinition : UnitDefinition.values()) {
            UNIT_TYPES.get(unitDefinition.UNIT.getCategory()).add(unitDefinition);
        }
        return UNIT_TYPES;
    }

    public final EnumMap> getAllActiveUnitDefinitions() {
        final EnumMap> UNIT_DEFINITIONS = new EnumMap<>(Category.class);
        final ArrayList                          CATEGORY_LIST    = new ArrayList<>(Category.values().length);
        CATEGORY_LIST.addAll(Arrays.asList(Category.values()));
        CATEGORY_LIST.forEach(category -> UNIT_DEFINITIONS.put(category, new ArrayList<>()));
        for (UnitDefinition unitDefinition : UnitDefinition.values()) {
            if (unitDefinition.UNIT.isActive()) { UNIT_DEFINITIONS.get(unitDefinition.UNIT.getCategory()).add(unitDefinition); }
        }
        return UNIT_DEFINITIONS;
    }

    public static final String format(final double number, final int decimals) {
        return format(number, Helper.clamp(0, 12, decimals), Locale.US);
    }
    public static final String format(final double number, final int decimals, final Locale locale) {
        String formatString = new StringBuilder("%.").append(Helper.clamp(0, 12, decimals)).append("f").toString();
        double value;
        for(int i = ABBREVIATIONS.length - 1 ; i >= 0; i--) {
            value = Math.pow(1000, i + 1.0);
            if (Double.compare(number, -value) <= 0 || Double.compare(number, value) >= 0) {
                return String.format(locale, formatString, (number / value)) + ABBREVIATIONS[i];
            }
        }
        return String.format(locale, formatString, number);
    }


    @Override public String toString() {
        return new StringBuilder().append(CURLY_BRACKET_OPEN)
                                  .append(QUOTES).append("category").append(QUOTES).append(COLON).append(QUOTES).append(getCategory()).append(QUOTES)
                                  .append(CURLY_BRACKET_CLOSE)
                                  .toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy