From f53c353981b9e658d8b8d23e86145171937fd90d Mon Sep 17 00:00:00 2001 From: Olof Larsson Date: Wed, 7 Jan 2015 15:54:48 +0100 Subject: [PATCH] Better StackTrace formatting and reflection get accessible. --- .../massivecraft/massivecore/util/MUtil.java | 97 +++++++++++++++++-- .../massivecore/util/ReflectionUtil.java | 59 ++++++++++- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/massivecraft/massivecore/util/MUtil.java b/src/main/java/com/massivecraft/massivecore/util/MUtil.java index 6b2100e6..ddf8ea59 100644 --- a/src/main/java/com/massivecraft/massivecore/util/MUtil.java +++ b/src/main/java/com/massivecraft/massivecore/util/MUtil.java @@ -1,7 +1,5 @@ package com.massivecraft.massivecore.util; -import java.io.PrintWriter; -import java.io.StringWriter; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.util.ArrayList; @@ -201,10 +199,97 @@ public class MUtil public static String getStackTraceString() { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - new Throwable().printStackTrace(pw); - return sw.toString(); + List strings = getStackTraceStrings(); + strings.remove(0); + return Txt.implode(strings, "\n"); + } + + public static List getStackTraceStrings() + { + StackTraceElement[] elements = Thread.currentThread().getStackTrace(); + elements = Arrays.copyOfRange(elements, 2, elements.length); + return getStackTraceStrings(elements); + } + + public static List getStackTraceStrings(List elements) + { + List ret = new MassiveList(); + + for (StackTraceElement element : elements) + { + ret.add(getStackTraceString(element)); + } + + return ret; + } + public static List getStackTraceStrings(StackTraceElement[] elements) + { + return getStackTraceStrings(Arrays.asList(elements)); + } + + // Same as the Java8 source but with color. + public static String getStackTraceString(StackTraceElement element) + { + ChatColor separatorColor = ChatColor.GRAY; + ChatColor classColor = ChatColor.YELLOW; + ChatColor methodColor = ChatColor.GREEN; + ChatColor fileColor = ChatColor.AQUA; + ChatColor lineColor = ChatColor.LIGHT_PURPLE; + + String className = element.getClassName(); + String methodName = element.getMethodName(); + boolean nativeMethod = element.isNativeMethod(); + String fileName = element.getFileName(); + int lineNumber = element.getLineNumber(); + + StringBuilder ret = new StringBuilder(); + + ret.append(classColor); + ret.append(className); + + ret.append(separatorColor); + ret.append("."); + + ret.append(methodColor); + ret.append(methodName); + + ret.append(separatorColor); + ret.append("("); + + ret.append(fileColor); + if (nativeMethod) + { + ret.append("Native Method"); + } + else + { + if (fileName != null && lineNumber >= 0) + { + ret.append(fileName); + + ret.append(separatorColor); + ret.append(":"); + + ret.append(lineColor); + ret.append(lineNumber); + } + else + { + if (fileName != null) + { + ret.append(fileName); + } + else + { + ret.append("Unknown Source"); + } + } + } + + ret.append(separatorColor); + ret.append(")"); + + return ret.toString(); } // -------------------------------------------- // diff --git a/src/main/java/com/massivecraft/massivecore/util/ReflectionUtil.java b/src/main/java/com/massivecraft/massivecore/util/ReflectionUtil.java index 12bac759..081529b0 100644 --- a/src/main/java/com/massivecraft/massivecore/util/ReflectionUtil.java +++ b/src/main/java/com/massivecraft/massivecore/util/ReflectionUtil.java @@ -1,21 +1,70 @@ package com.massivecraft.massivecore.util; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; public class ReflectionUtil { + // -------------------------------------------- // + // CONSTANTS + // -------------------------------------------- // + + private static Field FIELD_DOT_MODIFIERS; + + static + { + try + { + FIELD_DOT_MODIFIERS = Field.class.getDeclaredField("modifiers"); + FIELD_DOT_MODIFIERS.setAccessible(true); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + // -------------------------------------------- // + // MAKE ACCESSIBLE + // -------------------------------------------- // + + public static boolean makeAccessible(Field field) + { + try + { + // Mark the field as accessible using reflection. + field.setAccessible(true); + + // Remove the final modifier from the field. + // http://stackoverflow.com/questions/2474017/using-reflection-to-change-static-final-file-separatorchar-for-unit-testing + FIELD_DOT_MODIFIERS.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + return true; + } + catch (Exception e) + { + e.printStackTrace(); + return false; + } + } + + // -------------------------------------------- // + // FIELD SIMPLE: GET & SET & TRANSFER + // -------------------------------------------- // + public static Object getField(Class clazz, String fieldName, Object object) { try { Field field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); + makeAccessible(field); return field.get(object); } catch (Exception e) { + e.printStackTrace(); return null; } } @@ -25,12 +74,13 @@ public class ReflectionUtil try { Field field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); + makeAccessible(field); field.set(object, value); return true; } catch (Exception e) { + e.printStackTrace(); return false; } } @@ -40,13 +90,14 @@ public class ReflectionUtil try { Field field = clazz.getDeclaredField(fieldName); - field.setAccessible(true); + makeAccessible(field); Object value = field.get(from); field.set(to, value); return true; } catch (Exception e) { + e.printStackTrace(); return false; } } @@ -75,4 +126,6 @@ public class ReflectionUtil return transferFields(clazz, from, to, null); } + + }