Roll cacheinvalidation to 20150720
[chromium-blink-merge.git] / third_party / cacheinvalidation / src / java / com / google / ipc / invalidation / util / TextBuilder.java
blob6b204cdea50cae344369fdf1cd7f9ed06ae41548
1 /*
2 * Copyright 2011 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.ipc.invalidation.util;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Modifier;
22 /**
23 * A {@link TextBuilder} is an abstraction that allows classes to efficiently append their string
24 * representations and then use them later for human consumption, e.g., for debugging 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 that the method calls
27 * can be chained.
30 public class TextBuilder {
32 private final StringBuilder builder;
33 private final UtilFormatter formatter;
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 carefully:
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>
46 public static void outputFieldsToBuilder(TextBuilder builder, Object object, Class<?> clazz) {
47 Preconditions.checkArgument(clazz.isAssignableFrom(object.getClass()));
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;
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);
68 builder.append(", ");
69 } catch (IllegalArgumentException e) {
70 e.printStackTrace();
71 } catch (IllegalAccessException e) {
72 e.printStackTrace();
77 /**
78 * Returns an empty TextBuilder to which various objects' string
79 * representations can be added later.
81 public TextBuilder() {
82 builder = new StringBuilder();
83 formatter = new UtilFormatter(builder);
86 /**
87 * Appends the string representation of {@code c} to this builder.
89 * @param c the character being appended
91 public TextBuilder append(char c) {
92 builder.append(c);
93 return this;
96 /**
97 * Appends the string representation of {@code i} to this builder.
99 * @param i the integer being appended
101 public TextBuilder append(int i) {
102 builder.append(i);
103 return this;
107 * Appends the toString representation of {@code object} to this builder.
109 public TextBuilder append(Object object) {
110 if (object instanceof InternalBase) {
111 return append((InternalBase) object);
112 } else {
113 builder.append(object);
114 return this;
119 * Appends the {@code InternalBase#toCompactString} representation of {@code object} to this
120 * builder.
122 public TextBuilder append(InternalBase object) {
123 if (object == null) {
124 return append("null");
126 object.toCompactString(this);
127 return this;
131 * Appends the comma-separated {@code InternalBase#toCompactString} representations of
132 * {@code objects} to this builder.
134 public TextBuilder append(Iterable<? extends InternalBase> objects) {
135 if (objects == null) {
136 return this;
138 boolean first = true;
139 for (InternalBase object : objects) {
140 if (first) {
141 first = false;
142 } else {
143 builder.append(", ");
145 append(object);
147 return this;
150 /** Appends the {@link Bytes#toString} representation of {@code bytes} to this builder. */
151 public TextBuilder append(byte[] bytes) {
152 if (bytes == null) {
153 return append("null");
155 Bytes.toCompactString(this, bytes);
156 return this;
160 * Appends the string representation of {@code l} to this builder.
162 * @param l the long being appended
164 public TextBuilder append(long l) {
165 builder.append(l);
166 return this;
170 * Appends the string representation of {@code b} to this builder.
172 * @param b the boolean being appended
174 public TextBuilder append(boolean b) {
175 builder.append(b);
176 return this;
180 * Appends {@code s} to this builder.
182 * @param s the string being appended
184 public TextBuilder append(String s) {
185 builder.append(s);
186 return this;
190 * Writes a formatted string to this using the specified format string and
191 * arguments.
193 * @param format the format as used in {@link java.util.Formatter}
194 * @param args the arguments that are converted to their string form using
195 * {@code format}
197 public TextBuilder appendFormat(String format, Object... args) {
198 formatter.format(format, args);
199 return this;
202 @Override
203 public String toString() {
204 return builder.toString();