blob: a2cf10287c5605f62ff093f3c53d9b8ae74f92cc [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2015, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.jcommons.lang;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.FIELD;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER;
import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.RETURN_TYPE;
import java.util.Collection;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import java.util.function.Supplier;
@NonNullByDefault({ PARAMETER, RETURN_TYPE, FIELD })
public final class ObjectUtils {
public static class ToStringBuilder {
private static final String INDENT= " "; //$NON-NLS-1$
private static final String CONT_INDENT= INDENT + INDENT;
private static final String LINE_PREFIX= "\n";
private static final String PROP_PREFIX= LINE_PREFIX + INDENT;
private static final String PROP_ASSIGN= "= "; //$NON-NLS-1$
private static final Object NULL= "<null>"; //$NON-NLS-1$
private final StringBuilder sb;
private @Nullable Formatter formatter;
public ToStringBuilder() {
this.sb= new StringBuilder();
}
public ToStringBuilder(final String name) {
this.sb= new StringBuilder(name);
}
public ToStringBuilder(final String name, final Class<?> clazz) {
this.sb= new StringBuilder(name);
this.sb.append(" ("); //$NON-NLS-1$
this.sb.append(clazz.getName());
this.sb.append(")"); //$NON-NLS-1$
}
public ToStringBuilder(final Class<?> defClazz, final Class<?> clazz) {
this(defClazz.getSimpleName(), clazz);
}
public ToStringBuilder(final Class<?> defClazz) {
this(defClazz.getSimpleName());
}
public StringBuilder getStringBuilder() {
return this.sb;
}
public final void append(final String s) {
this.sb.append(s);
}
public final void append(final String s, final int begin, final int end) {
this.sb.append(s, begin, end);
}
public final void append(final char c) {
this.sb.append(c);
}
public final void append(final int number) {
this.sb.append(number);
}
public final void append(final long number) {
this.sb.append(number);
}
public final void append(final char sep, final String s) {
this.sb.append(sep);
this.sb.append(s);
}
public final void append(final char sep, final int number) {
this.sb.append(sep);
this.sb.append(number);
}
public final void append(final char sep, final long number) {
this.sb.append(sep);
this.sb.append(number);
}
public final void append(final char open, final String s, final char close) {
this.sb.append(open);
this.sb.append(s);
this.sb.append(close);
}
public final void append(final char open, final int number, final char close) {
this.sb.append(open);
this.sb.append(number);
this.sb.append(close);
}
public final void append(final char open, final long number, final char close) {
this.sb.append(open);
this.sb.append(number);
this.sb.append(close);
}
public final void appendFormat(final String valueFormat, final @Nullable Object... valueArgs) {
Formatter formatter= this.formatter;
if (formatter == null) {
formatter= new Formatter(this.sb, Locale.ENGLISH);
this.formatter= formatter;
}
formatter.format(valueFormat, valueArgs);
}
public final void appendLines(final String lines) {
appendLines(lines, LINE_PREFIX + CONT_INDENT);
}
public final void appendLines(final char sep, final String lines) {
this.sb.append(sep);
appendLines(lines, LINE_PREFIX + CONT_INDENT);
}
public final void appendLines(final List<@NonNull String> lines) {
final int n= lines.size();
if (n == 0) {
return;
}
append(lines.get(0));
for (int i= 1; i < n; i++) {
append(LINE_PREFIX + CONT_INDENT);
lines.get(i);
}
}
private void appendLines(final String s, final String contPrefix) {
int start= 0;
int end= s.indexOf('\n', start);
if (end < 0) {
append(s);
return;
}
if (end > 0 && s.charAt(end - 1) == '\r') {
append(s, start, end - 1);
}
else {
append(s, start, end);
}
start= end + 1;
while ((end= s.indexOf('\n', start)) >= 0) {
append(contPrefix);
if (end > 0 && s.charAt(end - 1) == '\r') {
append(s, start, end - 1);
}
else {
append(s, start, end);
}
start= end + 1;
}
if (start < s.length()) {
append(contPrefix);
append(s, start, s.length());
}
}
public void addProp(final String name) {
this.sb.append(PROP_PREFIX);
this.sb.append(name);
this.sb.append(PROP_ASSIGN);
}
public void addProp(final String name, final @Nullable String value) {
addProp(name);
if (value == null) {
this.sb.append(NULL);
return;
}
appendLines(value, PROP_PREFIX + CONT_INDENT);
}
public void addProp(final String name, final boolean value) {
addProp(name);
this.sb.append(value);
}
public void addProp(final String name, final int value) {
addProp(name);
this.sb.append(value);
}
public void addProp(final String name, final long value) {
addProp(name);
this.sb.append(value);
}
public void addProp(final String name, final float value) {
addProp(name);
this.sb.append(value);
}
public void addProp(final String name, final double value) {
addProp(name);
this.sb.append(value);
}
public void addProp(final String name, final @Nullable Object value) {
addProp(name);
if (value == null) {
this.sb.append(NULL);
return;
}
appendLines(value.toString(), PROP_PREFIX + CONT_INDENT);
}
public void addProp(final String name, final @Nullable Collection<?> value) {
addProp(name);
if (value == null) {
this.sb.append(NULL);
return;
}
if (value instanceof List) {
this.sb.append('[');
}
else {
this.sb.append('{');
}
if (!value.isEmpty()) {
for (final Object e : value) {
this.sb.append(PROP_PREFIX + INDENT);
if (e == null) {
this.sb.append(NULL);
continue;
}
appendLines(e.toString(), PROP_PREFIX + INDENT + CONT_INDENT);
}
this.sb.append(PROP_PREFIX);
}
if (value instanceof List) {
this.sb.append(']');
}
else {
this.sb.append('}');
}
}
public void addProp(final String name, final String valueFormat, final @Nullable Object... valueArgs) {
addProp(name);
appendFormat(valueFormat, valueArgs);
}
public String build() {
return this.sb.toString();
}
@Override
public String toString() {
return this.sb.toString();
}
}
public static final Class<@NonNull Object> NonNull_Object_TYPE= Object.class;
@SuppressWarnings("null")
public static final Class<@Nullable Object> Nullable_Object_TYPE= Object.class;
public static final Class<@NonNull String> NonNull_String_TYPE= String.class;
@SuppressWarnings("null")
public static final Class<@Nullable String> Nullable_String_TYPE= String.class;
public static boolean isNull(final @Nullable Object object) {
return (object == null);
}
public static boolean isAnyNull(final @Nullable Object object1, final @Nullable Object object2) {
return (object1 == null || object2 == null);
}
@SafeVarargs
public static <T> boolean isAnyNull(final T... objects) {
for (int i= 0; i < objects.length; i++) {
if (objects[i] == null) {
return true;
}
}
return false;
}
public static <T> @NonNull T nonNullAssert(final @Nullable T object) {
if (object == null) {
throw new NullPointerException();
}
return object;
}
public static <T> @NonNull T nonNullElse(final @Nullable T object, final @NonNull T elseObj) {
return (object != null) ? object : elseObj;
}
public static <T> @NonNull T nonNullElse(final @Nullable T object,
final Supplier<? extends @NonNull T> elseSupplier) {
return (object != null) ? object : elseSupplier.get();
}
/**
* Marks a @NonNull field as late initialized.
*
* @param <T> the type
* @return <code>null</code>
*/
@SuppressWarnings("null")
public static <T> @NonNull T nonNullLateInit() {
return null;
}
public static <T> @Nullable T nullable(final @Nullable T object) {
return object;
}
private ObjectUtils() {}
}