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