All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.inject.rebind.util.PrettyPrinter Maven / Gradle / Ivy

Go to download

GIN (GWT INjection) brings automatic dependency injection to Google Web Toolkit client-side code. GIN is built on top of Guice and uses (a subset of) Guice's binding language.

The newest version!
/*
 * 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.gwt.inject.rebind.util;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.inject.rebind.binding.Dependency;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;

import java.lang.annotation.Annotation;
import java.util.List;

/**
 * Pretty-printer that formats internal types for human consumption in error
 * messages.
 *
 * 

{@link #format(String, Object...)} acts like {@link String#format}, except * that it detects and pretty-prints the following argument types: * *

    *
  • {@link Class}: formatted as "org.example.Class$SubClass"
  • *
  • {@link Key}: formatted as "@org.example.Annotation org.example.Class$SubClass"
  • *
  • {@link List}: formatted as a dependency path preceded by a newline. If * the path begins at {@link Dependency.GINJECTOR}, that key is hidden, and the context * of the outgoing dependency is given as the context of the first key in the displayed * path.
  • *
* * All other arguments are passed unchanged to {@link String#format}. */ public final class PrettyPrinter { private PrettyPrinter() { } /** * Log a pretty-printed message if the given log level is active. The message * is only formatted if it will be logged. */ public static void log(TreeLogger logger, TreeLogger.Type type, String formatString, Object... args) { if (logger.isLoggable(type)) { logger.log(type, format(formatString, args)); } } /** * Generate a string based on a format template as {@link String#format} * would, using the pretty-printing rules specified in the class * documentation. */ public static String format(String formatString, Object... args) { // Rewrites the varargs so that objects that need special formatting are // replaced with formatted strings, then hands off to {@link String#format}. Object[] formattedArgs = new Object[args.length]; for (int i = 0; i < args.length; ++i) { formattedArgs[i] = formatObject(args[i]); } return String.format(formatString, (Object[]) formattedArgs); } /** * Pretty-print a single object. */ private static Object formatObject(Object object) { if (object instanceof Class) { return formatArg((Class) object); } else if (object instanceof Key) { return formatArg((Key) object); } else if (object instanceof List) { List list = (List) object; // Empirically check if this is a List. boolean allDependencies = true; for (Object entry : list) { if (!(entry instanceof Dependency)) { allDependencies = false; break; } } if (allDependencies) { return formatArg((List) list); } else { return object; } } else { return object; } } private static String formatArg(Class type) { // Make sure classes are formatted in a manner that's consistent with type // literals. return TypeLiteral.get(type).toString(); } private static String formatArg(Key key) { StringBuilder builder = new StringBuilder(); formatArgTo(key, builder); return builder.toString(); } /** * Formats a list of dependencies as a dependency path; see the class * comments. */ private static String formatArg(List path) { StringBuilder builder = new StringBuilder(); formatArgTo(path, builder); return builder.toString(); } private static void formatArgTo(Key key, StringBuilder builder) { Annotation annotation = key.getAnnotation(); if (annotation != null) { builder.append(annotation); builder.append(" "); } else if (key.getAnnotationType() != null) { builder.append("@"); builder.append(formatArg(key.getAnnotationType())); builder.append(" "); } builder.append(key.getTypeLiteral()); } /** * Formats a list of dependencies as a dependency path; see the class * comments. */ private static void formatArgTo(List path, StringBuilder builder) { if (path.isEmpty()) { return; } builder.append("\n"); boolean first = true; Key previousTarget = null; // For sanity-checking. for (Dependency dependency : path) { Key source = dependency.getSource(); Key target = dependency.getTarget(); // Sanity-check. if (previousTarget != null && !previousTarget.equals(source)) { throw new IllegalArgumentException("Dependency list is not a path."); } // There are two possible overall shapes of the list: // // If it starts with GINJECTOR, we get this: // // Key1 [context] // -> Key2 [context] // ... // // Otherwise (e.g., if we're dumping a cycle), we get this: // // Key1 // -> Key2 [context] // -> Key3 [context] // ... if (first) { if (source == Dependency.GINJECTOR) { formatArgTo(target, builder); builder.append(String.format(" [%s]%n", dependency.getContext())); } else { formatArgTo(source, builder); builder.append("\n -> "); formatArgTo(target, builder); builder.append(String.format(" [%s]%n", dependency.getContext())); } first = false; } else { builder.append(" -> "); formatArgTo(target, builder); builder.append(String.format(" [%s]%n", dependency.getContext())); } previousTarget = target; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy