package de.hftstuttgart.cityunits.model; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import javax.measure.Quantity; import javax.measure.Unit; import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.Platform; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; import org.eclipse.core.runtime.Status; import tech.units.indriya.format.SimpleQuantityFormat; import tech.units.indriya.quantity.Quantities; /** * A NullableQuantity wraps a javax.measure.Quantity having * a numerical value that is either a Double, a Long, * or null. The latter case represents an unknown numerical * value of a specific unit. On the other hand, the javax.measure.Unit * of the quantity is always defined. */ public class NullableQuantity { static { // TODO Implement specific QuantityFormat to enable custom number format? // ensure that editing, (de)serialization and default values of units all work // with the same number format (Decimal point etc.) Locale.setDefault(Locale.ENGLISH); // specific additional units for urban simulation like TON (t), PARTS_PER_MILLION (ppm), DECIBEL (dB) UrbanSimulationUnits.getInstance(); } public static NullableQuantity create(String str) { NullableQuantity newNullableQuantity = null; try { NumberFormat.getInstance().parse(str); newNullableQuantity = new NullableQuantity(str); } catch (final ParseException ex) { // no number value present: create NullQuantity just with unit try { NullableQuantity dummy = new NullableQuantity("1 " + str); //$NON-NLS-1$ newNullableQuantity = new NullQuantity(dummy.getUnit()); } catch (final IllegalArgumentException ex1) { // Unit could not be parsed Platform.getLog(NullableQuantity.class).warn("Unit '" + str + "' could not be parsed!", ex); } } catch (final IllegalArgumentException ex) { // Quantity could not be parsed Platform.getLog(NullableQuantity.class).warn("Quantity '" + str + "' could not be parsed!", ex); } return newNullableQuantity; } public static NullableQuantity create(Number number, Unit unit) { return number == null ? new NullQuantity(unit) : new NullableQuantity(number, unit); } private final Quantity quantity; private NullableQuantity(String str) { quantity = Quantities.getQuantity(str); } private NullableQuantity(Number number, Unit unit) { quantity = Quantities.getQuantity(number, unit); } /** * In case of an unknown numerical value of the quantity an empty Optional is returned via subclass. * @return the wrapped javax.measure.Quantity if its numerical value is present */ public Optional> getQuantity() { return Optional.of(quantity); } /** * @return numerical value of the wrapped javax.measure.Quantity if present */ public Optional getNumber() { return getQuantity().map(Quantity::getValue); } public Unit getUnit() { return quantity.getUnit(); } @Override public String toString() { return SimpleQuantityFormat.getInstance().format(quantity); } private static class NullQuantity extends NullableQuantity { public NullQuantity(Unit unit) { super(1, unit); } public Optional> getQuantity() { return Optional.empty(); } @Override public String toString() { return " " + getUnit().toString(); } } }