1 //020 8330 0577 bob
2 package com.thoughtworks.xstream.objecttree.reflection;
3
4 import com.thoughtworks.xstream.objecttree.ObjectAccessException;
5 import com.thoughtworks.xstream.objecttree.ObjectTree;
6
7 import java.lang.reflect.Field;
8 import java.lang.reflect.Modifier;
9 import java.util.LinkedList;
10 import java.util.List;
11
12 public class ReflectionObjectGraph implements ObjectTree {
13
14 private LinkedList fieldStack = new LinkedList();
15 private LinkedList instanceStack = new LinkedList();
16 private Class rootType;
17 private ObjectFactory objectFactory;
18
19 public ReflectionObjectGraph(Object root, ObjectFactory objectFactory) {
20 this.objectFactory = objectFactory;
21 init(root);
22 }
23
24 public ReflectionObjectGraph(Class rootType, ObjectFactory objectFactory) {
25 this.rootType = rootType;
26 this.objectFactory = objectFactory;
27 init(null);
28 }
29
30 private static class RootHolder {
31 Object value;
32 }
33
34 private void init(Object root) {
35 RootHolder holder = new RootHolder();
36 holder.value = root;
37 instanceStack.addLast(holder);
38 push("value");
39 }
40
41 public void push(String fieldName) {
42 Object top = instanceStack.getLast();
43
44 Field field = null;
45 Class currentClass = top.getClass();
46 try {
47
48 while (field == null) {
49 try {
50 field = currentClass.getDeclaredField(fieldName);
51 } catch (NoSuchFieldException e) {
52 if (Object.class.equals(currentClass)) {
53 throw new ObjectAccessException("Cannot access field " + fieldName, e);
54 }
55 currentClass = currentClass.getSuperclass();
56 }
57 }
58
59 } catch (SecurityException e) {
60 throw new ObjectAccessException("Cannot access field " + fieldName, e);
61 }
62 field.setAccessible(true);
63 fieldStack.addLast(field);
64
65 try {
66 instanceStack.addLast(field.get(top));
67 } catch (IllegalArgumentException e) {
68 throw new ObjectAccessException("Cannot access field " + fieldName, e);
69 } catch (IllegalAccessException e) {
70 throw new ObjectAccessException("Cannot access field " + fieldName, e);
71 }
72
73 }
74
75 public void pop() {
76 fieldStack.removeLast();
77 instanceStack.removeLast();
78 }
79
80 public Class type() {
81 if (fieldStack.size() == 1) {
82 return rootType;
83 } else {
84 Field field = (Field) fieldStack.getLast();
85 Class type = field.getType();
86 return type;
87 }
88 }
89
90 public Object get() {
91 return instanceStack.getLast();
92 }
93
94 public void set(Object value) {
95 try {
96 instanceStack.removeLast();
97 Field field = (Field) fieldStack.getLast();
98 Object top = instanceStack.getLast();
99 field.set(top, value);
100 instanceStack.addLast(value);
101 } catch (IllegalAccessException e) {
102 throw new ObjectAccessException("Cannot set field", e);
103 }
104 }
105
106 public void create(Class type) {
107 set(objectFactory.create(type));
108 }
109
110 public String[] fieldNames() {
111 List fieldNames = new LinkedList();
112 Class theClass = get().getClass();
113 Class currentClass = theClass;
114
115 while (!Object.class.equals(currentClass)) {
116 getFields(fieldNames, currentClass);
117 currentClass = currentClass.getSuperclass();
118 }
119
120 String[] result = new String[fieldNames.size()];
121 fieldNames.toArray(result);
122 return result;
123 }
124
125 private void getFields(List fieldNames, Class theClass) {
126 Field[] fields = theClass.getDeclaredFields();
127 for (int i = 0; i < fields.length; i++) {
128 Field field = fields[i];
129 int modifiers = field.getModifiers();
130 if (field.getName().startsWith("this$")) {
131 continue;
132 }
133 if (Modifier.isFinal(modifiers) ||
134 Modifier.isStatic(modifiers) ||
135 Modifier.isTransient(modifiers)) {
136 continue;
137 }
138 fieldNames.add(field.getName());
139 }
140 }
141
142 public ObjectTree newStack(Class type) {
143 return new ReflectionObjectGraph(type, objectFactory);
144 }
145
146 public ObjectTree newStack(Object instance) {
147 return new ReflectionObjectGraph(instance, objectFactory);
148 }
149
150 }
This page was automatically generated by Maven