![JAR search and dependency download from the Maven repository](/logo.png)
edu.stanford.nlp.util.logging.PrettyLogger Maven / Gradle / Ivy
package edu.stanford.nlp.util.logging;
import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import edu.stanford.nlp.util.logging.Redwood.RedwoodChannels;
import edu.stanford.nlp.util.Generics;
/**
* Primarily for debugging, PrettyLogger helps you dump various collection
* objects in a reasonably structured way via Redwood logging. It has support
* for many built in collection types (Mapping, Iterable, arrays, Properties) as
* well as anything that implements PrettyLoggable.
*
* @see PrettyLoggable
* @author David McClosky
* @author Gabor Angeli (+ primitive arrays; dictionaries)
*/
// TODO Should have an optional maximum depth, perhaps
public class PrettyLogger {
private static final RedwoodChannels DEFAULT_CHANNELS = new RedwoodChannels(Redwood.FORCE);
/**
* Static class.
*/
private PrettyLogger() {}
/*
* Main entry methods and utilities
*/
/**
* Pretty log an object. It will be logged to the default channel. Its class
* name will be used as a description.
*
* @param obj
* the object to be pretty logged
*/
public static void log(Object obj) {
log(obj.getClass().getSimpleName(), obj);
}
/**
* Pretty log an object along with its description. It will be logged to the
* default channel.
*
* @param description
* denote the object in the logs (via a track name, etc.).
* @param obj
* the object to be pretty logged
*/
public static void log(String description, Object obj) {
log(DEFAULT_CHANNELS, description, obj);
}
/**
* Pretty log an object. Its class name will be used as a description.
*
* @param channels
* the channels to pretty log to
* @param obj
* the object to be pretty logged
*/
public static void log(RedwoodChannels channels, Object obj) {
log(channels, obj.getClass().getSimpleName(), obj);
}
/**
* Pretty log an object.
*
* @param channels
* the channels to pretty log to
* @param description
* denote the object in the logs (via a track name, etc.).
* @param obj
* the object to be pretty logged
*/
// TODO perhaps some reflection magic can simplify this process?
@SuppressWarnings("unchecked")
public static void log(RedwoodChannels channels, String description, Object obj) {
if (obj instanceof Map) {
log(channels, description, (Map)obj);
} else if (obj instanceof PrettyLoggable) {
((PrettyLoggable) obj).prettyLog(channels, description);
} else if (obj instanceof Dictionary) {
log(channels, description, (Dictionary)obj);
} else if (obj instanceof Iterable) {
log(channels, description, (Iterable)obj);
} else if (obj.getClass().isArray()) {
Object[] arrayCopy; // the array to log
if(obj.getClass().getComponentType().isPrimitive()){
//(case: a primitive array)
Class componentClass = obj.getClass().getComponentType();
if(boolean.class.isAssignableFrom(componentClass)){
arrayCopy = new Object[((boolean[]) obj).length];
for(int i=0; i void log(RedwoodChannels channels, String description, Map mapping) {
Redwood.startTrack(description);
if (mapping == null) {
channels.log("(mapping is null)");
} else if (mapping.isEmpty()) {
channels.log("(empty)");
} else {
// convert keys to sorted list, if possible
List keys = new LinkedList();
for (K key : mapping.keySet()) {
keys.add(key);
}
Collections.sort(keys, (a, b) -> {
if (a != null && Comparable.class.isAssignableFrom(a.getClass())) {
return ((Comparable) a).compareTo(b);
} else {
return 0;
}
});
// log key/value pairs
int entryCounter = 0;
for (K key : keys) {
V value = mapping.get(key);
if (!dispatchable(key) && dispatchable(value)) {
log(channels, key.toString(), value);
} else if (dispatchable(key) || dispatchable(value)) {
Redwood.startTrack("Entry " + entryCounter);
if (dispatchable(key)) {
log(channels, "Key", key);
} else {
channels.logf("Key %s", key);
}
if (dispatchable(value)) {
log(channels, "Value", value);
} else {
channels.logf("Value %s", value);
}
Redwood.endTrack("Entry " + entryCounter);
} else {
channels.logf("%s = %s", key, value);
}
entryCounter++;
}
}
Redwood.endTrack(description);
}
/*
* Dictionaries (notably, Properties) -- convert them to Maps and dispatch
*/
private static void log(RedwoodChannels channels, String description, Dictionary dict) {
//(a real data structure)
Map map = Generics.newHashMap();
//(copy to map)
Enumeration keys = dict.keys();
while(keys.hasMoreElements()){
K key = keys.nextElement();
V value = dict.get(key);
map.put(key,value);
}
//(log like normal)
log(channels, description, map);
}
/*
* Iterables (includes Collection, List, Set, etc.)
*/
private static void log(RedwoodChannels channels, String description, Iterable iterable) {
Redwood.startTrack(description);
if (iterable == null) {
channels.log("(iterable is null)");
} else {
int index = 0;
for (T item : iterable) {
if (dispatchable(item) && item != iterable) {
log(channels, "Index " + index, item);
} else {
channels.logf("Index %d: %s", index, item == iterable ? "..." : item);
}
index++;
}
if (index == 0) {
channels.log("(empty)");
}
}
Redwood.endTrack(description);
}
/*
* Arrays
*/
private static void log(RedwoodChannels channels, String description, T[] array) {
Redwood.startTrack(description);
if (array == null) {
channels.log("(array is null)");
} else if (array.length == 0) {
channels.log("(empty)");
} else {
int index = 0;
for (T item : array) {
if (dispatchable(item)) {
log(channels, "Index " + index, item);
} else {
channels.logf("Index %d: %s", index, item);
}
index++;
}
}
Redwood.endTrack(description);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy