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