package de.invesdwin.util.lang; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; import de.invesdwin.util.lang.internal.MultilineToStringStyle; @NotThreadSafe public final class ToStringHelper { private static final String INDENT = MultilineToStringStyle.INDENT; private final StringBuilder builder; private boolean needsSeparator = false; private final List<String> withObjStrs; private boolean bracketAdded; private final boolean multiline; ToStringHelper(final Object self, final boolean multiline) { this(self.getClass(), multiline); } ToStringHelper(final Class<?> clazz, final boolean multiline) { this(clazz.getSimpleName(), multiline); } ToStringHelper(final String className, final boolean multiline) { org.assertj.core.api.Assertions.assertThat(className).isNotNull(); this.builder = new StringBuilder(32).append(className); this.withObjStrs = new ArrayList<String>(); this.multiline = multiline; } public ToStringHelper add(final String name, @Nullable final Object value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final boolean value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final char value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final double value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final float value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final int value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper add(final String name, final long value) { checkNameAndAppend(name).append(value); return this; } public ToStringHelper addValue(@Nullable final Object value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final boolean value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final char value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final double value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final float value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final int value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper addValue(final long value) { maybeAppendSeparator().append(value); return this; } public ToStringHelper with(final Object... objs) { for (final Object obj : objs) { if (obj != null) { final String string = obj.toString(); this.withObjStrs.add(string); } } return this; } private StringBuilder checkNameAndAppend(final String name) { org.assertj.core.api.Assertions.assertThat(name).isNotNull(); final StringBuilder append = maybeAppendSeparator().append(name); final String colon; if (multiline) { colon = " = "; } else { colon = ":"; } return append.append(colon); } @Override public String toString() { final StringBuilder sb = new StringBuilder(builder); if (bracketAdded) { if (multiline) { sb.append("\n"); } sb.append(']'); } if (!withObjStrs.isEmpty()) { boolean firstWith = true; for (final String withObjStr : withObjStrs) { if (firstWith) { sb.append(" with {"); firstWith = false; } else { sb.append(" and "); } if (multiline) { sb.append("\n").append(INDENT); } if (multiline) { sb.append(withObjStr.replace("\n", "\n" + INDENT)); } else { sb.append(withObjStr); } } if (multiline) { sb.append("\n"); } sb.append("}"); } return sb.toString(); } public boolean isMultiline() { return multiline; } private StringBuilder maybeAppendSeparator() { if (!bracketAdded) { bracketAdded = true; builder.append('['); if (multiline) { builder.append("\n").append(INDENT); } } if (needsSeparator) { if (multiline) { return builder.append(",").append("\n").append(INDENT); } else { return builder.append("|"); } } else { needsSeparator = true; return builder; } } }