http://git-wip-us.apache.org/repos/asf/ignite/blob/9273e51c/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java index b29d7cd..333f95e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringBuilder.java @@ -35,6 +35,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ignite.IgniteException; +import org.apache.ignite.IgniteSystemProperties; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; @@ -85,6 +86,9 @@ public class GridToStringBuilder { /** Maximum number of collection (map) entries to print. */ public static final int MAX_COL_SIZE = 100; + /** {@link IgniteSystemProperties#IGNITE_TO_STRING_INCLUDE_SENSITIVE} */ + public static final boolean INCLUDE_SENSITIVE = IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_TO_STRING_INCLUDE_SENSITIVE, false); + /** */ private static ThreadLocal<Queue<GridToStringThreadLocal>> threadCache = new ThreadLocal<Queue<GridToStringThreadLocal>>() { @Override protected Queue<GridToStringThreadLocal> initialValue() { @@ -114,8 +118,45 @@ public class GridToStringBuilder { * @param val4 Additional parameter value. * @return String presentation of the given object. */ - public static <T> String toString(Class<T> cls, T obj, String name0, Object val0, String name1, Object val1, - String name2, Object val2, String name3, Object val3, String name4, Object val4) { + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, + String name1, Object val1, + String name2, Object val2, + String name3, Object val3, + String name4, Object val4) { + return toString(cls, + obj, + name0, val0, false, + name1, val1, false, + name2, val2, false, + name3, val3, false, + name4, val4, false); + } + + /** + * Produces auto-generated output of string presentation for given object and its declaration class. + * + * @param <T> Type of the object. + * @param cls Declaration class of the object. Note that this should not be a runtime class. + * @param obj Object to get a string presentation for. + * @param name0 Additional parameter name. + * @param val0 Additional parameter value. + * @param name1 Additional parameter name. + * @param val1 Additional parameter value. + * @param name2 Additional parameter name. + * @param val2 Additional parameter value. + * @param name3 Additional parameter name. + * @param val3 Additional parameter value. + * @param name4 Additional parameter name. + * @param val4 Additional parameter value. + * @return String presentation of the given object. + */ + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, boolean sens0, + String name1, Object val1, boolean sens1, + String name2, Object val2, boolean sens2, + String name3, Object val3, boolean sens3, + String name4, Object val4, boolean sens4) { assert cls != null; assert obj != null; assert name0 != null; @@ -135,20 +176,26 @@ public class GridToStringBuilder { Object[] addNames = tmp.getAdditionalNames(); Object[] addVals = tmp.getAdditionalValues(); + boolean[] addSens = tmp.getAdditionalSensitives(); addNames[0] = name0; addVals[0] = val0; + addSens[0] = sens0; addNames[1] = name1; addVals[1] = val1; + addSens[1] = sens1; addNames[2] = name2; addVals[2] = val2; + addSens[2] = sens2; addNames[3] = name3; addVals[3] = val3; + addSens[3] = sens3; addNames[4] = name4; addVals[4] = val4; + addSens[4] = sens4; try { - return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, 5); + return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, addSens, 5); } finally { queue.offer(tmp); @@ -171,8 +218,43 @@ public class GridToStringBuilder { * @param val3 Additional parameter value. * @return String presentation of the given object. */ - public static <T> String toString(Class<T> cls, T obj, String name0, Object val0, String name1, Object val1, - String name2, Object val2, String name3, Object val3) { + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, + String name1, Object val1, + String name2, Object val2, + String name3, Object val3) { + return toString(cls, obj, + name0, val0, false, + name1, val1, false, + name2, val2, false, + name3, val3, false); + } + + /** + * Produces auto-generated output of string presentation for given object and its declaration class. + * + * @param <T> Type of the object. + * @param cls Declaration class of the object. Note that this should not be a runtime class. + * @param obj Object to get a string presentation for. + * @param name0 Additional parameter name. + * @param val0 Additional parameter value. + * @param sens0 Property sensitive flag. + * @param name1 Additional parameter name. + * @param val1 Additional parameter value. + * @param sens1 Property sensitive flag. + * @param name2 Additional parameter name. + * @param val2 Additional parameter value. + * @param sens2 Property sensitive flag. + * @param name3 Additional parameter name. + * @param val3 Additional parameter value. + * @param sens3 Property sensitive flag. + * @return String presentation of the given object. + */ + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, boolean sens0, + String name1, Object val1, boolean sens1, + String name2, Object val2, boolean sens2, + String name3, Object val3, boolean sens3) { assert cls != null; assert obj != null; assert name0 != null; @@ -191,18 +273,23 @@ public class GridToStringBuilder { Object[] addNames = tmp.getAdditionalNames(); Object[] addVals = tmp.getAdditionalValues(); + boolean[] addSens = tmp.getAdditionalSensitives(); addNames[0] = name0; addVals[0] = val0; + addSens[0] = sens0; addNames[1] = name1; addVals[1] = val1; + addSens[1] = sens1; addNames[2] = name2; addVals[2] = val2; + addSens[2] = sens2; addNames[3] = name3; addVals[3] = val3; + addSens[3] = sens3; try { - return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, 4); + return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, addSens, 4); } finally { queue.offer(tmp); @@ -223,8 +310,38 @@ public class GridToStringBuilder { * @param val2 Additional parameter value. * @return String presentation of the given object. */ - public static <T> String toString(Class<T> cls, T obj, String name0, Object val0, String name1, Object val1, + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, + String name1, Object val1, String name2, Object val2) { + return toString(cls, + obj, + name0, val0, false, + name1, val1, false, + name2, val2, false); + } + + /** + * Produces auto-generated output of string presentation for given object and its declaration class. + * + * @param <T> Type of the object. + * @param cls Declaration class of the object. Note that this should not be a runtime class. + * @param obj Object to get a string presentation for. + * @param name0 Additional parameter name. + * @param val0 Additional parameter value. + * @param sens0 Property sensitive flag. + * @param name1 Additional parameter name. + * @param val1 Additional parameter value. + * @param sens1 Property sensitive flag. + * @param name2 Additional parameter name. + * @param val2 Additional parameter value. + * @param sens2 Property sensitive flag. + * @return String presentation of the given object. + */ + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, boolean sens0, + String name1, Object val1, boolean sens1, + String name2, Object val2, boolean sens2) { assert cls != null; assert obj != null; assert name0 != null; @@ -242,16 +359,20 @@ public class GridToStringBuilder { Object[] addNames = tmp.getAdditionalNames(); Object[] addVals = tmp.getAdditionalValues(); + boolean[] addSens = tmp.getAdditionalSensitives(); addNames[0] = name0; addVals[0] = val0; + addSens[0] = sens0; addNames[1] = name1; addVals[1] = val1; + addSens[1] = sens1; addNames[2] = name2; addVals[2] = val2; + addSens[2] = sens2; try { - return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, 3); + return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, addSens, 3); } finally { queue.offer(tmp); @@ -270,7 +391,29 @@ public class GridToStringBuilder { * @param val1 Additional parameter value. * @return String presentation of the given object. */ - public static <T> String toString(Class<T> cls, T obj, String name0, Object val0, String name1, Object val1) { + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, + String name1, Object val1) { + return toString(cls, obj, name0, val0, false, name1, val1, false); + } + + /** + * Produces auto-generated output of string presentation for given object and its declaration class. + * + * @param <T> Type of the object. + * @param cls Declaration class of the object. Note that this should not be a runtime class. + * @param obj Object to get a string presentation for. + * @param name0 Additional parameter name. + * @param val0 Additional parameter value. + * @param sens0 Property sensitive flag. + * @param name1 Additional parameter name. + * @param val1 Additional parameter value. + * @param sens1 Property sensitive flag. + * @return String presentation of the given object. + */ + public static <T> String toString(Class<T> cls, T obj, + String name0, Object val0, boolean sens0, + String name1, Object val1, boolean sens1) { assert cls != null; assert obj != null; assert name0 != null; @@ -287,14 +430,17 @@ public class GridToStringBuilder { Object[] addNames = tmp.getAdditionalNames(); Object[] addVals = tmp.getAdditionalValues(); + boolean[] addSens = tmp.getAdditionalSensitives(); addNames[0] = name0; addVals[0] = val0; + addSens[0] = sens0; addNames[1] = name1; addVals[1] = val1; + addSens[1] = sens1; try { - return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, 2); + return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, addSens, 2); } finally { queue.offer(tmp); @@ -312,6 +458,21 @@ public class GridToStringBuilder { * @return String presentation of the given object. */ public static <T> String toString(Class<T> cls, T obj, String name, @Nullable Object val) { + return toString(cls, obj, name, val, false); + } + + /** + * Produces auto-generated output of string presentation for given object and its declaration class. + * + * @param <T> Type of the object. + * @param cls Declaration class of the object. Note that this should not be a runtime class. + * @param obj Object to get a string presentation for. + * @param name Additional parameter name. + * @param val Additional parameter value. + * @param sens Property sensitive flag. + * @return String presentation of the given object. + */ + public static <T> String toString(Class<T> cls, T obj, String name, @Nullable Object val, boolean sens) { assert cls != null; assert obj != null; assert name != null; @@ -327,12 +488,14 @@ public class GridToStringBuilder { Object[] addNames = tmp.getAdditionalNames(); Object[] addVals = tmp.getAdditionalValues(); + boolean[] addSens = tmp.getAdditionalSensitives(); addNames[0] = name; addVals[0] = val; + addSens[0] = sens; try { - return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, 1); + return toStringImpl(cls, tmp.getStringBuilder(), obj, addNames, addVals, addSens, 1); } finally { queue.offer(tmp); @@ -362,7 +525,7 @@ public class GridToStringBuilder { try { return toStringImpl(cls, tmp.getStringBuilder(), obj, tmp.getAdditionalNames(), - tmp.getAdditionalValues(), 0); + tmp.getAdditionalValues(), null, 0); } finally { queue.offer(tmp); @@ -390,12 +553,16 @@ public class GridToStringBuilder { * @param obj Object for which to get string presentation. * @param addNames Names of additional values to be included. * @param addVals Additional values to be included. + * @param addSens Sensitive flag of values or {@code null} if all values are not sensitive. * @param addLen How many additional values will be included. * @return String presentation of the given object. * @param <T> Type of object. */ @SuppressWarnings({"unchecked"}) - private static <T> String toStringImpl(Class<T> cls, SB buf, T obj, Object[] addNames, Object[] addVals, + private static <T> String toStringImpl(Class<T> cls, SB buf, T obj, + Object[] addNames, + Object[] addVals, + @Nullable boolean[] addSens, int addLen) { assert cls != null; assert buf != null; @@ -430,26 +597,10 @@ public class GridToStringBuilder { buf.a(name).a('='); - if (field.getType().isArray()) { - if (field.getType().equals(byte[].class)) - buf.a(Arrays.toString((byte[])field.get(obj))); - else if (field.getType().equals(boolean[].class)) - buf.a(Arrays.toString((boolean[])field.get(obj))); - else if (field.getType().equals(short[].class)) - buf.a(Arrays.toString((short[])field.get(obj))); - else if (field.getType().equals(int[].class)) - buf.a(Arrays.toString((int[])field.get(obj))); - else if (field.getType().equals(long[].class)) - buf.a(Arrays.toString((long[])field.get(obj))); - else if (field.getType().equals(float[].class)) - buf.a(Arrays.toString((float[])field.get(obj))); - else if (field.getType().equals(double[].class)) - buf.a(Arrays.toString((double[])field.get(obj))); - else if (field.getType().equals(char[].class)) - buf.a(Arrays.toString((char[])field.get(obj))); - else - buf.a(Arrays.toString((Object[])field.get(obj))); - } + Class<?> fieldType = field.getType(); + + if (fieldType.isArray()) + buf.a(arrayToString(fieldType, field.get(obj))); else { Object val = field.get(obj); @@ -475,15 +626,7 @@ public class GridToStringBuilder { } } - if (addLen > 0) - for (int i = 0; i < addLen; i++) { - if (!first) - buf.a(", "); - else - first = false; - - buf.a(addNames[i]).a('=').a(addVals[i]); - } + appendVals(buf, first, addNames, addVals, addSens, addLen); buf.a(']'); @@ -508,6 +651,402 @@ public class GridToStringBuilder { } /** + * @param arrType Type of the array. + * @param arr Array object. + * @return String representation of an array. + */ + private static String arrayToString(Class arrType, Object arr) { + if (arrType.equals(byte[].class)) + return Arrays.toString((byte[])arr); + if (arrType.equals(boolean[].class)) + return Arrays.toString((boolean[])arr); + if (arrType.equals(short[].class)) + return Arrays.toString((short[])arr); + if (arrType.equals(int[].class)) + return Arrays.toString((int[])arr); + if (arrType.equals(long[].class)) + return Arrays.toString((long[])arr); + if (arrType.equals(float[].class)) + return Arrays.toString((float[])arr); + if (arrType.equals(double[].class)) + return Arrays.toString((double[])arr); + if (arrType.equals(char[].class)) + return Arrays.toString((char[])arr); + + return Arrays.toString((Object[])arr); + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name Property name. + * @param val Property value. + * @return String presentation. + */ + public static String toString(String str, String name, @Nullable Object val) { + return toString(str, name, val, false); + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name Property name. + * @param val Property value. + * @param sens Property sensitive flag. + * @return String presentation. + */ + public static String toString(String str, String name, @Nullable Object val, boolean sens) { + assert name != null; + + Queue<GridToStringThreadLocal> queue = threadCache.get(); + + assert queue != null; + + // Since string() methods can be chain-called from the same thread we + // have to keep a list of thread-local objects and remove/add them + // in each string() apply. + GridToStringThreadLocal tmp = queue.isEmpty() ? new GridToStringThreadLocal() : queue.remove(); + + Object[] propNames = tmp.getAdditionalNames(); + Object[] propVals = tmp.getAdditionalValues(); + boolean[] propSens = tmp.getAdditionalSensitives(); + + propNames[0] = name; + propVals[0] = val; + propSens[0] = sens; + + try { + return toStringImpl(str, tmp.getStringBuilder(), propNames, propVals, propSens, 1); + } + finally { + queue.offer(tmp); + } + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name0 Property name. + * @param val0 Property value. + * @param name1 Property name. + * @param val1 Property value. + * @return String presentation. + */ + public static String toString(String str, String name0, @Nullable Object val0, String name1, + @Nullable Object val1) { + return toString(str, name0, val0, false, name1, val1, false); + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name0 Property name. + * @param val0 Property value. + * @param sens0 Property sensitive flag. + * @param name1 Property name. + * @param val1 Property value. + * @param sens1 Property sensitive flag. + * @return String presentation. + */ + public static String toString(String str, + String name0, @Nullable Object val0, boolean sens0, + String name1, @Nullable Object val1, boolean sens1) { + assert name0 != null; + assert name1 != null; + + Queue<GridToStringThreadLocal> queue = threadCache.get(); + + assert queue != null; + + // Since string() methods can be chain-called from the same thread we + // have to keep a list of thread-local objects and remove/add them + // in each string() apply. + GridToStringThreadLocal tmp = queue.isEmpty() ? new GridToStringThreadLocal() : queue.remove(); + + Object[] propNames = tmp.getAdditionalNames(); + Object[] propVals = tmp.getAdditionalValues(); + boolean[] propSens = tmp.getAdditionalSensitives(); + + propNames[0] = name0; + propVals[0] = val0; + propSens[0] = sens0; + propNames[1] = name1; + propVals[1] = val1; + propSens[1] = sens1; + + try { + return toStringImpl(str, tmp.getStringBuilder(), propNames, propVals, propSens, 2); + } + finally { + queue.offer(tmp); + } + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name0 Property name. + * @param val0 Property value. + * @param sens0 Property sensitive flag. + * @param name1 Property name. + * @param val1 Property value. + * @param sens1 Property sensitive flag. + * @param name2 Property name. + * @param val2 Property value. + * @param sens2 Property sensitive flag. + * @return String presentation. + */ + public static String toString(String str, + String name0, @Nullable Object val0, boolean sens0, + String name1, @Nullable Object val1, boolean sens1, + String name2, @Nullable Object val2, boolean sens2) { + assert name0 != null; + assert name1 != null; + assert name2 != null; + + Queue<GridToStringThreadLocal> queue = threadCache.get(); + + assert queue != null; + + // Since string() methods can be chain-called from the same thread we + // have to keep a list of thread-local objects and remove/add them + // in each string() apply. + GridToStringThreadLocal tmp = queue.isEmpty() ? new GridToStringThreadLocal() : queue.remove(); + + Object[] propNames = tmp.getAdditionalNames(); + Object[] propVals = tmp.getAdditionalValues(); + boolean[] propSens = tmp.getAdditionalSensitives(); + + propNames[0] = name0; + propVals[0] = val0; + propSens[0] = sens0; + propNames[1] = name1; + propVals[1] = val1; + propSens[1] = sens1; + propNames[2] = name2; + propVals[2] = val2; + propSens[2] = sens2; + + try { + return toStringImpl(str, tmp.getStringBuilder(), propNames, propVals, propSens, 3); + } + finally { + queue.offer(tmp); + } + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name0 Property name. + * @param val0 Property value. + * @param sens0 Property sensitive flag. + * @param name1 Property name. + * @param val1 Property value. + * @param sens1 Property sensitive flag. + * @param name2 Property name. + * @param val2 Property value. + * @param sens2 Property sensitive flag. + * @param name3 Property name. + * @param val3 Property value. + * @param sens3 Property sensitive flag. + * @return String presentation. + */ + public static String toString(String str, + String name0, @Nullable Object val0, boolean sens0, + String name1, @Nullable Object val1, boolean sens1, + String name2, @Nullable Object val2, boolean sens2, + String name3, @Nullable Object val3, boolean sens3) { + assert name0 != null; + assert name1 != null; + assert name2 != null; + assert name3 != null; + + Queue<GridToStringThreadLocal> queue = threadCache.get(); + + assert queue != null; + + // Since string() methods can be chain-called from the same thread we + // have to keep a list of thread-local objects and remove/add them + // in each string() apply. + GridToStringThreadLocal tmp = queue.isEmpty() ? new GridToStringThreadLocal() : queue.remove(); + + Object[] propNames = tmp.getAdditionalNames(); + Object[] propVals = tmp.getAdditionalValues(); + boolean[] propSens = tmp.getAdditionalSensitives(); + + propNames[0] = name0; + propVals[0] = val0; + propSens[0] = sens0; + propNames[1] = name1; + propVals[1] = val1; + propSens[1] = sens1; + propNames[2] = name2; + propVals[2] = val2; + propSens[2] = sens2; + propNames[3] = name3; + propVals[3] = val3; + propSens[3] = sens3; + + try { + return toStringImpl(str, tmp.getStringBuilder(), propNames, propVals, propSens, 4); + } + finally { + queue.offer(tmp); + } + } + + /** + * Produces uniformed output of string with context properties + * + * @param str Output prefix or {@code null} if empty. + * @param name0 Property name. + * @param val0 Property value. + * @param sens0 Property sensitive flag. + * @param name1 Property name. + * @param val1 Property value. + * @param sens1 Property sensitive flag. + * @param name2 Property name. + * @param val2 Property value. + * @param sens2 Property sensitive flag. + * @param name3 Property name. + * @param val3 Property value. + * @param sens3 Property sensitive flag. + * @param name4 Property name. + * @param val4 Property value. + * @param sens4 Property sensitive flag. + * @return String presentation. + */ + public static String toString(String str, + String name0, @Nullable Object val0, boolean sens0, + String name1, @Nullable Object val1, boolean sens1, + String name2, @Nullable Object val2, boolean sens2, + String name3, @Nullable Object val3, boolean sens3, + String name4, @Nullable Object val4, boolean sens4) { + assert name0 != null; + assert name1 != null; + assert name2 != null; + assert name3 != null; + assert name4 != null; + + Queue<GridToStringThreadLocal> queue = threadCache.get(); + + assert queue != null; + + // Since string() methods can be chain-called from the same thread we + // have to keep a list of thread-local objects and remove/add them + // in each string() apply. + GridToStringThreadLocal tmp = queue.isEmpty() ? new GridToStringThreadLocal() : queue.remove(); + + Object[] propNames = tmp.getAdditionalNames(); + Object[] propVals = tmp.getAdditionalValues(); + boolean[] propSens = tmp.getAdditionalSensitives(); + + propNames[0] = name0; + propVals[0] = val0; + propSens[0] = sens0; + propNames[1] = name1; + propVals[1] = val1; + propSens[1] = sens1; + propNames[2] = name2; + propVals[2] = val2; + propSens[2] = sens2; + propNames[3] = name3; + propVals[3] = val3; + propSens[3] = sens3; + propNames[4] = name4; + propVals[4] = val4; + propSens[4] = sens4; + + try { + return toStringImpl(str, tmp.getStringBuilder(), propNames, propVals, propSens, 5); + } + finally { + queue.offer(tmp); + } + } + + /** + * Creates an uniformed string presentation for the binary-like object. + * + * @param str Output prefix or {@code null} if empty. + * @param buf String builder buffer. + * @param propNames Names of object properties. + * @param propVals Property values. + * @param propSens Sensitive flag of values or {@code null} if all values is not sensitive. + * @param propCnt Properties count. + * @return String presentation of the object. + */ + private static String toStringImpl(String str, SB buf, Object[] propNames, Object[] propVals, + boolean[] propSens, int propCnt) { + + buf.setLength(0); + + if (str != null) + buf.a(str).a(" "); + + buf.a("["); + + appendVals(buf, true, propNames, propVals, propSens, propCnt); + + buf.a(']'); + + return buf.toString(); + } + + /** + * Append additional values to the buffer. + * + * @param buf Buffer. + * @param first First value flag. + * @param addNames Names of additional values to be included. + * @param addVals Additional values to be included. + * @param addSens Sensitive flag of values or {@code null} if all values are not sensitive. + * @param addLen How many additional values will be included. + */ + private static void appendVals(SB buf, + boolean first, + Object[] addNames, + Object[] addVals, + boolean[] addSens, + int addLen) + { + if (addLen > 0) { + for (int i = 0; i < addLen; i++) { + Object addVal = addVals[i]; + + if (addVal != null) { + if (addSens != null && addSens[i] && !INCLUDE_SENSITIVE) + continue; + + GridToStringInclude incAnn = addVal.getClass().getAnnotation(GridToStringInclude.class); + + if (incAnn != null && incAnn.sensitive() && !INCLUDE_SENSITIVE) + continue; + + Class<?> cls = addVal.getClass(); + + if (cls.isArray()) + addVal = arrayToString(cls, addVal); + } + + if (!first) + buf.a(", "); + else + first = false; + + buf.a(addNames[i]).a('=').a(addVal); + } + } + } + + /** * @param cls Class. * @param <T> Type of the object. * @return Descriptor for the class. @@ -518,7 +1057,7 @@ public class GridToStringBuilder { String key = cls.getName() + System.identityHashCode(cls.getClassLoader()); - GridToStringClassDescriptor cd = null; + GridToStringClassDescriptor cd; rwLock.readLock().lock(); @@ -537,9 +1076,15 @@ public class GridToStringBuilder { Class<?> type = f.getType(); - if (f.isAnnotationPresent(GridToStringInclude.class) || - type.isAnnotationPresent(GridToStringInclude.class)) - add = true; + final GridToStringInclude incFld = f.getAnnotation(GridToStringInclude.class); + final GridToStringInclude incType = type.getAnnotation(GridToStringInclude.class); + + if (incFld != null || incType != null) { + // Information is not sensitive when both the field and the field type are not sensitive. + // When @GridToStringInclude is not present then the flag is false by default for that attribute. + final boolean notSens = (incFld == null || !incFld.sensitive()) && (incType == null || !incType.sensitive()); + add = notSens || INCLUDE_SENSITIVE; + } else if (!f.isAnnotationPresent(GridToStringExclude.class) && !f.getType().isAnnotationPresent(GridToStringExclude.class)) { if ( @@ -573,8 +1118,9 @@ public class GridToStringBuilder { GridToStringFieldDescriptor fd = new GridToStringFieldDescriptor(f.getName()); // Get order, if any. - if (f.isAnnotationPresent(GridToStringOrder.class)) - fd.setOrder(f.getAnnotation(GridToStringOrder.class).value()); + final GridToStringOrder annOrder = f.getAnnotation(GridToStringOrder.class); + if (annOrder != null) + fd.setOrder(annOrder.value()); cd.addField(fd); }
http://git-wip-us.apache.org/repos/asf/ignite/blob/9273e51c/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringInclude.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringInclude.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringInclude.java index ec502a7..5ea1fe6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringInclude.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringInclude.java @@ -17,6 +17,8 @@ package org.apache.ignite.internal.util.tostring; +import org.apache.ignite.IgniteSystemProperties; + import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -32,5 +34,13 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface GridToStringInclude { - // No-op. + /** + * A flag indicating a sensitive information stored in the field or fields of the class.<br/> + * Such information will be included in {@code toString()} output ONLY when the system property + * {@link IgniteSystemProperties#IGNITE_TO_STRING_INCLUDE_SENSITIVE IGNITE_TO_STRING_INCLUDE_SENSITIVE} + * is set to {@code true}. + * + * @return Attribute value. + */ + boolean sensitive() default false; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/9273e51c/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringThreadLocal.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringThreadLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringThreadLocal.java index ab91452..33fc6a0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringThreadLocal.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/tostring/GridToStringThreadLocal.java @@ -20,7 +20,7 @@ package org.apache.ignite.internal.util.tostring; import org.apache.ignite.internal.util.typedef.internal.SB; /** - * Helper wrapper containing StringBuilder and additional values. Stored as a thread-lcal variable. + * Helper wrapper containing StringBuilder and additional values. Stored as a thread-local variable. */ class GridToStringThreadLocal { /** */ @@ -32,6 +32,9 @@ class GridToStringThreadLocal { /** */ private Object[] addVals = new Object[5]; + /** */ + private boolean[] addSens = new boolean[5]; + /** * @return String builder. */ @@ -52,4 +55,11 @@ class GridToStringThreadLocal { Object[] getAdditionalValues() { return addVals; } + + /** + * @return Additional values. + */ + boolean[] getAdditionalSensitives() { + return addSens; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/9273e51c/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectsAbstractSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectsAbstractSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectsAbstractSelfTest.java index 150c245..bf72782 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectsAbstractSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectsAbstractSelfTest.java @@ -60,6 +60,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryEx; import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; import org.apache.ignite.internal.util.typedef.P2; import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiInClosure; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; @@ -224,7 +225,11 @@ public abstract class GridCacheBinaryObjectsAbstractSelfTest extends GridCommonA String typeName = nameMapper.typeName(TestReferenceObject.class.getName()); - assertTrue("Unexpected toString: " + str, str.startsWith(typeName) && str.contains("obj=" + typeName + " [")); + assertTrue("Unexpected toString: " + str, + S.INCLUDE_SENSITIVE ? + str.startsWith(typeName) && str.contains("obj=" + typeName + " [") : + str.startsWith("BinaryObject") && str.contains("idHash=") && str.contains("hash=") + ); TestReferenceObject obj1_r = po.deserialize(); http://git-wip-us.apache.org/repos/asf/ignite/blob/9273e51c/modules/core/src/test/java/org/apache/ignite/internal/util/tostring/GridToStringBuilderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/util/tostring/GridToStringBuilderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/util/tostring/GridToStringBuilderSelfTest.java index 4f5fe9b..6a0eae2 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/util/tostring/GridToStringBuilderSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/util/tostring/GridToStringBuilderSelfTest.java @@ -54,7 +54,13 @@ public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { IgniteLogger log = log(); - log.info(obj.toStringWithAdditional()); + String manual = obj.toStringWithAdditionalManual(); + log.info(manual); + + String automatic = obj.toStringWithAdditionalAutomatic(); + log.info(automatic); + + assert manual.equals(automatic); } /** @@ -117,7 +123,7 @@ public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { /** * Test class. */ - private class TestClass1 { + private static class TestClass1 { /** */ @SuppressWarnings("unused") @GridToStringOrder(0) @@ -129,6 +135,7 @@ public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { /** */ @SuppressWarnings("unused") + @GridToStringInclude(sensitive = true) private long longVar; /** */ @@ -180,7 +187,8 @@ public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { buf.append("id=").append(id).append(", "); buf.append("uuidVar=").append(uuidVar).append(", "); buf.append("intVar=").append(intVar).append(", "); - buf.append("longVar=").append(longVar).append(", "); + if (S.INCLUDE_SENSITIVE) + buf.append("longVar=").append(longVar).append(", "); buf.append("boolVar=").append(boolVar).append(", "); buf.append("byteVar=").append(byteVar).append(", "); buf.append("name=").append(name).append(", "); @@ -200,10 +208,23 @@ public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { } /** - * @return String with additional parameters. + * @return Automatic string with additional parameters. + */ + String toStringWithAdditionalAutomatic() { + return S.toString(TestClass1.class, this, "newParam1", 1, false, "newParam2", 2, true); + } + + /** + * @return Manual string with additional parameters. */ - String toStringWithAdditional() { - return S.toString(TestClass1.class, this, "newParam1", 1, "newParam2", 2); + String toStringWithAdditionalManual() { + StringBuilder s = new StringBuilder(toStringManual()); + s.setLength(s.length() - 1); + s.append(", newParam1=").append(1); + if (S.INCLUDE_SENSITIVE) + s.append(", newParam2=").append(2); + s.append(']'); + return s.toString(); } } } \ No newline at end of file
