001
014
015 package com.liferay.portal.json.jabsorb.serializer;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019
020 import java.io.Serializable;
021
022 import java.lang.reflect.Constructor;
023 import java.lang.reflect.Field;
024 import java.lang.reflect.Modifier;
025
026 import java.util.HashSet;
027 import java.util.Iterator;
028 import java.util.Set;
029
030 import org.jabsorb.JSONSerializer;
031 import org.jabsorb.serializer.AbstractSerializer;
032 import org.jabsorb.serializer.MarshallException;
033 import org.jabsorb.serializer.ObjectMatch;
034 import org.jabsorb.serializer.SerializerState;
035 import org.jabsorb.serializer.UnmarshallException;
036
037 import org.json.JSONObject;
038
039
042 public class LiferaySerializer extends AbstractSerializer {
043
044 @Override
045 public boolean canSerialize(
046 @SuppressWarnings("rawtypes") Class clazz,
047 @SuppressWarnings("rawtypes") Class jsonClass) {
048
049 Constructor<?> constructor = null;
050
051 try {
052 constructor = clazz.getConstructor();
053 }
054 catch (Exception e) {
055 }
056
057 if (Serializable.class.isAssignableFrom(clazz) &&
058 ((jsonClass == null) || (jsonClass == JSONObject.class)) &&
059 (constructor != null)) {
060
061 return true;
062 }
063
064 return false;
065 }
066
067 @Override
068 public Class<?>[] getJSONClasses() {
069 return _JSON_CLASSES;
070 }
071
072 @Override
073 public Class<?>[] getSerializableClasses() {
074 return _SERIALIZABLE_CLASSES;
075 }
076
077 @Override
078 public Object marshall(
079 SerializerState serializerState, Object parentObject, Object object)
080 throws MarshallException {
081
082 JSONObject jsonObject = new JSONObject();
083
084 Class<?> javaClass = object.getClass();
085
086 if (ser.getMarshallClassHints()) {
087 try {
088 jsonObject.put("javaClass", javaClass.getName());
089 }
090 catch (Exception e) {
091 throw new MarshallException("Unable to put javaClass", e);
092 }
093 }
094
095 JSONObject serializableJSONObject = new JSONObject();
096
097 try {
098 jsonObject.put("serializable", serializableJSONObject);
099
100 serializerState.push(
101 object, serializableJSONObject, "serializable");
102 }
103 catch (Exception e) {
104 throw new MarshallException("Unable to put serializable", e);
105 }
106
107 String fieldName = null;
108
109 try {
110 Set<String> processedFieldNames = new HashSet<String>();
111
112 while (javaClass != null) {
113 Field[] declaredFields = javaClass.getDeclaredFields();
114
115 for (Field field : declaredFields) {
116 fieldName = field.getName();
117
118
119
120 if (processedFieldNames.contains(fieldName)) {
121 continue;
122 }
123
124 processedFieldNames.add(fieldName);
125
126 int modifiers = field.getModifiers();
127
128
129
130 if (((modifiers & Modifier.STATIC) == Modifier.STATIC) ||
131 ((modifiers & Modifier.TRANSIENT) ==
132 Modifier.TRANSIENT)) {
133
134 continue;
135 }
136
137 if (!field.isAccessible()) {
138 field.setAccessible(true);
139 }
140
141 if (fieldName.startsWith("_")) {
142 fieldName = fieldName.substring(1);
143 }
144
145 Object fieldObject = ser.marshall(
146 serializerState, serializableJSONObject,
147 field.get(object), fieldName);
148
149
150
151
152 if (JSONSerializer.CIRC_REF_OR_DUPLICATE != fieldObject) {
153 serializableJSONObject.put(fieldName, fieldObject);
154 }
155 }
156
157 javaClass = javaClass.getSuperclass();
158 }
159 }
160 catch (Exception e) {
161 throw new MarshallException(
162 "Unable to match field " + fieldName, e);
163 }
164 finally {
165 serializerState.pop();
166 }
167
168 return jsonObject;
169 }
170
171 @Override
172 public ObjectMatch tryUnmarshall(
173 SerializerState serializerState,
174 @SuppressWarnings("rawtypes") Class clazz, Object object)
175 throws UnmarshallException {
176
177 JSONObject jsonObject = (JSONObject)object;
178
179 String javaClassName = null;
180
181 try {
182 javaClassName = jsonObject.getString("javaClass");
183 }
184 catch (Exception e) {
185 throw new UnmarshallException("Unable to get javaClass", e);
186 }
187
188 if (javaClassName == null) {
189 throw new UnmarshallException("javaClass is undefined");
190 }
191
192 try {
193 Class.forName(javaClassName);
194 }
195 catch (Exception e) {
196 throw new UnmarshallException(
197 "Unable to load javaClass " + javaClassName, e);
198 }
199
200 JSONObject serializableJSONObject = null;
201
202 try {
203 serializableJSONObject = jsonObject.getJSONObject("serializable");
204 }
205 catch (Exception e) {
206 throw new UnmarshallException("Unable to get serializable", e);
207 }
208
209 if (serializableJSONObject == null) {
210 throw new UnmarshallException("serializable is undefined");
211 }
212
213 ObjectMatch objectMatch = new ObjectMatch(-1);
214
215 serializerState.setSerialized(object, objectMatch);
216
217 String fieldName = null;
218
219 try {
220 Iterator<?> iterator = serializableJSONObject.keys();
221
222 while (iterator.hasNext()) {
223 fieldName = (String)iterator.next();
224
225 ObjectMatch fieldObjectMatch = ser.tryUnmarshall(
226 serializerState, null,
227 serializableJSONObject.get(fieldName));
228
229 ObjectMatch maxFieldObjectMatch = fieldObjectMatch.max(
230 objectMatch);
231
232 objectMatch.setMismatch(maxFieldObjectMatch.getMismatch());
233 }
234 }
235 catch (Exception e) {
236 throw new UnmarshallException(
237 "Unable to match field " + fieldName, e);
238 }
239
240 return objectMatch;
241 }
242
243 @Override
244 public Object unmarshall(
245 SerializerState serializerState,
246 @SuppressWarnings("rawtypes") Class clazz, Object object)
247 throws UnmarshallException {
248
249 JSONObject jsonObject = (JSONObject)object;
250
251 String javaClassName = null;
252
253 try {
254 javaClassName = jsonObject.getString("javaClass");
255 }
256 catch (Exception e) {
257 throw new UnmarshallException("Unable to get javaClass", e);
258 }
259
260 if (javaClassName == null) {
261 throw new UnmarshallException("javaClass is undefined");
262 }
263
264 Class<?> javaClass = null;
265
266 Object javaClassInstance = null;
267
268 try {
269 javaClass = Class.forName(javaClassName);
270
271 javaClassInstance = javaClass.newInstance();
272 }
273 catch (Exception e) {
274 throw new UnmarshallException(
275 "Unable to load javaClass " + javaClassName, e);
276 }
277
278 JSONObject serializableJSONObject = null;
279
280 try {
281 serializableJSONObject = jsonObject.getJSONObject("serializable");
282 }
283 catch (Exception e) {
284 throw new UnmarshallException("Unable to get serializable", e);
285 }
286
287 if (serializableJSONObject == null) {
288 throw new UnmarshallException("serializable is undefined");
289 }
290
291 serializerState.setSerialized(object, javaClassInstance);
292
293 String fieldName = null;
294
295 try {
296 Set<String> processedFieldNames = new HashSet<String>();
297
298 while (javaClass != null) {
299 Field[] fields = javaClass.getDeclaredFields();
300
301 for (Field field : fields) {
302 fieldName = field.getName();
303
304
305
306 if (processedFieldNames.contains(fieldName)) {
307 continue;
308 }
309
310 processedFieldNames.add(fieldName);
311
312 int modifiers = field.getModifiers();
313
314
315
316 if (((modifiers & Modifier.STATIC) == Modifier.STATIC) ||
317 ((modifiers & Modifier.TRANSIENT) ==
318 Modifier.TRANSIENT)) {
319
320 continue;
321 }
322
323 if (!field.isAccessible()) {
324 field.setAccessible(true);
325 }
326
327 if (fieldName.startsWith("_")) {
328 fieldName = fieldName.substring(1);
329 }
330
331 Object value = null;
332
333 try {
334 value = ser.unmarshall(
335 serializerState, field.getType(),
336 serializableJSONObject.get(fieldName));
337 }
338 catch (Exception e) {
339 }
340
341 if (value != null) {
342 try {
343 field.set(javaClassInstance, value);
344 }
345 catch (Exception e) {
346 _log.error(e, e);
347 }
348 }
349 }
350
351 javaClass = javaClass.getSuperclass();
352 }
353 }
354 catch (Exception e) {
355 throw new UnmarshallException(
356 "Unable to match field " + fieldName, e);
357 }
358
359 return javaClassInstance;
360 }
361
362 private static final Class<?>[] _JSON_CLASSES = {JSONObject.class};
363
364 private static final Class<?>[] _SERIALIZABLE_CLASSES =
365 {Serializable.class};
366
367 private static final Log _log = LogFactoryUtil.getLog(
368 LiferaySerializer.class);
369
370 }