Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

324
LINES

< > BotCompany Repo | #1005469 // structureConcept function

JavaX fragment (include)

1  
static String structureConcept(Object o) {
2  
  new HashSet refd;
3  
  new StringBuilder out;
4  
  structureConcept_1(out, o, new structureConcept_Data(refd));
5  
  return structureConcept_2(str(out), refd);
6  
}
7  
8  
// leave to false, unless unstructure() breaks
9  
static boolean structureConcept_allowShortening = false;
10  
11  
static int structureConcept_shareStringsLongerThan = 20;
12  
13  
static class structureConcept_Data {
14  
  int stringSizeLimit;
15  
  new IdentityHashMap<O, Integer> seen;
16  
  HashSet<Integer> refd;
17  
  new HashMap<S, Int> strings;
18  
  new HashSet<S> concepts;
19  
  Class conceptClass = findClass("Concept");
20  
  bool markConcepts;
21  
  new Map<S, Concept> unlisted; // unlisted empty instances to check default field values
22  
  
23  
  *(HashSet<Int> *refd) {}
24  
}
25  
26  
static void structureConcept_1(StringBuilder out, Object o, structureConcept_Data d) {
27  
  if (o == null) { out.append("null"); ret; }
28  
  
29  
  // these are never back-referenced (for readability)
30  
  
31  
  if (o instanceof BigInteger) {
32  
    out.append("bigint(").append(o).append(")"); ret;
33  
  }
34  
  
35  
  if (o instanceof Double) {
36  
    out.append("d(").append(quote(str(o))).append(")"); ret;
37  
  }
38  
    
39  
  if (o instanceof Float) {
40  
    out.append("fl ").append(quote(str(o))); ret;
41  
  }
42  
    
43  
  if (o instanceof Long) {
44  
    out.append(o).append("L"); ret;
45  
  }
46  
  
47  
  if (o instanceof Integer) {
48  
    out.append(str(o)); ret;
49  
  }
50  
    
51  
  if (o instanceof Boolean) {
52  
    out.append(((Boolean) o).booleanValue() ? "t" : "f"); ret;
53  
  }
54  
    
55  
  if (o instanceof Character) {
56  
    out.append(quoteCharacter((Character) o)); ret;
57  
  }
58  
    
59  
  if (o instanceof File) {
60  
    out.append("File ").append(quote(((File) o).getPath())); ret;
61  
  }
62  
    
63  
  // referencable objects follow
64  
  
65  
  Integer ref = d.seen.get(o);
66  
  if (ref != null) {
67  
    d.refd.add(ref);
68  
    out.append("r").append(ref); ret;
69  
  }
70  
      
71  
  if (o instanceof S && (ref = d.strings.get((S) o)) != null) {
72  
    d.refd.add(ref);
73  
    out.append("r").append(ref); ret;
74  
  }
75  
  
76  
  ref = d.seen.size()+1;
77  
  d.seen.put(o, ref);
78  
  out.append("m").append(ref).append(" "); // marker
79  
80  
  if (o instanceof S) {
81  
    S s = d.stringSizeLimit != 0 ? shorten((S) o, d.stringSizeLimit) : (S) o;
82  
    if (l(s) >= structureConcept_shareStringsLongerThan)
83  
      d.strings.put(s, ref);
84  
    out.append(quote(s)); ret;
85  
  }
86  
    
87  
  String name = o.getClass().getName();
88  
89  
  if (o instanceof HashSet) {
90  
    out.append("hashset ");
91  
    structureConcept_1(out, new ArrayList((Set) o), d);
92  
    ret;
93  
  }
94  
95  
  if (o instanceof TreeSet) {
96  
    out.append("treeset ");
97  
    structureConcept_1(out, new ArrayList((Set) o), d);
98  
    ret;
99  
  }
100  
  
101  
  if (o instanceof Collection && neq(name, "main$Concept$RefL")) {
102  
    if (!o instanceof ArrayList)
103  
      out.append(shortDynamicClassName(o));
104  
    out.append("[");
105  
    int l = out.length();
106  
    for (Object x : (Collection) o) {
107  
      if (out.length() != l) out.append(", ");
108  
      structureConcept_1(out, deref(x), d);
109  
    }
110  
    out.append("]");
111  
    ret;
112  
  }
113  
  
114  
  if (o instanceof Map) {
115  
    if (o instanceof HashMap) out.append("hm");
116  
    out.append("{");
117  
    int l = out.length();
118  
    for (Object e : ((Map) o).entrySet()) {
119  
      if (out.length() != l) out.append(", ");
120  
      structureConcept_1(out, ((Map.Entry) e).getKey(), d);
121  
      out.append("=");
122  
      structureConcept_1(out, ((Map.Entry) e).getValue(), d);
123  
    }
124  
    out.append("}");
125  
    ret;
126  
  }
127  
  
128  
  if (o.getClass().isArray()) {
129  
    if (o instanceof byte[]) {
130  
      out.append("ba ").append(quote(bytesToHex((byte[]) o))); ret;
131  
    }
132  
133  
    int n = Array.getLength(o);
134  
135  
    if (o instanceof bool[]) {
136  
      S hex = boolArrayToHex((bool[]) o);
137  
      int i = l(hex);
138  
      while (i > 0 && hex.charAt(i-1) == '0' && hex.charAt(i-2) == '0') i -= 2;
139  
      out.append("boolarray ").append(n).append(" ").append(quote(substring(hex, 0, i))); ret;
140  
    }
141  
    
142  
    S atype = "array", sep = ", ";
143  
144  
    if (o instanceof int[]) {
145  
      //ret "intarray " + quote(intArrayToHex((int[]) o));
146  
      atype = "intarray";
147  
      sep = " ";
148  
    }
149  
    
150  
    out.append(atype).append("{");
151  
    for (int i = 0; i < n; i++) {
152  
      if (i != 0) out.append(sep);
153  
      structureConcept_1(out, Array.get(o, i), d);
154  
    }
155  
    out.append("}"); ret;
156  
  }
157  
158  
  if (o instanceof Class) {
159  
    out.append("class(").append(quote(((Class) o).getName())).append(")"); ret;
160  
  }
161  
    
162  
  if (o instanceof Throwable) {
163  
    out.append("exception(").append(quote(((Throwable) o).getMessage())).append(")"); ret;
164  
  }
165  
    
166  
  if (o instanceof BitSet) {
167  
    BitSet bs = (BitSet) o;
168  
    out.append("bitset{");
169  
    int l = out.length();
170  
    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
171  
      if (out.length() != l) out.append(", ");
172  
      out.append(i);
173  
    }
174  
    out.append("}"); ret;
175  
  }
176  
    
177  
  // Need more cases? This should cover all library classes...
178  
  if (name.startsWith("java.") || name.startsWith("javax.")) {
179  
    out.append(str(o)); ret;
180  
  }
181  
    
182  
  String shortName = o.getClass().getName().replaceAll("^main\\$", "");
183  
  
184  
  if (shortName.equals("Lisp")) {
185  
    out.append("l(");
186  
    structureConcept_1(out, getOpt(o, "head"), d);
187  
    L args = cast getOpt(o, "args");
188  
    if (nempty(args))
189  
      for (int i = 0; i < l(args); i++) {
190  
        out.append(", ");
191  
        O arg = args.get(i);
192  
        
193  
        // sweet shortening
194  
        if (arg != null && eq(arg.getClass().getName(), "main$Lisp") && isTrue(call(arg, "isEmpty")))
195  
          arg = get(arg, "head");
196  
          
197  
        structureConcept_1(out, arg, d);
198  
      }
199  
    out.append(")"); ret;
200  
  }
201  
  
202  
  Class c = o.getClass();
203  
  bool concept = d.conceptClass != null && d.conceptClass.isInstance(o);
204  
  S dynName = shortDynamicClassName(o);
205  
  if (concept && !d.concepts.contains(dynName)) {
206  
    d.concepts.add(dynName);
207  
    if (d.markConcepts)
208  
      out.append("c ");
209  
  }
210  
  
211  
  // serialize an object with fields.
212  
  // first, collect all fields and values in fv.
213  
  
214  
  Map<S, O> fv = new TreeMap;
215  
  while (c != Object.class) {
216  
    for (Field field : c.getDeclaredFields()) {
217  
      if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0)
218  
        continue;
219  
      S fieldName = field.getName();
220  
      
221  
      Object value;
222  
      try {
223  
        field.setAccessible(true);
224  
        value = field.get(o);
225  
      } catch (Exception e) {
226  
        value = "?";
227  
      }
228  
      
229  
      // omit field "className" if equal to class's name
230  
      if (concept && eq(fieldName, "className")
231  
        && eq(value, shortName)) value = null;
232  
      
233  
      // put special cases here...
234  
      
235  
      if (value != null)
236  
        fv.put(fieldName, value);
237  
    }
238  
    c = c.getSuperclass();
239  
  }
240  
  
241  
  // Now we have fields & values. Process fieldValues if it's a DynamicObject.
242  
  
243  
  if (o instanceof DynamicObject) {
244  
    fv.putAll((Map) fv.get("fieldValues"));
245  
    fv.remove("fieldValues");
246  
    shortName = dynName;
247  
    fv.remove("className");
248  
  }
249  
  
250  
  S singleField = null;
251  
  
252  
  if (o instanceof ConceptL) {
253  
    out.append(shortName).append("[");
254  
    int l = out.length();
255  
    for (Object x : o/ConceptL.l) {
256  
      if (out.length() != l) out.append(", ");
257  
      structureConcept_1(out, deref(x), d);
258  
    }
259  
    out.append("]");
260  
    ret;
261  
  }
262  
  
263  
  if (o instanceof Str && empty(o/Str.otherNames)) {
264  
    out/*.append("Str ")*/.append(quote(o/Str.name));
265  
    ret;
266  
  }
267  
  
268  
  if (o instanceof Concept) {
269  
    Concept cpt = cast o;
270  
    Set<S> fields = conceptFields(cpt);
271  
    if (l(fields) == 1) singleField = first(fields);
272  
    Concept unl = d.unlisted.get(dynName);
273  
    if (unl == null)
274  
      d.unlisted.put(dynName, unl = unlisted(cpt.getClass()));
275  
    fv.clear();
276  
    for (S field : fields) {
277  
      O val = cget(cpt, field);
278  
      if (val != null && neq(cget(unl, field), val))
279  
        fv.put(field, val);
280  
    }
281  
  }
282  
  
283  
  S fieldOrder = toStringOpt(getOpt(o, "_fieldOrder"));
284  
  
285  
  // Render this$1 first because unstructure needs it for constructor call.
286  
  
287  
  out.append(shortName).append("(");
288  
  int l = out.length();
289  
  
290  
  if (fv.containsKey("this$1")) {
291  
    out.append("this$1=");
292  
    structureConcept_1(out, fv.get("this$1"), d);
293  
    fv.remove("this$1");
294  
  }
295  
  
296  
  // Render the other fields.
297  
298  
  if (fieldOrder != null)
299  
    fv = putKeysFirst(fv, toObjectArray(splitAtSpace(fieldOrder)));
300  
    
301  
  for (S fieldName : keys(fv)) {
302  
    if (out.length() != l) out.append(", ");
303  
    if (neq(fieldName, singleField))
304  
      out.append(fieldName).append("=");
305  
    structureConcept_1(out, fv.get(fieldName), d);
306  
  }
307  
308  
  if (out.length() == l) out.setLength(l-1); // drop "("
309  
  else out.append(")");
310  
}
311  
312  
// drop unused markers
313  
static S structureConcept_2(S s, HashSet<Integer> refd) {
314  
  L<S> tok = javaTok(s);
315  
  new StringBuilder out;
316  
  for (int i = 1; i < l(tok); i += 2) {
317  
    S t = tok.get(i);
318  
    if (t.startsWith("m") && isInteger(t.substring(1))
319  
      && !refd.contains(parseInt(t.substring(1))))
320  
      continue;
321  
    out.append(t).append(tok.get(i+1));
322  
  }
323  
  ret str(out);
324  
}

Author comment

Began life as a copy of #1005374

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ddnzoavkxhuk, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1005469
Snippet name: structureConcept function
Eternal ID of this version: #1005469/1
Text MD5: 69b6012b473221431a2bbb53c88ee2b0
Author: stefan
Category: javax / concepts
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-11-21 16:32:09
Source code size: 9113 bytes / 324 lines
Pitched / IR pitched: No / No
Views / Downloads: 573 / 549
Referenced in: [show references]