| Index: third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/util/TextBuilder.java
|
| diff --git a/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/util/TextBuilder.java b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/util/TextBuilder.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6d55d52f010752417ca1a0dc137b6cab0bfe0754
|
| --- /dev/null
|
| +++ b/third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/util/TextBuilder.java
|
| @@ -0,0 +1,202 @@
|
| +/*
|
| + * Copyright 2011 Google Inc.
|
| + *
|
| + * Licensed 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 com.google.ipc.invalidation.util;
|
| +
|
| +import java.lang.reflect.Field;
|
| +import java.lang.reflect.Modifier;
|
| +
|
| +/**
|
| + * A {@link TextBuilder} is an abstraction that allows classes to efficiently append their string
|
| + * representations and then use them later for human consumption, e.g., for debugging or logging. It
|
| + * is currently a wrapper around {@link StringBuilder} and {@link Formatter} to give us format and
|
| + * append capabilities together. All append methods return this TextBuilder so that the method calls
|
| + * can be chained.
|
| + *
|
| + */
|
| +public class TextBuilder {
|
| +
|
| + private final StringBuilder builder;
|
| + private final UtilFormatter formatter;
|
| +
|
| + /**
|
| + * Given an {@code object} that is an instance of {@code clazz}, outputs names and values of all
|
| + * member fields declared on {@code clazz}. This method should be used carefully:
|
| + * <ol>
|
| + * <li>This method is expensive. For frequently logged types, an ad hoc
|
| + * {@link InternalBase#toCompactString} implementation is preferred.</li>
|
| + * <li>May overflow the stack if there is a cycle in an object graph.</li>
|
| + * <li>Custom formatters have been implemented for many protos. They will not be used by this
|
| + * method.</li>
|
| + * </ol>
|
| + */
|
| + public static void outputFieldsToBuilder(TextBuilder builder, Object object, Class<?> clazz) {
|
| + Preconditions.checkArgument(clazz.isAssignableFrom(object.getClass()));
|
| +
|
| + // Get all the fields and print them using toCompactString if possible;
|
| + // otherwise, via toString
|
| + Field[] fields = clazz.getDeclaredFields();
|
| + for (Field field : fields) {
|
| + try {
|
| + // Ignore static final fields, as they're uninteresting.
|
| + int modifiers = field.getModifiers();
|
| + if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
|
| + continue;
|
| + }
|
| +
|
| + field.setAccessible(true);
|
| + builder.append(field.getName() + " = ");
|
| + Object fieldValue = field.get(object);
|
| + if (fieldValue instanceof InternalBase) {
|
| + ((InternalBase) fieldValue).toCompactString(builder);
|
| + } else {
|
| + builder.append(fieldValue);
|
| + }
|
| + builder.append(", ");
|
| + } catch (IllegalArgumentException e) {
|
| + e.printStackTrace();
|
| + } catch (IllegalAccessException e) {
|
| + e.printStackTrace();
|
| + }
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Returns an empty TextBuilder to which various objects' string
|
| + * representations can be added later.
|
| + */
|
| + public TextBuilder() {
|
| + builder = new StringBuilder();
|
| + formatter = new UtilFormatter(builder);
|
| + }
|
| +
|
| + /**
|
| + * Appends the string representation of {@code c} to this builder.
|
| + *
|
| + * @param c the character being appended
|
| + */
|
| + public TextBuilder append(char c) {
|
| + builder.append(c);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the string representation of {@code i} to this builder.
|
| + *
|
| + * @param i the integer being appended
|
| + */
|
| + public TextBuilder append(int i) {
|
| + builder.append(i);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the toString representation of {@code object} to this builder.
|
| + */
|
| + public TextBuilder append(Object object) {
|
| + builder.append(object);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the {@code InternalBase#toCompactString} representation of {@code object} to this
|
| + * builder.
|
| + */
|
| + public TextBuilder append(InternalBase object) {
|
| + if (object == null) {
|
| + return append("null");
|
| + }
|
| + object.toCompactString(this);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the comma-separated {@code InternalBase#toCompactString} representations of
|
| + * {@code objects} to this builder.
|
| + */
|
| + public TextBuilder append(Iterable<? extends InternalBase> objects) {
|
| + if (objects == null) {
|
| + return this;
|
| + }
|
| + boolean first = true;
|
| + for (InternalBase object : objects) {
|
| + if (first) {
|
| + first = false;
|
| + } else {
|
| + builder.append(", ");
|
| + }
|
| + append(object);
|
| + }
|
| + return this;
|
| + }
|
| +
|
| + /** Appends the {@link Bytes#toString} representation of {@code bytes} to this builder. */
|
| + public TextBuilder append(byte[] bytes) {
|
| + if (bytes == null) {
|
| + return append("null");
|
| + }
|
| + Bytes.toCompactString(this, bytes);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the string representation of {@code l} to this builder.
|
| + *
|
| + * @param l the long being appended
|
| + */
|
| + public TextBuilder append(long l) {
|
| + builder.append(l);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends the string representation of {@code b} to this builder.
|
| + *
|
| + * @param b the boolean being appended
|
| + */
|
| + public TextBuilder append(boolean b) {
|
| + builder.append(b);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Appends {@code s} to this builder.
|
| + *
|
| + * @param s the string being appended
|
| + */
|
| + public TextBuilder append(String s) {
|
| + builder.append(s);
|
| + return this;
|
| + }
|
| +
|
| + /**
|
| + * Writes a formatted string to this using the specified format string and
|
| + * arguments.
|
| + *
|
| + * @param format the format as used in {@link java.util.Formatter}
|
| + * @param args the arguments that are converted to their string form using
|
| + * {@code format}
|
| + */
|
| + public TextBuilder appendFormat(String format, Object... args) {
|
| + formatter.format(format, args);
|
| + return this;
|
| + }
|
| +
|
| + @Override
|
| + public String toString() {
|
| + return builder.toString();
|
| + }
|
| +}
|
|
|