Move java source, and resources to new paths for gradle
[fw/altos] / altosdroid / app / src / main / java / org / altusmetrum / AltosDroid / Dumper.java
1 package org.altusmetrum.AltosDroid;
2
3         import java.lang.reflect.Array;
4         import java.lang.reflect.Field;
5         import java.util.HashMap;
6
7         public class Dumper {
8                 private static Dumper instance = new Dumper();
9
10                 protected static Dumper getInstance() {
11                         return instance;
12                 }
13
14                 class DumpContext {
15                         int maxDepth = 0;
16                         int maxArrayElements = 0;
17                         int callCount = 0;
18                         HashMap<String, String> ignoreList = new HashMap<String, String>();
19                         HashMap<Object, Integer> visited = new HashMap<Object, Integer>();
20                 }
21
22                 public static String dump(Object o) {
23                         return dump(o, 0, 0, null);
24                 }
25
26                 public static String dump(Object o, int maxDepth, int maxArrayElements, String[] ignoreList) {
27                         DumpContext ctx = Dumper.getInstance().new DumpContext();
28                         ctx.maxDepth = maxDepth;
29                         ctx.maxArrayElements = maxArrayElements;
30
31                         if (ignoreList != null) {
32                                 for (int i = 0; i < Array.getLength(ignoreList); i++) {
33                                         int colonIdx = ignoreList[i].indexOf(':');
34                                         if (colonIdx == -1)
35                                                 ignoreList[i] = ignoreList[i] + ":";
36                                         ctx.ignoreList.put(ignoreList[i], ignoreList[i]);
37                                 }
38                         }
39
40                         return dump(o, ctx);
41                 }
42
43                 protected static String dump(Object o, DumpContext ctx) {
44                         if (o == null) {
45                                 return "<null>";
46                         }
47
48                         ctx.callCount++;
49                         StringBuffer tabs = new StringBuffer();
50                         for (int k = 0; k < ctx.callCount; k++) {
51                                 tabs.append("\t");
52                         }
53                         StringBuffer buffer = new StringBuffer();
54                         @SuppressWarnings("rawtypes")
55                         Class oClass = o.getClass();
56
57                         String oSimpleName = getSimpleNameWithoutArrayQualifier(oClass);
58
59                         if (ctx.ignoreList.get(oSimpleName + ":") != null)
60                                 return "<Ignored>";
61
62                         if (oClass.isArray()) {
63                                 buffer.append("\n");
64                                 buffer.append(tabs.toString().substring(1));
65                                 buffer.append("[\n");
66                                 int rowCount = ctx.maxArrayElements == 0 ? Array.getLength(o) : Math.min(ctx.maxArrayElements, Array.getLength(o));
67                                 for (int i = 0; i < rowCount; i++) {
68                                         buffer.append(tabs.toString());
69                                         try {
70                                                 Object value = Array.get(o, i);
71                                                 buffer.append(dumpValue(value, ctx));
72                                         } catch (Exception e) {
73                                                 buffer.append(e.getMessage());
74                                         }
75                                         if (i < Array.getLength(o) - 1)
76                                                 buffer.append(",");
77                                         buffer.append("\n");
78                                 }
79                                 if (rowCount < Array.getLength(o)) {
80                                         buffer.append(tabs.toString());
81                                         buffer.append(Array.getLength(o) - rowCount + " more array elements...");
82                                         buffer.append("\n");
83                                 }
84                                 buffer.append(tabs.toString().substring(1));
85                                 buffer.append("]");
86                         } else {
87                                 buffer.append("\n");
88                                 buffer.append(tabs.toString().substring(1));
89                                 buffer.append("{\n");
90                                 buffer.append(tabs.toString());
91                                 buffer.append("hashCode: " + o.hashCode());
92                                 buffer.append("\n");
93                                 while (oClass != null && oClass != Object.class) {
94                                         Field[] fields = oClass.getDeclaredFields();
95
96                                         if (ctx.ignoreList.get(oClass.getSimpleName()) == null) {
97                                                 if (oClass != o.getClass()) {
98                                                         buffer.append(tabs.toString().substring(1));
99                                                         buffer.append("  Inherited from superclass " + oSimpleName + ":\n");
100                                                 }
101
102                                                 for (int i = 0; i < fields.length; i++) {
103
104                                                         String fSimpleName = getSimpleNameWithoutArrayQualifier(fields[i].getType());
105                                                         String fName = fields[i].getName();
106
107                                                         fields[i].setAccessible(true);
108                                                         buffer.append(tabs.toString());
109                                                         buffer.append(fName + "(" + fSimpleName + ")");
110                                                         buffer.append("=");
111
112                                                         if (ctx.ignoreList.get(":" + fName) == null &&
113                                                                 ctx.ignoreList.get(fSimpleName + ":" + fName) == null &&
114                                                                 ctx.ignoreList.get(fSimpleName + ":") == null) {
115
116                                                                 try {
117                                                                         Object value = fields[i].get(o);
118                                                                         buffer.append(dumpValue(value, ctx));
119                                                                 } catch (Exception e) {
120                                                                         buffer.append(e.getMessage());
121                                                                 }
122                                                                 buffer.append("\n");
123                                                         } else {
124                                                                 buffer.append("<Ignored>");
125                                                                 buffer.append("\n");
126                                                         }
127                                                 }
128                                                 oClass = oClass.getSuperclass();
129                                                 oSimpleName = oClass.getSimpleName();
130                                         } else {
131                                                 oClass = null;
132                                                 oSimpleName = "";
133                                         }
134                                 }
135                                 buffer.append(tabs.toString().substring(1));
136                                 buffer.append("}");
137                         }
138                         ctx.callCount--;
139                         return buffer.toString();
140                 }
141
142                 protected static String dumpValue(Object value, DumpContext ctx) {
143                         if (value == null) {
144                                 return "<null>";
145                         }
146                         if (value.getClass().isPrimitive() ||
147                                 value.getClass() == java.lang.Short.class ||
148                                 value.getClass() == java.lang.Long.class ||
149                                 value.getClass() == java.lang.String.class ||
150                                 value.getClass() == java.lang.Integer.class ||
151                                 value.getClass() == java.lang.Float.class ||
152                                 value.getClass() == java.lang.Byte.class ||
153                                 value.getClass() == java.lang.Character.class ||
154                                 value.getClass() == java.lang.Double.class ||
155                                 value.getClass() == java.lang.Boolean.class) {
156
157                                 return value.toString();
158
159                         } else {
160
161                                 Integer visitedIndex = ctx.visited.get(value);
162                                 if (visitedIndex == null) {
163                                         ctx.visited.put(value, ctx.callCount);
164                                         if (ctx.maxDepth == 0 || ctx.callCount < ctx.maxDepth) {
165                                                 return dump(value, ctx);
166                                         } else {
167                                                 return "<Reached max recursion depth>";
168                                         }
169                                 } else {
170                                         return "<Previously visited - see hashCode " + value.hashCode() + ">";
171                                 }
172                         }
173                 }
174
175
176                 private static String getSimpleNameWithoutArrayQualifier(@SuppressWarnings("rawtypes") Class clazz) {
177                         String simpleName = clazz.getSimpleName();
178                         int indexOfBracket = simpleName.indexOf('['); 
179                         if (indexOfBracket != -1)
180                                 return simpleName.substring(0, indexOfBracket);
181                         return simpleName;
182                 }
183 }