1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service.impl;
17
18 import java.lang.reflect.Field;
19 import java.util.ArrayList;
20 import java.util.Iterator;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.kuali.rice.krad.service.LegacyDataAdapter;
25 import org.kuali.rice.krad.service.XmlObjectSerializerService;
26 import org.kuali.rice.krad.service.util.DateTimeConverter;
27 import org.springframework.beans.factory.annotation.Required;
28
29 import com.thoughtworks.xstream.XStream;
30 import com.thoughtworks.xstream.converters.MarshallingContext;
31 import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
32 import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
33 import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
34 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
35 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
36 import com.thoughtworks.xstream.mapper.Mapper;
37
38
39
40
41
42
43
44
45 public class XmlObjectSerializerServiceImpl implements XmlObjectSerializerService {
46 private static final Log LOG = LogFactory.getLog(XmlObjectSerializerServiceImpl.class);
47
48 protected LegacyDataAdapter lda;
49
50 protected XStream xstream;
51
52 public XmlObjectSerializerServiceImpl() {
53 xstream = new XStream(new ProxyAwareJavaReflectionProvider());
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 xstream.registerConverter(new ProxyConverter(xstream.getMapper(), xstream.getReflectionProvider() ));
71 try {
72 Class<?> objListProxyClass = Class.forName("org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl");
73 xstream.addDefaultImplementation(ArrayList.class, objListProxyClass);
74 } catch ( Exception ex ) {
75
76 }
77 xstream.registerConverter(new DateTimeConverter());
78 }
79
80 @Required
81 public void setLegacyDataAdapter(LegacyDataAdapter lda) {
82 this.lda = lda;
83 }
84
85 @Override
86 public String toXml(Object object) {
87 if ( LOG.isDebugEnabled() ) {
88 LOG.debug( "toXml(" + object + ") : \n" + xstream.toXML(object) );
89 }
90 return xstream.toXML(object);
91 }
92
93 @Override
94 public Object fromXml(String xml) {
95 if ( LOG.isDebugEnabled() ) {
96 LOG.debug( "fromXml() : \n" + xml );
97 }
98 if ( xml != null ) {
99 xml = xml.replaceAll( "--EnhancerByCGLIB--[0-9a-f]{0,8}", "" );
100 }
101 return xstream.fromXML(xml);
102 }
103
104
105
106
107
108 public class ProxyConverter extends ReflectionConverter {
109 public ProxyConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
110 super(mapper, reflectionProvider);
111 }
112
113 @Override
114
115
116 @SuppressWarnings("unchecked")
117 public boolean canConvert(Class clazz) {
118 return clazz.getName().contains("CGLIB");
119 }
120
121 @Override
122 public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {
123 super.marshal(lda.resolveProxy(obj), writer, context);
124 }
125
126
127 }
128
129 public class ProxyAwareJavaReflectionProvider extends PureJavaReflectionProvider {
130
131
132
133
134 @Override
135 public void visitSerializableFields(Object object, Visitor visitor) {
136 for (Iterator iterator = fieldDictionary.serializableFieldsFor(object.getClass()); iterator.hasNext();) {
137 Field field = (Field) iterator.next();
138 if (!fieldModifiersSupported(field)) {
139 continue;
140 }
141 validateFieldAccess(field);
142 if (ignoreField(field)) {
143 continue;
144 }
145 Object value = null;
146 try {
147 value = field.get(object);
148 if (value != null && lda.isProxied(value)) {
149 value = lda.resolveProxy(value);
150 }
151 } catch (Exception e) {
152 throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName() + " on " + object, e);
153 }
154 visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
155 }
156 }
157
158 protected boolean ignoreField(Field field) {
159 return false;
160 }
161
162 }
163
164 }