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

org.gradle.performance.measure.Units Maven / Gradle / Ivy

There is a newer version: 8.11.1
Show newest version
/*
 * Copyright 2012 the original author or authors.
 *
 * 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
 *
 *      http://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 org.gradle.performance.measure;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class Units implements Comparable> {
    private final Class type;
    private final String displaySingular;
    private final String displayPlural;

    protected Units(Class type, String displaySingular, String displayPlural) {
        this.type = type;
        this.displaySingular = displaySingular;
        this.displayPlural = displayPlural;
    }

    /**
     * Creates the base units for a given quantity.
     */
    public static  Units base(Class type, String displaySingular) {
        return new BaseUnits<>(type, displaySingular, displaySingular);
    }

    /**
     * Creates the base units for a given quantity.
     */
    public static  Units base(Class type, String displaySingular, String displayPlural) {
        return new BaseUnits<>(type, displaySingular, displayPlural);
    }

    protected Class getType() {
        return type;
    }

    @Override
    public String toString() {
        return displayPlural;
    }

    /**
     * Creates units that are some multiple of this units.
     */
    public abstract Units times(long value, String displaySingular, String displayPlural);

    /**
     * Creates units that are some multiple of this units.
     */
    public Units times(long value, String displaySingular) {
        return times(value, displaySingular, displaySingular);
    }

    protected abstract Units getBaseUnits();

    protected abstract List> getUnitsForQuantity();

    protected abstract BigDecimal getFactor();

    protected abstract BigDecimal scaleTo(BigDecimal value, Units units);

    protected String format(BigDecimal value) {
        return value.compareTo(BigDecimal.ONE) == 0 ? displaySingular : displayPlural;
    }

    private static class BaseUnits extends Units {
        private final List> units = new ArrayList<>();

        protected BaseUnits(Class type, String displaySingular, String displayPlural) {
            super(type, displaySingular, displayPlural);
            units.add(this);
        }

        @Override
        public BigDecimal scaleTo(BigDecimal value, Units units) {
            if (units == this) {
                return value;
            }
            ScaledUnits scaledUnits = (ScaledUnits) units;
            return value.divide(scaledUnits.factor, 6, RoundingMode.HALF_UP).stripTrailingZeros();
        }

        @Override
        protected List> getUnitsForQuantity() {
            return units;
        }

        @Override
        public Units times(long value, String displaySingular, String displayPlural) {
            return new ScaledUnits<>(this, displaySingular, displayPlural, BigDecimal.valueOf(value));
        }

        @Override
        protected Units getBaseUnits() {
            return this;
        }

        @Override
        protected BigDecimal getFactor() {
            return BigDecimal.ONE;
        }

        @Override
        public int compareTo(Units o) {
            if (o == this) {
                return 0;
            }
            if (o.getType() != getType()) {
                throw new IllegalArgumentException(String.format("Cannot compare units of %s with units of %s.", getType(), o.getType()));
            }
            return -1;
        }

        public void add(ScaledUnits units) {
            this.units.add(units);
            Collections.sort(this.units);
        }
    }

    private static class ScaledUnits extends Units {
        private final BaseUnits baseUnits;
        private final BigDecimal factor;

        public ScaledUnits(BaseUnits baseUnits, String displaySingular, String displayPlural, BigDecimal factor) {
            super(baseUnits.getType(), displaySingular, displayPlural);
            assert factor.compareTo(BigDecimal.ONE) > 0;
            this.baseUnits = baseUnits;
            this.factor = factor;
            baseUnits.add(this);
        }

        @Override
        public Units times(long value, String displaySingular, String displayPlural) {
            return new ScaledUnits<>(baseUnits, displaySingular, displayPlural, factor.multiply(BigDecimal.valueOf(value)));
        }

        @Override
        public BigDecimal scaleTo(BigDecimal value, Units units) {
            if (units == this) {
                return value;
            }
            if (units.equals(baseUnits)) {
                return value.multiply(factor);
            }
            ScaledUnits other = (ScaledUnits) units;
            return value.multiply(factor).divide(other.factor, 6, RoundingMode.HALF_UP).stripTrailingZeros();
        }

        @Override
        protected List> getUnitsForQuantity() {
            return baseUnits.getUnitsForQuantity();
        }

        @Override
        protected Units getBaseUnits() {
            return baseUnits;
        }

        @Override
        protected BigDecimal getFactor() {
            return factor;
        }

        @Override
        public int compareTo(Units o) {
            if (o.getType() != getType()) {
                throw new IllegalArgumentException(String.format("Cannot compare units of %s with units of %s.", getType(), o.getType()));
            }
            if (o.equals(baseUnits)) {
                return 1;
            }
            ScaledUnits other = (ScaledUnits) o;
            if (!other.baseUnits.equals(baseUnits)) {
                throw new IllegalArgumentException("Cannot compare units with different base units.");
            }
            return factor.compareTo(other.factor);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy