1 package org.catacomb.serial;
2
3 import org.catacomb.be.DeReferencable;
4 import org.catacomb.interlish.structure.*;
5 import org.catacomb.report.E;
6 import org.catacomb.serial.om.OmAttribute;
7 import org.catacomb.serial.om.OmElement;
8
9
10 import java.lang.reflect.AccessibleObject;
11 import java.lang.reflect.Field;
12 import java.lang.reflect.Modifier;
13 import java.util.ArrayList;
14 import java.util.Map;
15
16
17
18 public class Reflector {
19
20
21
22 public static Element makeObjectElementByReflection(Object obj,
23 OmElementizer elementizer) {
24
25
26 SerializationContext ctxt = elementizer.getContext();
27
28
29 if (obj instanceof DeReferencable) {
30 ((DeReferencable)obj).deReference();
31 }
32
33
34
35 ArrayList<Attribute> attributes = new ArrayList<Attribute>();
36 ArrayList<Element> elements = new ArrayList<Element>();
37
38
39 String scnm = obj.getClass().getName();
40 int ild = scnm.lastIndexOf(".");
41 String spk = scnm.substring(0, ild);
42 String ss = scnm.substring(ild + 1, scnm.length());
43
44
45 String eltname = ss;
46
47 if (elementizer.getContext().shouldWritePackage(spk)) {
48 attributes.add(new OmAttribute("package", spk));
49 }
50
51
52
53 ArrayList<Field> af = new ArrayList<Field>();
54 Class<?> cls = obj.getClass();
55 do {
56 Field[] declFields = cls.getDeclaredFields();
57 for (Field fld : declFields) {
58 af.add(fld);
59 }
60 AccessibleObject.setAccessible(declFields, true);
61 cls = cls.getSuperclass();
62 } while (cls != null);
63
64
65 for (Field field : af) {
66 String name = field.getName();
67 int modif = field.getModifiers();
68
69 if (name.startsWith("p_") || name.startsWith("r_")) {
70
71
72 } else if (name.startsWith("s_")) {
73 Object val = getFieldValue(field, obj);
74 if (val == null) {
75
76 E.warning("found special field " + name + " but value is null");
77
78 } else {
79 int hcode = val.hashCode();
80 if (ctxt.acceptsReferents()) {
81
82 ctxt.addReferent("" + hcode, val);
83
84 OmElement elt = new OmElement();
85 elt.setName(name);
86 elt.addAttribute("archive-hash", "" + hcode);
87 elements.add(elt);
88
89 } else {
90 E.warning(" - (Reflector) special object " + "not saved " + name + " " + val);
91 }
92 }
93
94 } else if (Modifier.isFinal(modif) && Modifier.isStatic(modif)) {
95
96
97 } else {
98 Object val = getFieldValue(field, obj);
99
100
101
102 if (val == null) {
103
104
105 } else if (val instanceof Map) {
106 E.error("raw map in reflector as child of " + obj);
107 E.error(" - ignoring " + val);
108
109 } else if (val instanceof Stateless) {
110
111
112 } else if (val instanceof String) {
113 attributes.add(new OmAttribute(name, (String)val));
114
115 } else {
116 if (ctxt.recurseAll() || val instanceof int[][] || val instanceof double[][]) {
117
118 Element elt = elementizer.makeElement(val);
119 OmElement omelt = (OmElement)elt;
120 if (omelt != null) {
121 omelt.setName(name);
122 elements.add(omelt);
123 }
124
125 }
126 }
127 }
128 }
129 OmElement elt = new OmElement(attributes, elements);
130 elt.setName(eltname);
131 return elt;
132 }
133
134
135
136 public static Object getFieldValue(Field field, Object obj) {
137
138 Object val = null;
139 try {
140 val = field.get(obj);
141
142 } catch (Exception ex) {
143 E.error(" getting field " + field.getName() + " on " + obj.getClass().getName() + " " + ex);
144 val = "ERROR";
145 }
146
147
148 return SerialUtil.stringifyObject(val);
149 }
150
151
152
153 }