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 com.thoughtworks.xstream.XStream;
19 import com.thoughtworks.xstream.converters.MarshallingContext;
20 import com.thoughtworks.xstream.converters.SingleValueConverter;
21 import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
22 import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
23 import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
24 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
25 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
26 import com.thoughtworks.xstream.mapper.Mapper;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.ojb.broker.core.proxy.ListProxyDefaultImpl;
30 import org.joda.time.DateTime;
31 import org.joda.time.format.ISODateTimeFormat;
32 import org.kuali.rice.krad.service.KRADServiceLocator;
33 import org.kuali.rice.krad.service.PersistenceService;
34 import org.kuali.rice.krad.service.XmlObjectSerializerService;
35 import org.kuali.rice.krad.util.DateTimeConverter;
36
37 import java.lang.reflect.Field;
38 import java.util.ArrayList;
39 import java.util.Iterator;
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 private PersistenceService persistenceService;
52
53 private 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 xstream.addDefaultImplementation(ArrayList.class, ListProxyDefaultImpl.class);
75 xstream.registerConverter(new DateTimeConverter());
76 }
77
78
79
80
81 public String toXml(Object object) {
82 if ( LOG.isDebugEnabled() ) {
83 LOG.debug( "toXml(" + object + ") : \n" + xstream.toXML(object) );
84 }
85 return xstream.toXML(object);
86 }
87
88
89
90
91 public Object fromXml(String xml) {
92 if ( LOG.isDebugEnabled() ) {
93 LOG.debug( "fromXml() : \n" + xml );
94 }
95 if ( xml != null ) {
96 xml = xml.replaceAll( "--EnhancerByCGLIB--[0-9a-f]{0,8}", "" );
97 }
98 return xstream.fromXML(xml);
99 }
100
101
102
103
104
105 public class ProxyConverter extends ReflectionConverter {
106 public ProxyConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
107 super(mapper, reflectionProvider);
108 }
109
110 @Override
111
112
113 @SuppressWarnings("unchecked")
114 public boolean canConvert(Class clazz) {
115 return clazz.getName().contains("CGLIB");
116 }
117
118 @Override
119 public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {
120 super.marshal(getPersistenceService().resolveProxy(obj), writer, context);
121 }
122
123
124 }
125
126 public class ProxyAwareJavaReflectionProvider extends PureJavaReflectionProvider {
127
128 public ProxyAwareJavaReflectionProvider() {
129 super();
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 Object value = null;
143 try {
144 value = field.get(object);
145 if (value != null && getPersistenceService().isProxied(value)) {
146 value = getPersistenceService().resolveProxy(value);
147 }
148 } catch (IllegalArgumentException e) {
149 throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
150 } catch (IllegalAccessException e) {
151 throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e);
152 }
153 visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value);
154 }
155 }
156
157 }
158
159 public PersistenceService getPersistenceService() {
160 if ( persistenceService == null ) {
161 persistenceService = KRADServiceLocator.getPersistenceService();
162 }
163 return persistenceService;
164 }
165
166 }