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

org.opentripplanner.model.base.ValueObjectToStringBuilder Maven / Gradle / Ivy

package org.opentripplanner.model.base;

import org.opentripplanner.transit.raptor.util.TimeUtils;

import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.time.Duration;
import java.util.Locale;
import java.util.function.Function;

/**
 * Use this to-string-builder to build value objects. A
 * [ValueObject](http://wiki.c2.com/?ValueObject) is usually a small object/class with
 * a few fields. We want the {@code toString()} to be small and easy to read. The
 * text should be short and without class and field name prefixes.
 * 

* Examples: *

 * - Money:  "5 kr", "USD 100"
 * - Time:   "2020-01-15", "3h3m5s", "14:23:59"
 * - Coordinate:  "(60.23451, 10.345678)"
 * 
*

* {@code ClassName{field1:value, field2:value, ..., NOT-SET:[fieldX, ...]}} *

* Use the {@link #of()} factory method to create a instance of this class. */ public class ValueObjectToStringBuilder { private static final String FIELD_SEPARATOR = " "; private static final DecimalFormatSymbols DECIMAL_SYMBOLS = DecimalFormatSymbols.getInstance( Locale.US ); private final StringBuilder sb = new StringBuilder(); private DecimalFormat coordinateFormat; private DecimalFormat integerFormat; private DecimalFormat decimalFormat; boolean skipSep = true; /** Use factory method: {@link #of()}. */ private ValueObjectToStringBuilder() { } /** * Create a new toString builder for a [ValueObject](http://wiki.c2.com/?ValueObject) type. * The builder will NOT include metadata(class and field names) when building the string. */ public static ValueObjectToStringBuilder of() { return new ValueObjectToStringBuilder(); } /* General purpose formatters */ public ValueObjectToStringBuilder addNum(Number num) { return addIt(num, it -> formatNumber(num)); } public ValueObjectToStringBuilder addNum(Number num, String unit) { return addIt(num, it -> formatNumber(it) + unit); } public ValueObjectToStringBuilder addBool(Boolean value, String ifTrue, String ifFalse) { return addIt(value, it -> it ? ifTrue : ifFalse); } public ValueObjectToStringBuilder addStr(String value) { return addIt(value, it -> "'" + it + "'"); } public ValueObjectToStringBuilder addEnum(Enum value) { return addIt(value, Enum::name); } public ValueObjectToStringBuilder addObj(Object obj) { return addIt(obj, Object::toString); } /** * A text/labels to your string. No separator character is writen to the buffer * before or after the label - hence you need to include white space in the label if you * want it. */ public ValueObjectToStringBuilder addLbl(String label) { sb.append(label); skipSep = true; return this; } /* Special purpose formatters */ /** * Add a Coordinate location: (longitude, latitude). The coordinate is * printed with a precision of 5 digits after the period. The precision level used * in OTP is 7 digits, so 2 coordinates that appear to be equal (by toString) might not be * exactly equals. */ public ValueObjectToStringBuilder addCoordinate(Number lat, Number lon) { return addIt("(" + formatCoordinate(lat) + ", " + formatCoordinate(lon) + ")"); } /** * Add time in seconds since midnight. Format: HH:mm:ss. */ public ValueObjectToStringBuilder addServiceTime(int secondsPastMidnight) { // Use a NOT_SET value witch is unlikely to be used return addServiceTime(secondsPastMidnight, -87_654_321); } /** * Add time in seconds since midnight. Format: HH:mm:ss. Ignore if not set. */ public ValueObjectToStringBuilder addServiceTime(int secondsPastMidnight, int notSet) { return addIt(TimeUtils.timeToStrLong(secondsPastMidnight, notSet)); } /** * Add a duration to the string in format like '3h4m35s'. Each component (hours, minutes, and or * seconds) is only added if they are not zero {@code 0}. This is the same format as the * {@link Duration#toString()}, but without the 'PT' prefix. */ public ValueObjectToStringBuilder addDuration(Integer durationSeconds) { return addIt(durationSeconds, TimeUtils::durationToStr); } @Override public String toString() { return sb.toString(); } /* private methods */ private ValueObjectToStringBuilder addIt(String value) { return addIt(value, it -> it); } private ValueObjectToStringBuilder addIt(T value, Function mapToString) { if (skipSep) { skipSep = false; } else { sb.append(FIELD_SEPARATOR); } sb.append(value == null ? "null" : mapToString.apply(value)); return this; } String formatCoordinate(Number value) { if(coordinateFormat == null) { coordinateFormat = new DecimalFormat("0.0####", DECIMAL_SYMBOLS); } // This need to be null-safe, because one of the coordinates in // #addCoordinate(String name, Number lat, Number lon) could be null. return value == null ? "null" : coordinateFormat.format(value); } String formatNumber(Number value) { if (value == null) { return "null"; } if(value instanceof Integer || value instanceof Long || value instanceof BigInteger) { if(integerFormat == null) { integerFormat = new DecimalFormat("#,##0", DECIMAL_SYMBOLS); } return integerFormat.format(value); } if(decimalFormat == null) { decimalFormat = new DecimalFormat("#,##0.0##", DECIMAL_SYMBOLS); } return decimalFormat.format(value); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy