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 java.time.Duration;
import java.util.function.Function;
import org.opentripplanner.util.time.DurationUtils;
import org.opentripplanner.util.time.TimeUtils;

/**
 * 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 final StringBuilder sb = new StringBuilder(); private final OtpNumberFormat numFormat = new OtpNumberFormat(); boolean skipSep = true; boolean skipNull = false; /** 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 */ /** * {@code null} values are skipped after this method is called. * This is the default behavior. */ public ValueObjectToStringBuilder skipNull() { this.skipNull = true; return this; } /** * Use {@link #skipNull()} and {@code skipNull(false)} to turn the skip flag on and off. * Example: * *

     * ValueObjectToStringBuilder.of()
     *   .skipNull().addNum(null).addText("?")
     *   .includeNull().addNum(null).addText("!")
     *
     * is "?null!"
     * 
*/ public ValueObjectToStringBuilder includeNull() { this.skipNull = false; return this; } public ValueObjectToStringBuilder addNum(Number num) { return addIt(num, numFormat::formatNumber); } public ValueObjectToStringBuilder addNum(Number num, String unit) { return addIt(num, it -> numFormat.formatNumber(it, unit)); } public ValueObjectToStringBuilder addBool(Boolean value, String ifTrue, String ifFalse) { return addIt(value, it -> it ? ifTrue : ifFalse); } /** Add a quoted string value */ public ValueObjectToStringBuilder addStr(String value) { return addIt(value, it -> "'" + it + "'"); } /** * Add plain text without quotes or any pending whitespace separator after it. Include * white space if you need it. */ public ValueObjectToStringBuilder addText(String label) { sb.append(label); skipSep = true; return this; } public ValueObjectToStringBuilder addEnum(Enum value) { return addIt(value, Enum::name); } public ValueObjectToStringBuilder addObj(Object obj) { return addIt(obj, Object::toString); } /* 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) { if(skipNull && lat==null && lon==null) { return this; } return addIt( "(" + numFormat.formatCoordinate(lat) + ", " + numFormat.formatCoordinate(lon) + ")" ); } /** * Add time in seconds since midnight. Format: HH:mm:ss. */ public ValueObjectToStringBuilder addServiceTime(int secondsPastMidnight) { // Use a NOT_SET value which 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.timeToStrCompact(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, DurationUtils::durationToStr); } /** * Add a cost in the format $N.NN or $N (id decimals are zero) */ public ValueObjectToStringBuilder addCost(Integer cost) { return addIt(cost, OtpNumberFormat::formatCost); } /** * Add a cost in the format $N.NNu or $Nu, where 'N' is the number and 'u' is the unit. */ public ValueObjectToStringBuilder addCost(Integer cost, String unit) { return addIt(cost, it -> OtpNumberFormat.formatCost(it, unit)); } @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(skipNull && value == null) { return this; } if (skipSep) { skipSep = false; } else { sb.append(FIELD_SEPARATOR); } sb.append(value == null ? "null" : mapToString.apply(value)); return this; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy