| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.ignite.internal.util.tostring; |
| |
| import com.sun.management.ThreadMXBean; |
| import java.lang.management.ManagementFactory; |
| import java.lang.reflect.Array; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| import java.util.UUID; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.CyclicBarrier; |
| import java.util.concurrent.locks.ReadWriteLock; |
| import java.util.function.Function; |
| import org.apache.ignite.IgniteLogger; |
| import org.apache.ignite.IgniteSystemProperties; |
| import org.apache.ignite.internal.IgniteInternalFuture; |
| import org.apache.ignite.internal.processors.cache.KeyCacheObjectImpl; |
| import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey; |
| import org.apache.ignite.internal.util.typedef.internal.S; |
| import org.apache.ignite.testframework.GridTestUtils; |
| import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; |
| import org.apache.ignite.testframework.junits.common.GridCommonTest; |
| import org.junit.Test; |
| |
| import static java.util.Arrays.asList; |
| import static java.util.Collections.emptyList; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_TO_STRING_COLLECTION_LIMIT; |
| import static org.apache.ignite.IgniteSystemProperties.IGNITE_TO_STRING_MAX_LENGTH; |
| import static org.apache.ignite.internal.util.tostring.GridToStringBuilder.compact; |
| import static org.apache.ignite.internal.util.tostring.GridToStringBuilder.identity; |
| |
| /** |
| * Tests for {@link GridToStringBuilder}. |
| */ |
| @GridCommonTest(group = "Utils") |
| public class GridToStringBuilderSelfTest extends GridCommonAbstractTest { |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToString() throws Exception { |
| TestClass1 obj = new TestClass1(); |
| |
| IgniteLogger log = log(); |
| |
| log.info(obj.toStringManual()); |
| log.info(obj.toStringAutomatic()); |
| |
| assertEquals (obj.toStringManual(), obj.toStringAutomatic()); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringWithAdditions() throws Exception { |
| TestClass1 obj = new TestClass1(); |
| |
| IgniteLogger log = log(); |
| |
| String manual = obj.toStringWithAdditionalManual(); |
| log.info(manual); |
| |
| String automatic = obj.toStringWithAdditionalAutomatic(); |
| log.info(automatic); |
| |
| assertEquals(manual, automatic); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCheckSimpleListRecursionPrevention() throws Exception { |
| ArrayList<Object> list1 = new ArrayList<>(); |
| ArrayList<Object> list2 = new ArrayList<>(); |
| |
| list2.add(list1); |
| list1.add(list2); |
| |
| info(GridToStringBuilder.toString(ArrayList.class, list1)); |
| info(GridToStringBuilder.toString(ArrayList.class, list2)); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCheckSimpleMapRecursionPrevention() throws Exception { |
| HashMap<Object, Object> map1 = new HashMap<>(); |
| HashMap<Object, Object> map2 = new HashMap<>(); |
| |
| map1.put("2", map2); |
| map2.put("1", map1); |
| |
| info(GridToStringBuilder.toString(HashMap.class, map1)); |
| info(GridToStringBuilder.toString(HashMap.class, map2)); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCheckListAdvancedRecursionPrevention() throws Exception { |
| ArrayList<Object> list1 = new ArrayList<>(); |
| ArrayList<Object> list2 = new ArrayList<>(); |
| |
| list2.add(list1); |
| list1.add(list2); |
| |
| info(GridToStringBuilder.toString(ArrayList.class, list1, "name", list2)); |
| info(GridToStringBuilder.toString(ArrayList.class, list2, "name", list1)); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCheckMapAdvancedRecursionPrevention() throws Exception { |
| HashMap<Object, Object> map1 = new HashMap<>(); |
| HashMap<Object, Object> map2 = new HashMap<>(); |
| |
| map1.put("2", map2); |
| map2.put("1", map1); |
| |
| info(GridToStringBuilder.toString(HashMap.class, map1, "name", map2)); |
| info(GridToStringBuilder.toString(HashMap.class, map2, "name", map1)); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCheckObjectRecursionPrevention() throws Exception { |
| Node n1 = new Node(); |
| Node n2 = new Node(); |
| Node n3 = new Node(); |
| Node n4 = new Node(); |
| |
| n1.name = "n1"; |
| n2.name = "n2"; |
| n3.name = "n3"; |
| n4.name = "n4"; |
| |
| n1.next = n2; |
| n2.next = n3; |
| n3.next = n4; |
| n4.next = n3; |
| |
| n1.nodes = new Node[4]; |
| n2.nodes = n1.nodes; |
| n3.nodes = n1.nodes; |
| n4.nodes = n1.nodes; |
| |
| n1.nodes[0] = n1; |
| n1.nodes[1] = n2; |
| n1.nodes[2] = n3; |
| n1.nodes[3] = n4; |
| |
| String expN1 = n1.toString(); |
| String expN2 = n2.toString(); |
| String expN3 = n3.toString(); |
| String expN4 = n4.toString(); |
| |
| info(expN1); |
| info(expN2); |
| info(expN3); |
| info(expN4); |
| info(GridToStringBuilder.toString("Test", "Appended vals", n1)); |
| |
| CyclicBarrier bar = new CyclicBarrier(4); |
| |
| IgniteInternalFuture<String> fut1 = GridTestUtils.runAsync(new BarrierCallable(bar, n1, expN1)); |
| IgniteInternalFuture<String> fut2 = GridTestUtils.runAsync(new BarrierCallable(bar, n2, expN2)); |
| IgniteInternalFuture<String> fut3 = GridTestUtils.runAsync(new BarrierCallable(bar, n3, expN3)); |
| IgniteInternalFuture<String> fut4 = GridTestUtils.runAsync(new BarrierCallable(bar, n4, expN4)); |
| |
| fut1.get(3_000); |
| fut2.get(3_000); |
| fut3.get(3_000); |
| fut4.get(3_000); |
| } |
| |
| /** |
| * Test class. |
| */ |
| private static class Node { |
| /** */ |
| @GridToStringInclude |
| String name; |
| |
| /** */ |
| @GridToStringInclude |
| Node next; |
| |
| /** */ |
| @GridToStringInclude |
| Node[] nodes; |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return GridToStringBuilder.toString(Node.class, this); |
| } |
| } |
| |
| /** |
| * Test class. |
| */ |
| private static class BarrierCallable implements Callable<String> { |
| /** */ |
| CyclicBarrier bar; |
| |
| /** */ |
| Object obj; |
| |
| /** Expected value of {@code toString()} method. */ |
| String exp; |
| |
| /** */ |
| private BarrierCallable(CyclicBarrier bar, Object obj, String exp) { |
| this.bar = bar; |
| this.obj = obj; |
| this.exp = exp; |
| } |
| |
| /** {@inheritDoc} */ |
| @Override public String call() throws Exception { |
| for (int i = 0; i < 10; i++) { |
| bar.await(); |
| |
| assertEquals(exp, obj.toString()); |
| } |
| |
| return null; |
| } |
| } |
| |
| /** |
| * JUnit. |
| */ |
| @Test |
| public void testToStringPerformance() { |
| TestClass1 obj = new TestClass1(); |
| |
| IgniteLogger log = log(); |
| |
| // Warm up. |
| obj.toStringAutomatic(); |
| |
| long start = System.currentTimeMillis(); |
| |
| for (int i = 0; i < 100000; i++) |
| obj.toStringManual(); |
| |
| log.info("Manual toString() took: " + (System.currentTimeMillis() - start) + "ms"); |
| |
| start = System.currentTimeMillis(); |
| |
| for (int i = 0; i < 100000; i++) |
| obj.toStringAutomatic(); |
| |
| log.info("Automatic toString() took: " + (System.currentTimeMillis() - start) + "ms"); |
| } |
| |
| /** |
| * Test array print. |
| * @param v value to get array class and fill array. |
| * @param limit value of IGNITE_TO_STRING_COLLECTION_LIMIT. |
| * @throws Exception if failed. |
| */ |
| private <T, V> void testArr(V v, int limit) throws Exception { |
| T[] arrOf = (T[]) Array.newInstance(v.getClass(), limit + 1); |
| Arrays.fill(arrOf, v); |
| T[] arr = Arrays.copyOf(arrOf, limit); |
| |
| checkArrayOverflow(arrOf, arr, limit); |
| } |
| |
| /** |
| * Test array print. |
| * |
| * @throws Exception if failed. |
| */ |
| @Test |
| public void testArrLimitWithRecursion() throws Exception { |
| int limit = IgniteSystemProperties.getInteger(IGNITE_TO_STRING_COLLECTION_LIMIT, 100); |
| |
| ArrayList[] arrOf = new ArrayList[limit + 1]; |
| Arrays.fill(arrOf, new ArrayList()); |
| ArrayList[] arr = Arrays.copyOf(arrOf, limit); |
| |
| arrOf[0].add(arrOf); |
| arr[0].add(arr); |
| |
| checkArrayOverflow(arrOf, arr, limit); |
| } |
| |
| /** |
| * @param arrOf Array. |
| * @param arr Array copy. |
| * @param limit Array limit. |
| */ |
| private void checkArrayOverflow(Object[] arrOf, Object[] arr, int limit) { |
| String arrStr = GridToStringBuilder.arrayToString(arr); |
| String arrOfStr = GridToStringBuilder.arrayToString(arrOf); |
| |
| // Simulate overflow |
| StringBuilder resultSB = new StringBuilder(arrStr); |
| resultSB.deleteCharAt(resultSB.length()-1); |
| resultSB.append("... and ").append(arrOf.length - limit).append(" more]"); |
| |
| arrStr = resultSB.toString(); |
| |
| info(arrOfStr); |
| info(arrStr); |
| |
| assertTrue("Collection limit error in array of type " + arrOf.getClass().getName() |
| + " error, normal arr: <" + arrStr + ">, overflowed arr: <" + arrOfStr + ">", arrStr.equals(arrOfStr)); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringCollectionLimits() throws Exception { |
| int limit = IgniteSystemProperties.getInteger(IGNITE_TO_STRING_COLLECTION_LIMIT, 100); |
| |
| Object vals[] = new Object[] {Byte.MIN_VALUE, Boolean.TRUE, Short.MIN_VALUE, Integer.MIN_VALUE, Long.MIN_VALUE, |
| Float.MIN_VALUE, Double.MIN_VALUE, Character.MIN_VALUE, new TestClass1()}; |
| for (Object val : vals) |
| testArr(val, limit); |
| |
| int[] intArr1 = new int[0]; |
| |
| assertEquals("[]", GridToStringBuilder.arrayToString(intArr1)); |
| assertEquals("null", GridToStringBuilder.arrayToString(null)); |
| |
| int[] intArr2 = {1, 2, 3}; |
| |
| assertEquals("[1, 2, 3]", GridToStringBuilder.arrayToString(intArr2)); |
| |
| Object[] intArr3 = {2, 3, 4}; |
| |
| assertEquals("[2, 3, 4]", GridToStringBuilder.arrayToString(intArr3)); |
| |
| byte[] byteArr = new byte[1]; |
| |
| byteArr[0] = 1; |
| assertEquals(Arrays.toString(byteArr), GridToStringBuilder.arrayToString(byteArr)); |
| byteArr = Arrays.copyOf(byteArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(byteArr).contains("... and 1 more")); |
| |
| boolean[] boolArr = new boolean[1]; |
| |
| boolArr[0] = true; |
| assertEquals(Arrays.toString(boolArr), GridToStringBuilder.arrayToString(boolArr)); |
| boolArr = Arrays.copyOf(boolArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(boolArr).contains("... and 1 more")); |
| |
| short[] shortArr = new short[1]; |
| |
| shortArr[0] = 100; |
| assertEquals(Arrays.toString(shortArr), GridToStringBuilder.arrayToString(shortArr)); |
| shortArr = Arrays.copyOf(shortArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(shortArr).contains("... and 1 more")); |
| |
| int[] intArr = new int[1]; |
| |
| intArr[0] = 10000; |
| assertEquals(Arrays.toString(intArr), GridToStringBuilder.arrayToString(intArr)); |
| intArr = Arrays.copyOf(intArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(intArr).contains("... and 1 more")); |
| |
| long[] longArr = new long[1]; |
| |
| longArr[0] = 10000000; |
| assertEquals(Arrays.toString(longArr), GridToStringBuilder.arrayToString(longArr)); |
| longArr = Arrays.copyOf(longArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(longArr).contains("... and 1 more")); |
| |
| float[] floatArr = new float[1]; |
| |
| floatArr[0] = 1.f; |
| assertEquals(Arrays.toString(floatArr), GridToStringBuilder.arrayToString(floatArr)); |
| floatArr = Arrays.copyOf(floatArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(floatArr).contains("... and 1 more")); |
| |
| double[] doubleArr = new double[1]; |
| |
| doubleArr[0] = 1.; |
| assertEquals(Arrays.toString(doubleArr), GridToStringBuilder.arrayToString(doubleArr)); |
| doubleArr = Arrays.copyOf(doubleArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(doubleArr).contains("... and 1 more")); |
| |
| char[] cArr = new char[1]; |
| |
| cArr[0] = 'a'; |
| assertEquals(Arrays.toString(cArr), GridToStringBuilder.arrayToString(cArr)); |
| cArr = Arrays.copyOf(cArr, 101); |
| assertTrue("Can't find \"... and 1 more\" in overflowed array string!", |
| GridToStringBuilder.arrayToString(cArr).contains("... and 1 more")); |
| |
| Map<String, String> strMap = new TreeMap<>(); |
| List<String> strList = new ArrayList<>(limit+1); |
| |
| TestClass1 testCls = new TestClass1(); |
| |
| testCls.strMap = strMap; |
| testCls.strListIncl = strList; |
| |
| for (int i = 0; i < limit; i++) { |
| strMap.put("k" + i, "v"); |
| strList.add("e"); |
| } |
| |
| checkColAndMap(testCls); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringColAndMapLimitWithRecursion() throws Exception { |
| int limit = IgniteSystemProperties.getInteger(IGNITE_TO_STRING_COLLECTION_LIMIT, 100); |
| Map strMap = new TreeMap<>(); |
| List strList = new ArrayList<>(limit+1); |
| |
| TestClass1 testClass = new TestClass1(); |
| testClass.strMap = strMap; |
| testClass.strListIncl = strList; |
| |
| Map m = new TreeMap(); |
| m.put("m", strMap); |
| |
| List l = new ArrayList(); |
| l.add(strList); |
| |
| strMap.put("k0", m); |
| strList.add(l); |
| |
| for (int i = 1; i < limit; i++) { |
| strMap.put("k" + i, "v"); |
| strList.add("e"); |
| } |
| |
| checkColAndMap(testClass); |
| } |
| |
| /** |
| * @param testCls Class with collection and map included in toString(). |
| */ |
| private void checkColAndMap(TestClass1 testCls) { |
| String testClsStr = GridToStringBuilder.toString(TestClass1.class, testCls); |
| |
| testCls.strMap.put("kz", "v"); // important to add last element in TreeMap here |
| testCls.strListIncl.add("e"); |
| |
| String testClsStrOf = GridToStringBuilder.toString(TestClass1.class, testCls); |
| |
| String testClsStrOfR = testClsStrOf.replaceAll("... and 1 more",""); |
| |
| info(testClsStr); |
| info(testClsStrOf); |
| info(testClsStrOfR); |
| |
| assertTrue("Collection limit error in Map or List, normal: <" + testClsStr + ">, overflowed: <" |
| + testClsStrOf + ">", testClsStr.length() == testClsStrOfR.length()); |
| } |
| |
| /** |
| * @throws Exception If failed. |
| */ |
| @Test |
| public void testToStringSizeLimits() throws Exception { |
| int limit = IgniteSystemProperties.getInteger(IGNITE_TO_STRING_MAX_LENGTH, 10_000); |
| int tailLen = limit / 10 * 2; |
| |
| StringBuilder sb = new StringBuilder(limit + 10); |
| |
| for (int i = 0; i < limit - 100; i++) |
| sb.append('a'); |
| |
| String actual = GridToStringBuilder.toString(TestClass2.class, new TestClass2(sb.toString())); |
| String exp = "TestClass2 [str=" + sb + ", nullArr=null]"; |
| |
| assertEquals(exp, actual); |
| |
| for (int i = 0; i < 110; i++) |
| sb.append('b'); |
| |
| actual = GridToStringBuilder.toString(TestClass2.class, new TestClass2(sb.toString())); |
| exp = "TestClass2 [str=" + sb + ", nullArr=null]"; |
| |
| assertEquals(exp.substring(0, limit - tailLen), actual.substring(0, limit - tailLen)); |
| assertEquals(exp.substring(exp.length() - tailLen), actual.substring(actual.length() - tailLen)); |
| |
| assertTrue(actual.contains("... and")); |
| assertTrue(actual.contains("skipped ...")); |
| } |
| |
| /** |
| * |
| */ |
| @Test |
| public void testObjectPlusStringToString() { |
| IgniteTxKey k = new IgniteTxKey(new KeyCacheObjectImpl(1, null, 1), 123); |
| |
| info(k.toString()); |
| |
| assertTrue("Wrong string: " + k, k.toString().startsWith("IgniteTxKey [")); |
| } |
| |
| /** |
| * |
| */ |
| @Test |
| public void testHierarchy() { |
| Wrapper w = new Wrapper(); |
| Parent p = w.p; |
| String hash = identity(p); |
| |
| checkHierarchy("Wrapper [p=Child [b=0, pb=Parent[] [null], super=Parent [a=0, pa=Parent[] [null]]]]", w); |
| |
| p.pa[0] = p; |
| |
| checkHierarchy("Wrapper [p=Child" + hash + |
| " [b=0, pb=Parent[] [null], super=Parent [a=0, pa=Parent[] [Child" + hash + "]]]]", w); |
| |
| ((Child)p).pb[0] = p; |
| |
| checkHierarchy("Wrapper [p=Child" + hash + " [b=0, pb=Parent[] [Child" + hash |
| + "], super=Parent [a=0, pa=Parent[] [Child" + hash + "]]]]", w); |
| } |
| |
| /** |
| * Test GridToStringBuilder memory consumption. |
| */ |
| @Test |
| public void testMemoryConsumption() { |
| int objCnt = 100; |
| |
| ThreadMXBean bean = (ThreadMXBean)ManagementFactory.getThreadMXBean(); |
| |
| TestClass2 obj = new TestClass2(new String(new char[1_000_000])); |
| |
| List<TestClass2> arr = new ArrayList<>(objCnt); |
| |
| for (int i = 1; i <= objCnt; i++) |
| arr.add(new TestClass2(new String(new char[i]))); |
| |
| GridToStringBuilder.toString(TestClass2.class, obj); |
| |
| long allocated0 = bean.getThreadAllocatedBytes(Thread.currentThread().getId()); |
| |
| for (TestClass2 item : arr) |
| GridToStringBuilder.toString(TestClass2.class, item); |
| |
| long allocated1 = bean.getThreadAllocatedBytes(Thread.currentThread().getId()); |
| |
| log.info("Memory allocated by GridToStringBuilder for " + objCnt + " objects: " + (allocated1 - allocated0)); |
| |
| assertTrue("Too much memory allocated by GridToStringBuilder: " + (allocated1 - allocated0), |
| allocated1 - allocated0 < 1_000_000); |
| } |
| |
| |
| |
| /** |
| * Checking that method |
| * {@link GridToStringBuilder#compact(Collection, Function) compact} works |
| * correctly for {@link Integer}. |
| */ |
| @Test |
| public void testCompactIntegers() { |
| List<Integer> emptyList = emptyList(); |
| List<Integer> intList = asList(1, 2, 3, 9, 8, 7, 12); |
| |
| String compactStr = "[1-3, 7-9, 12]"; |
| |
| Function<Integer, Integer> nextVal = i -> i + 1; |
| |
| checkCompact(emptyList, intList, nextVal, compactStr); |
| |
| assertEquals("[]", compact(emptyList)); |
| assertEquals(compactStr, compact(intList)); |
| } |
| |
| /** |
| * Checking that method |
| * {@link GridToStringBuilder#compact(Collection, Function) compact} works |
| * correctly for {@link Double}. |
| */ |
| @Test |
| public void testCompactDoubles() { |
| checkCompact( |
| emptyList(), |
| asList(1.0, 2.0, 3.0, 9.0, 8.0, 7.0, 12.0), |
| i -> i + 1.0, |
| "[1.0-3.0, 7.0-9.0, 12.0]" |
| ); |
| } |
| |
| /** |
| * Checking that method |
| * {@link GridToStringBuilder#compact(Collection, Function) compact} works |
| * correctly for {@link Long}. |
| */ |
| @Test |
| public void testCompactLongs() { |
| checkCompact( |
| emptyList(), |
| asList(1L, 2L, 3L, 9L, 8L, 7L, 12L), |
| i -> i + 1L, |
| "[1-3, 7-9, 12]" |
| ); |
| } |
| |
| /** |
| * Checking the correct operation of method |
| * {@link GridToStringBuilder#compact(Collection, Function) compact}. |
| * For an empty collection of numbers, "[] " is expected, and for a |
| * non-empty collection, the value of the parameter {@code numCol} is |
| * expected. |
| * |
| * @param emptyCol Empty collection. |
| * @param numCol Not an empty collection of numbers. |
| * @param nextNum Function for getting the next number. |
| * @param compactStr Expected compact string for param {@code numCol}. |
| */ |
| private <T extends Number & Comparable<? super T>> void checkCompact( |
| Collection<T> emptyCol, |
| Collection<T> numCol, |
| Function<T, T> nextNum, |
| String compactStr |
| ) { |
| assertEquals("[]", compact(emptyCol, nextNum)); |
| assertEquals(compactStr, compact(numCol, nextNum)); |
| } |
| |
| /** |
| * @param exp Expected. |
| * @param w Wrapper. |
| */ |
| private void checkHierarchy(String exp, Wrapper w) { |
| String wS = w.toString(); |
| |
| info(wS); |
| |
| assertEquals(exp, wS); |
| } |
| |
| /** |
| * Test class. |
| */ |
| private static class TestClass1 { |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringOrder(0) |
| private String id = "1234567890"; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private int intVar; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringInclude(sensitive = true) |
| private long longVar; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringOrder(1) |
| private final UUID uuidVar = UUID.randomUUID(); |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private boolean boolVar; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private byte byteVar; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private String name = "qwertyuiopasdfghjklzxcvbnm"; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private final Integer finalInt = 2; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private List<String> strList; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringInclude |
| private Map<String, String> strMap; |
| |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringInclude |
| private List<String> strListIncl; |
| |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private final Object obj = new Object(); |
| |
| /** */ |
| @SuppressWarnings("unused") |
| private ReadWriteLock lock; |
| |
| /** |
| * @return Manual string. |
| */ |
| String toStringManual() { |
| StringBuilder buf = new StringBuilder(); |
| |
| buf.append(getClass().getSimpleName()).append(" ["); |
| |
| buf.append("id=").append(id).append(", "); |
| buf.append("uuidVar=").append(uuidVar).append(", "); |
| buf.append("intVar=").append(intVar).append(", "); |
| if (S.includeSensitive()) |
| buf.append("longVar=").append(longVar).append(", "); |
| buf.append("boolVar=").append(boolVar).append(", "); |
| buf.append("byteVar=").append(byteVar).append(", "); |
| buf.append("name=").append(name).append(", "); |
| buf.append("finalInt=").append(finalInt).append(", "); |
| buf.append("strMap=").append(strMap).append(", "); |
| buf.append("strListIncl=").append(strListIncl); |
| |
| buf.append("]"); |
| |
| return buf.toString(); |
| } |
| |
| /** |
| * @return Automatic string. |
| */ |
| String toStringAutomatic() { |
| return S.toString(TestClass1.class, this); |
| } |
| |
| /** |
| * @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 toStringWithAdditionalManual() { |
| StringBuilder s = new StringBuilder(toStringManual()); |
| s.setLength(s.length() - 1); |
| s.append(", newParam1=").append(1); |
| if (S.includeSensitive()) |
| s.append(", newParam2=").append(2); |
| s.append(']'); |
| return s.toString(); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private static class TestClass2{ |
| /** */ |
| @SuppressWarnings("unused") |
| @GridToStringInclude |
| private String str; |
| |
| /** */ |
| @GridToStringInclude |
| private Object[] nullArr; |
| |
| /** |
| * @param str String. |
| */ |
| TestClass2(String str) { |
| this.str = str; |
| } |
| } |
| |
| /** |
| * |
| */ |
| private static class Parent { |
| /** */ |
| private int a; |
| |
| /** */ |
| @GridToStringInclude |
| private Parent pa[] = new Parent[1]; |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(Parent.class, this); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private static class Child extends Parent { |
| /** */ |
| private int b; |
| |
| /** */ |
| @GridToStringInclude |
| private Parent pb[] = new Parent[1]; |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(Child.class, this, super.toString()); |
| } |
| } |
| |
| /** |
| * |
| */ |
| private static class Wrapper { |
| /** */ |
| @GridToStringInclude |
| Parent p = new Child(); |
| |
| /** {@inheritDoc} */ |
| @Override public String toString() { |
| return S.toString(Wrapper.class, this); |
| } |
| } |
| } |