| OLD | NEW |
| (Empty) | |
| 1 /* |
| 2 * Copyright 2011 Google Inc. |
| 3 * |
| 4 * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 * you may not use this file except in compliance with the License. |
| 6 * You may obtain a copy of the License at |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. |
| 15 */ |
| 16 |
| 17 package com.google.ipc.invalidation.util; |
| 18 |
| 19 import java.lang.reflect.Field; |
| 20 import java.lang.reflect.Modifier; |
| 21 |
| 22 /** |
| 23 * A {@link TextBuilder} is an abstraction that allows classes to efficiently ap
pend their string |
| 24 * representations and then use them later for human consumption, e.g., for debu
gging or logging. It |
| 25 * is currently a wrapper around {@link StringBuilder} and {@link Formatter} to
give us format and |
| 26 * append capabilities together. All append methods return this TextBuilder so t
hat the method calls |
| 27 * can be chained. |
| 28 * |
| 29 */ |
| 30 public class TextBuilder { |
| 31 |
| 32 private final StringBuilder builder; |
| 33 private final UtilFormatter formatter; |
| 34 |
| 35 /** |
| 36 * Given an {@code object} that is an instance of {@code clazz}, outputs names
and values of all |
| 37 * member fields declared on {@code clazz}. This method should be used careful
ly: |
| 38 * <ol> |
| 39 * <li>This method is expensive. For frequently logged types, an ad hoc |
| 40 * {@link InternalBase#toCompactString} implementation is preferred.</li> |
| 41 * <li>May overflow the stack if there is a cycle in an object graph.</li> |
| 42 * <li>Custom formatters have been implemented for many protos. They will not
be used by this |
| 43 * method.</li> |
| 44 * </ol> |
| 45 */ |
| 46 public static void outputFieldsToBuilder(TextBuilder builder, Object object, C
lass<?> clazz) { |
| 47 Preconditions.checkArgument(clazz.isAssignableFrom(object.getClass())); |
| 48 |
| 49 // Get all the fields and print them using toCompactString if possible; |
| 50 // otherwise, via toString |
| 51 Field[] fields = clazz.getDeclaredFields(); |
| 52 for (Field field : fields) { |
| 53 try { |
| 54 // Ignore static final fields, as they're uninteresting. |
| 55 int modifiers = field.getModifiers(); |
| 56 if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { |
| 57 continue; |
| 58 } |
| 59 |
| 60 field.setAccessible(true); |
| 61 builder.append(field.getName() + " = "); |
| 62 Object fieldValue = field.get(object); |
| 63 if (fieldValue instanceof InternalBase) { |
| 64 ((InternalBase) fieldValue).toCompactString(builder); |
| 65 } else { |
| 66 builder.append(fieldValue); |
| 67 } |
| 68 builder.append(", "); |
| 69 } catch (IllegalArgumentException e) { |
| 70 e.printStackTrace(); |
| 71 } catch (IllegalAccessException e) { |
| 72 e.printStackTrace(); |
| 73 } |
| 74 } |
| 75 } |
| 76 |
| 77 /** |
| 78 * Returns an empty TextBuilder to which various objects' string |
| 79 * representations can be added later. |
| 80 */ |
| 81 public TextBuilder() { |
| 82 builder = new StringBuilder(); |
| 83 formatter = new UtilFormatter(builder); |
| 84 } |
| 85 |
| 86 /** |
| 87 * Appends the string representation of {@code c} to this builder. |
| 88 * |
| 89 * @param c the character being appended |
| 90 */ |
| 91 public TextBuilder append(char c) { |
| 92 builder.append(c); |
| 93 return this; |
| 94 } |
| 95 |
| 96 /** |
| 97 * Appends the string representation of {@code i} to this builder. |
| 98 * |
| 99 * @param i the integer being appended |
| 100 */ |
| 101 public TextBuilder append(int i) { |
| 102 builder.append(i); |
| 103 return this; |
| 104 } |
| 105 |
| 106 /** |
| 107 * Appends the toString representation of {@code object} to this builder. |
| 108 */ |
| 109 public TextBuilder append(Object object) { |
| 110 builder.append(object); |
| 111 return this; |
| 112 } |
| 113 |
| 114 /** |
| 115 * Appends the {@code InternalBase#toCompactString} representation of {@code o
bject} to this |
| 116 * builder. |
| 117 */ |
| 118 public TextBuilder append(InternalBase object) { |
| 119 if (object == null) { |
| 120 return append("null"); |
| 121 } |
| 122 object.toCompactString(this); |
| 123 return this; |
| 124 } |
| 125 |
| 126 /** |
| 127 * Appends the comma-separated {@code InternalBase#toCompactString} representa
tions of |
| 128 * {@code objects} to this builder. |
| 129 */ |
| 130 public TextBuilder append(Iterable<? extends InternalBase> objects) { |
| 131 if (objects == null) { |
| 132 return this; |
| 133 } |
| 134 boolean first = true; |
| 135 for (InternalBase object : objects) { |
| 136 if (first) { |
| 137 first = false; |
| 138 } else { |
| 139 builder.append(", "); |
| 140 } |
| 141 append(object); |
| 142 } |
| 143 return this; |
| 144 } |
| 145 |
| 146 /** Appends the {@link Bytes#toString} representation of {@code bytes} to this
builder. */ |
| 147 public TextBuilder append(byte[] bytes) { |
| 148 if (bytes == null) { |
| 149 return append("null"); |
| 150 } |
| 151 Bytes.toCompactString(this, bytes); |
| 152 return this; |
| 153 } |
| 154 |
| 155 /** |
| 156 * Appends the string representation of {@code l} to this builder. |
| 157 * |
| 158 * @param l the long being appended |
| 159 */ |
| 160 public TextBuilder append(long l) { |
| 161 builder.append(l); |
| 162 return this; |
| 163 } |
| 164 |
| 165 /** |
| 166 * Appends the string representation of {@code b} to this builder. |
| 167 * |
| 168 * @param b the boolean being appended |
| 169 */ |
| 170 public TextBuilder append(boolean b) { |
| 171 builder.append(b); |
| 172 return this; |
| 173 } |
| 174 |
| 175 /** |
| 176 * Appends {@code s} to this builder. |
| 177 * |
| 178 * @param s the string being appended |
| 179 */ |
| 180 public TextBuilder append(String s) { |
| 181 builder.append(s); |
| 182 return this; |
| 183 } |
| 184 |
| 185 /** |
| 186 * Writes a formatted string to this using the specified format string and |
| 187 * arguments. |
| 188 * |
| 189 * @param format the format as used in {@link java.util.Formatter} |
| 190 * @param args the arguments that are converted to their string form using |
| 191 * {@code format} |
| 192 */ |
| 193 public TextBuilder appendFormat(String format, Object... args) { |
| 194 formatter.format(format, args); |
| 195 return this; |
| 196 } |
| 197 |
| 198 @Override |
| 199 public String toString() { |
| 200 return builder.toString(); |
| 201 } |
| 202 } |
| OLD | NEW |