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

com.phloc.commons.string.ToStringGenerator Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
/**
 * Copyright (C) 2006-2015 phloc systems
 * http://www.phloc.com
 * office[at]phloc[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phloc.commons.string;

import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

/**
 * This is a utility class for easier toString method creations. It
 * assumes that the toString method is only used for the
 * representation of the internal state and not for creating human readable
 * formats.
 * 

* A real world example for a final class derived from {@link Object} or a base * class looks like this:

@Override
 * public String toString () {
 *   return new ToStringGenerator (this).append ("member1", member1).append ("member2", member2).toString ();
 * }
*

*

* For a derived class, the typical code looks like this, assuming that the base * class also used the {@link ToStringGenerator}:

@Override
 * public String toString () {
 *   return ToStringGenerator.getDerived (super.toString ()).append ("member3", member3).append ("member4", member4).toString ();
 * }
*

* * @author Philip Helger */ @NotThreadSafe public final class ToStringGenerator { /** String to be emitted for null values */ public static final String CONSTANT_NULL = "null"; /** String to be emitted for this values */ public static final String CONSTANT_THIS = "this"; /** String to be emited for password values */ public static final String CONSTANT_PASSWORD = "****"; private static final int FIRST_FIELD = 1; private static final int APPENDED_CLOSING_BRACKET = 2; private final StringBuilder m_aSB = new StringBuilder ("["); private final Object m_aSrc; private int m_nIndex = 0; public ToStringGenerator (@Nullable final Object aSrc) { if (aSrc != null) { final String sClassName = aSrc.getClass ().getName (); final int nIndex = sClassName.lastIndexOf ('.'); m_aSB.append (nIndex == -1 ? sClassName : sClassName.substring (nIndex + 1)) .append ("@0x") .append (StringHelper.getHexStringLeadingZero (System.identityHashCode (aSrc), 8)); } m_aSrc = aSrc; } private void _beforeAddField () { if ((m_nIndex & FIRST_FIELD) == 0) { m_nIndex |= FIRST_FIELD; // Only if a valid source object was provided if (m_aSB.length () > 1) m_aSB.append (": "); } else m_aSB.append ("; "); } @Nonnull private ToStringGenerator _appendSuper (final String sSuper) { _beforeAddField (); m_aSB.append (sSuper); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final boolean aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final boolean [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final byte aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final byte [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final char aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final char [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final double aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final double [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final float aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final float [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final int aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final int [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final long aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final long [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, final short aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (aValue); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final short [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('=').append (Arrays.toString (aValue)); return this; } @Nonnull public ToStringGenerator appendPassword (@Nonnull final String sField) { return append (sField, CONSTANT_PASSWORD); } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final Enum aValue) { return append (sField, String.valueOf (aValue)); } @Nonnull private String _getObjectValue (@Nullable final Object aValue) { return aValue == null ? CONSTANT_NULL : aValue == m_aSrc ? CONSTANT_THIS : aValue.toString (); } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final Object aValue) { if (aValue != null && aValue.getClass ().isArray ()) { // Passed value is an array final Class aCompType = aValue.getClass ().getComponentType (); if (aCompType.equals (boolean.class)) return append (sField, (boolean []) aValue); if (aCompType.equals (byte.class)) return append (sField, (byte []) aValue); if (aCompType.equals (char.class)) return append (sField, (char []) aValue); if (aCompType.equals (double.class)) return append (sField, (double []) aValue); if (aCompType.equals (float.class)) return append (sField, (float []) aValue); if (aCompType.equals (int.class)) return append (sField, (int []) aValue); if (aCompType.equals (long.class)) return append (sField, (long []) aValue); if (aCompType.equals (short.class)) return append (sField, (short []) aValue); return append (sField, (Object []) aValue); } _beforeAddField (); // Avoid endless loop with base object m_aSB.append (sField).append ('=').append (_getObjectValue (aValue)); return this; } @Nonnull public ToStringGenerator append (@Nonnull final String sField, @Nullable final Object [] aValue) { _beforeAddField (); m_aSB.append (sField).append ('='); if (aValue == null) m_aSB.append (CONSTANT_NULL); else { final int nMax = aValue.length - 1; if (nMax == -1) m_aSB.append ("[]"); else { m_aSB.append ('['); for (int i = 0;; i++) { // Avoid endless loop with base object m_aSB.append (_getObjectValue (aValue[i])); if (i == nMax) break; m_aSB.append (", "); } m_aSB.append (']'); } } return this; } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final boolean [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final byte [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final char [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final double [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final float [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final int [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final long [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final short [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final Object aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotNull (@Nonnull final String sField, @Nullable final Object [] aValue) { return aValue == null ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final boolean [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final byte [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final char [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final double [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final float [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final int [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final long [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final short [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final Object [] aValue) { return aValue == null || aValue.length == 0 ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final Collection aValue) { return aValue == null || aValue.isEmpty () ? this : append (sField, aValue); } @Nonnull public ToStringGenerator appendIfNotEmpty (@Nonnull final String sField, @Nullable final Map aValue) { return aValue == null || aValue.isEmpty () ? this : append (sField, aValue); } @Override @Nonnull public String toString () { if ((m_nIndex & APPENDED_CLOSING_BRACKET) == 0) { m_nIndex |= APPENDED_CLOSING_BRACKET; m_aSB.append (']'); } return m_aSB.toString (); } /** * Create a {@link ToStringGenerator} for derived classes where the base class * also uses the {@link ToStringGenerator}. This avoids that the implementing * class name is emitted more than once. * * @param sSuperToString * Always pass in super.toString () * @return Never null */ @Nonnull public static ToStringGenerator getDerived (@Nonnull final String sSuperToString) { // We don't need the object is "super.toString" is involved, because in // super.toString the object is already emitted! return new ToStringGenerator (null)._appendSuper (sSuperToString); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy