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 public Class<?>[] getJSONClasses() {
068 return _JSON_CLASSES;
069 }
070
071 public Class<?>[] getSerializableClasses() {
072 return _SERIALIZABLE_CLASSES;
073 }
074
075 public Object marshall(
076 SerializerState serializerState, Object parentObject, Object object)
077 throws MarshallException {
078
079 JSONObject jsonObject = new JSONObject();
080
081 Class<?> javaClass = object.getClass();
082
083 if (ser.getMarshallClassHints()) {
084 try {
085 jsonObject.put("javaClass", javaClass.getName());
086 }
087 catch (Exception e) {
088 throw new MarshallException("Unable to put javaClass", e);
089 }
090 }
091
092 JSONObject serializableJSONObject = new JSONObject();
093
094 try {
095 jsonObject.put("serializable", serializableJSONObject);
096
097 serializerState.push(
098 object, serializableJSONObject, "serializable");
099 }
100 catch (Exception e) {
101 throw new MarshallException("Unable to put serializable", e);
102 }
103
104 String fieldName = null;
105
106 try {
107 Set<String> processedFieldNames = new HashSet<String>();
108
109 while (javaClass != null) {
110 Field[] declaredFields = javaClass.getDeclaredFields();
111
112 for (Field field : declaredFields) {
113 fieldName = field.getName();
114
115
116
117 if (processedFieldNames.contains(fieldName)) {
118 continue;
119 }
120
121 processedFieldNames.add(fieldName);
122
123 int modifiers = field.getModifiers();
124
125
126
127
128 if (((modifiers & Modifier.FINAL) == Modifier.FINAL) ||
129 ((modifiers & Modifier.STATIC) == Modifier.STATIC) ||
130 ((modifiers & Modifier.TRANSIENT) ==
131 Modifier.TRANSIENT)) {
132
133 continue;
134 }
135
136 if (!field.isAccessible()) {
137 field.setAccessible(true);
138 }
139
140 if (fieldName.startsWith("_")) {
141 fieldName = fieldName.substring(1);
142 }
143
144 Object fieldObject = ser.marshall(
145 serializerState, serializableJSONObject,
146 field.get(object), fieldName);
147
148
149
150
151 if (JSONSerializer.CIRC_REF_OR_DUPLICATE != fieldObject) {
152 serializableJSONObject.put(fieldName, fieldObject);
153 }
154 }
155
156 javaClass = javaClass.getSuperclass();
157 }
158 }
159 catch (Exception e) {
160 throw new MarshallException(
161 "Unable to match field " + fieldName, e);
162 }
163 finally {
164 serializerState.pop();
165 }
166
167 return jsonObject;
168 }
169
170 public ObjectMatch tryUnmarshall(
171 SerializerState serializerState,
172 @SuppressWarnings("rawtypes") Class clazz, Object object)
173 throws UnmarshallException {
174
175 JSONObject jsonObject = (JSONObject)object;
176
177 String javaClassName = null;
178
179 try {
180 javaClassName = jsonObject.getString("javaClass");
181 }
182 catch (Exception e) {
183 throw new UnmarshallException("Unable to get javaClass", e);
184 }
185
186 if (javaClassName == null) {
187 throw new UnmarshallException("javaClass is undefined");
188 }
189
190 try {
191 Class<?> javaClass = Class.forName(javaClassName);
192
193 Serializable.class.isAssignableFrom(javaClass);
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 public Object unmarshall(
244 SerializerState serializerState,
245 @SuppressWarnings("rawtypes") Class clazz, Object object)
246 throws UnmarshallException {
247
248 JSONObject jsonObject = (JSONObject)object;
249
250 String javaClassName = null;
251
252 try {
253 javaClassName = jsonObject.getString("javaClass");
254 }
255 catch (Exception e) {
256 throw new UnmarshallException("Unable to get javaClass", e);
257 }
258
259 if (javaClassName == null) {
260 throw new UnmarshallException("javaClass is undefined");
261 }
262
263 Class<?> javaClass = null;
264
265 Object javaClassInstance = null;
266
267 try {
268 javaClass = Class.forName(javaClassName);
269
270 javaClassInstance = javaClass.newInstance();
271 }
272 catch (Exception e) {
273 throw new UnmarshallException(
274 "Unable to load javaClass " + javaClassName, e);
275 }
276
277 JSONObject serializableJSONObject = null;
278
279 try {
280 serializableJSONObject = jsonObject.getJSONObject("serializable");
281 }
282 catch (Exception e) {
283 throw new UnmarshallException("Unable to get serializable", e);
284 }
285
286 if (serializableJSONObject == null) {
287 throw new UnmarshallException("serializable is undefined");
288 }
289
290 serializerState.setSerialized(object, javaClassInstance);
291
292 String fieldName = null;
293
294 try {
295 Set<String> processedFieldNames = new HashSet<String>();
296
297 while (javaClass != null) {
298 Field[] fields = javaClass.getDeclaredFields();
299
300 for (Field field : fields) {
301 fieldName = field.getName();
302
303
304
305 if (processedFieldNames.contains(fieldName)) {
306 continue;
307 }
308
309 processedFieldNames.add(fieldName);
310
311 int modifiers = field.getModifiers();
312
313
314
315
316 if (((modifiers & Modifier.FINAL) == Modifier.FINAL) ||
317 ((modifiers & Modifier.STATIC) == Modifier.STATIC) ||
318 ((modifiers & Modifier.TRANSIENT) ==
319 Modifier.TRANSIENT)) {
320
321 continue;
322 }
323
324 if (!field.isAccessible()) {
325 field.setAccessible(true);
326 }
327
328 if (fieldName.startsWith("_")) {
329 fieldName = fieldName.substring(1);
330 }
331
332 Object value = null;
333
334 try {
335 value = ser.unmarshall(
336 serializerState, field.getType(),
337 serializableJSONObject.get(fieldName));
338 }
339 catch (Exception e) {
340 }
341
342 if (value != null) {
343 try {
344 field.set(javaClassInstance, value);
345 }
346 catch (Exception e) {
347 _log.error(e, e);
348 }
349 }
350 }
351
352 javaClass = javaClass.getSuperclass();
353 }
354 }
355 catch (Exception e) {
356 throw new UnmarshallException(
357 "Unable to match field " + fieldName, e);
358 }
359
360 return javaClassInstance;
361 }
362
363 private static final Class<?>[] _JSON_CLASSES = {JSONObject.class};
364
365 private static final Class<?>[] _SERIALIZABLE_CLASSES =
366 {Serializable.class};
367
368 private static Log _log = LogFactoryUtil.getLog(LiferaySerializer.class);
369
370 }