1 package org.hamcrest; 2 3 import static java.lang.String.valueOf; 4 5 import java.util.Arrays; 6 import java.util.Iterator; 7 8 import org.hamcrest.internal.ArrayIterator; 9 import org.hamcrest.internal.SelfDescribingValueIterator; 10 11 /** 12 * A {@link Description} that is stored as a string. 13 */ 14 public abstract class BaseDescription implements Description { appendText(String text)15 public Description appendText(String text) { 16 append(text); 17 return this; 18 } 19 appendDescriptionOf(SelfDescribing value)20 public Description appendDescriptionOf(SelfDescribing value) { 21 value.describeTo(this); 22 return this; 23 } 24 appendValue(Object value)25 public Description appendValue(Object value) { 26 if (value == null) { 27 append("null"); 28 } else if (value instanceof String) { 29 toJavaSyntax((String) value); 30 } else if (value instanceof Character) { 31 append('"'); 32 toJavaSyntax((Character) value); 33 append('"'); 34 } else if (value instanceof Short) { 35 append('<'); 36 append(valueOf(value)); 37 append("s>"); 38 } else if (value instanceof Long) { 39 append('<'); 40 append(valueOf(value)); 41 append("L>"); 42 } else if (value instanceof Float) { 43 append('<'); 44 append(valueOf(value)); 45 append("F>"); 46 } else if (value.getClass().isArray()) { 47 appendValueList("[",", ","]", new ArrayIterator(value)); 48 } else { 49 append('<'); 50 append(valueOf(value)); 51 append('>'); 52 } 53 return this; 54 } 55 appendValueList(String start, String separator, String end, T... values)56 public <T> Description appendValueList(String start, String separator, String end, T... values) { 57 return appendValueList(start, separator, end, Arrays.asList(values)); 58 } 59 appendValueList(String start, String separator, String end, Iterable<T> values)60 public <T> Description appendValueList(String start, String separator, String end, Iterable<T> values) { 61 return appendValueList(start, separator, end, values.iterator()); 62 } 63 appendValueList(String start, String separator, String end, Iterator<T> values)64 private <T> Description appendValueList(String start, String separator, String end, Iterator<T> values) { 65 return appendList(start, separator, end, new SelfDescribingValueIterator<T>(values)); 66 } 67 appendList(String start, String separator, String end, Iterable<? extends SelfDescribing> values)68 public Description appendList(String start, String separator, String end, Iterable<? extends SelfDescribing> values) { 69 return appendList(start, separator, end, values.iterator()); 70 } 71 appendList(String start, String separator, String end, Iterator<? extends SelfDescribing> i)72 private Description appendList(String start, String separator, String end, Iterator<? extends SelfDescribing> i) { 73 boolean separate = false; 74 75 append(start); 76 while (i.hasNext()) { 77 if (separate) append(separator); 78 appendDescriptionOf(i.next()); 79 separate = true; 80 } 81 append(end); 82 83 return this; 84 } 85 86 87 /** Append the String <var>str</var> to the description. 88 * The default implementation passes every character to {@link #append(char)}. 89 * Override in subclasses to provide an efficient implementation. 90 */ append(String str)91 protected void append(String str) { 92 for (int i = 0; i < str.length(); i++) { 93 append(str.charAt(i)); 94 } 95 } 96 97 /** Append the char <var>c</var> to the description. 98 */ append(char c)99 protected abstract void append(char c); 100 toJavaSyntax(String unformatted)101 private void toJavaSyntax(String unformatted) { 102 append('"'); 103 for (int i = 0; i < unformatted.length(); i++) { 104 toJavaSyntax(unformatted.charAt(i)); 105 } 106 append('"'); 107 } 108 toJavaSyntax(char ch)109 private void toJavaSyntax(char ch) { 110 switch (ch) { 111 case '"': 112 append("\\\""); 113 break; 114 case '\n': 115 append("\\n"); 116 break; 117 case '\r': 118 append("\\r"); 119 break; 120 case '\t': 121 append("\\t"); 122 break; 123 default: 124 append(ch); 125 } 126 } 127 } 128