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

com.pervasivecode.utils.measure.ScalingFormatter Maven / Gradle / Ivy

Go to download

Classes for using and formatting data and data-rate values in the JSR 363 Units of Measurement API.

The newest version!
package com.pervasivecode.utils.measure;

import static com.google.common.base.Preconditions.checkNotNull;
import java.text.NumberFormat;
import javax.measure.Quantity;
import javax.measure.Unit;
import javax.measure.format.UnitFormat;
import tec.uom.lib.common.BinaryPrefix;
import tec.uom.se.format.SimpleUnitFormat;
import tec.uom.se.unit.MetricPrefix;
import tec.uom.se.unit.ProductUnit;
import tec.uom.se.unit.Units;

/**
 * Formatter for {@link Quantity} objects that applies scale prefixes to make the formatted value
 * easier to read.
 * 

* Example: formatting a value of 12,000 meters for the US locale and the SI prefix system would * result in a format of "12 km" since the value would be scaled to kilometers. *

* Note: The system of scale prefixes, the number-value formatter, and the unit-label provider are * all parameterized, to enable formatting for various locales and prefix systems. This means that * callers will need to provide an appropriately localized NumberFormat and UnitLabelProvider, as * well as a QuantityPrefixSelector capable of applying the caller's desired system of prefixes as * appropriate. * * @param The type of measurement that the formatter is able to format. Example: * {@link javax.measure.quantity.Mass Mass} * @see ScalingFormatters */ public class ScalingFormatter> implements QuantityFormatter { private final QuantityPrefixSelector prefixSelector; private final Unit baseUnit; private final NumberFormat numberFormat; private final UnitFormat unitFormat; /** * Set up a ScalingFormatter with the specified scaling and formatting behavior. * * @param baseInformationUnit The fundamental unit of this type of measurement, e.g. * {@link Units#OHM OHM}. * @param prefixSelector This decides which scale prefix is appropriate to use for any given value * of any given magnitude. * @param numberFormat This constructs the correct String representation for the numeric portion * of the Quantity, after it has been scaled by the {@code prefixSelector}. */ public ScalingFormatter(Unit baseInformationUnit, QuantityPrefixSelector prefixSelector, NumberFormat numberFormat) { this.baseUnit = checkNotNull(baseInformationUnit); this.prefixSelector = checkNotNull(prefixSelector); this.numberFormat = checkNotNull(numberFormat); this.unitFormat = SimpleUnitFormat.getInstance(); } /** * Set up a ScalingFormatter with the specified scaling and formatting behavior. * * @param baseInformationUnit The fundamental unit of this type of measurement, e.g. * {@link Units#OHM OHM}. * @param prefixSelector This decides which scale prefix is appropriate to use for any given value * of any given magnitude. * @param numberFormat This constructs the correct String representation for the numeric portion * of the Quantity, after it has been scaled by the {@code prefixSelector}. * @param unitLabelProvider Provider of additional unit+prefix labels for units and prefixes other * than the base SI units and prefixes directly supported by {@link SimpleUnitFormat}. * (Note that unit symbols for compound units are not correctly generated by * {@link ProductUnit}, e.g. "m/s" for {@link Units#METRE METRE} divided by * {@link Units#SECOND SECOND}, so they must be explicitly provided here.) */ public ScalingFormatter(Unit baseInformationUnit, QuantityPrefixSelector prefixSelector, NumberFormat numberFormat, UnitLabelProvider unitLabelProvider) { this(baseInformationUnit, prefixSelector, numberFormat); UnitFormatLabelSetter labelSetter = new UnitFormatLabelSetter(unitLabelProvider, unitFormat); labelSetter.setBaseUnitLabel(baseInformationUnit); labelSetter.setSiUnitLabels(baseInformationUnit); labelSetter.setIecBinaryUnitLabels(baseInformationUnit); } /** * Scale and format a value. * * @param measure The value to scale and format. * @return The scaled and formatted String representation of {@code measure}. */ @Override public String format(Quantity measure) { Quantity m = prefixSelector.selectBestPrefix(measure, baseUnit); StringBuilder sb = new StringBuilder(); sb.append(this.numberFormat.format(m.getValue().doubleValue())); sb.append(' '); sb.append(this.unitFormat.format(m.getUnit())); return sb.toString(); } /** * Populate a SimpleUnitFormat instance with labels that include prefixes from the SI and IEC * Binary systems of prefixes. * * @param

The kind of measurement that this instance will provide labels for. Example: * {@link javax.measure.quantity.Area Area} */ private static class UnitFormatLabelSetter

> { private final UnitLabelProvider

unitLabels; private final UnitFormat fmt; public UnitFormatLabelSetter(UnitLabelProvider

unitLabels, UnitFormat fmt) { this.unitLabels = unitLabels; this.fmt = fmt; } private void setLabel(Unit

unit) { String label = unitLabels.getLabel(unit); if (label != null) { fmt.label(unit, label); } } public void setBaseUnitLabel(Unit

unit) { setLabel(unit); } // TODO consider removing this hardcoded list of prefixes in favor of querying UnitLabelProvider // instances for the list of all prefixes which they can provide. public void setSiUnitLabels(Unit

baseUnit) { setLabel(MetricPrefix.KILO(baseUnit)); setLabel(MetricPrefix.MEGA(baseUnit)); setLabel(MetricPrefix.GIGA(baseUnit)); setLabel(MetricPrefix.TERA(baseUnit)); setLabel(MetricPrefix.PETA(baseUnit)); setLabel(MetricPrefix.EXA(baseUnit)); setLabel(MetricPrefix.ZETTA(baseUnit)); setLabel(MetricPrefix.YOTTA(baseUnit)); } public void setIecBinaryUnitLabels(Unit

baseUnit) { setLabel(BinaryPrefix.KIBI(baseUnit)); setLabel(BinaryPrefix.MEBI(baseUnit)); setLabel(BinaryPrefix.GIBI(baseUnit)); setLabel(BinaryPrefix.TEBI(baseUnit)); setLabel(BinaryPrefix.PEBI(baseUnit)); setLabel(BinaryPrefix.EXBI(baseUnit)); setLabel(BinaryPrefix.ZEBI(baseUnit)); setLabel(BinaryPrefix.YOBI(baseUnit)); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy