All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.backendless.persistence.BackendlessSerializer Maven / Gradle / Ivy

There is a newer version: 3.1.0
Show newest version
/*
 * ********************************************************************************************************************
 *  

* BACKENDLESS.COM CONFIDENTIAL *

* ******************************************************************************************************************** *

* Copyright 2012 BACKENDLESS.COM. All Rights Reserved. *

* NOTICE: All information contained herein is, and remains the property of Backendless.com and its suppliers, * if any. The intellectual and technical concepts contained herein are proprietary to Backendless.com and its * suppliers and may be covered by U.S. and Foreign Patents, patents in process, and are protected by trade secret * or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden * unless prior written permission is obtained from Backendless.com. *

* ******************************************************************************************************************** */ package com.backendless.persistence; import com.backendless.Backendless; import com.backendless.BackendlessUser; import com.backendless.FootprintsManager; import com.backendless.Persistence; import com.backendless.exceptions.BackendlessException; import com.backendless.exceptions.ExceptionMessage; import com.backendless.geo.GeoPoint; import java.lang.reflect.Array; import java.util.*; /** * Handles object to Map serialization for Backendless services. */ public class BackendlessSerializer { /** * Serializes Object to Map using WebOrb's serializer. * * @param entity object to be serialized * @return Map corresponding to given Object */ public static Map serializeToMap( Object entity ) { return (Map) serializeToMap( entity, new HashMap>( ) ); } private static Object serializeToMap( Object entity, Map> serializedCache ) { if(entity.getClass().isArray()) { return serializeArray( entity, serializedCache ); } if( entity.getClass().isEnum() ) { return ((Enum) entity).name(); } Map serializedEntity = new HashMap(); if( entity.getClass() == BackendlessUser.class ) { serializedEntity = ((BackendlessUser) entity).getProperties(); } else { weborb.util.ObjectInspector.getObjectProperties( entity.getClass(), entity, (HashMap) serializedEntity, new ArrayList(), true, true ); } serializedCache.put( entity, serializedEntity ); FootprintsManager.getInstance().Inner.putMissingPropsToEntityMap( entity, serializedEntity ); //put ___class field, otherwise server will not be able to detect class serializedEntity.put( Persistence.REST_CLASS_FIELD, Persistence.getSimpleName( entity.getClass() ) ); //recursively serialize object properties Iterator> entityIterator = serializedEntity.entrySet().iterator(); while( entityIterator.hasNext() ) { Map.Entry entityEntry = entityIterator.next(); // ignoring properties which contain $. This occurs in InstantRun in AndroidStudio - it injects $change property. if( entityEntry.getKey().contains( "$" ) ) { entityIterator.remove(); continue; } // ignore Parcelable CREATOR field on Android // http://developer.android.com/reference/android/os/Parcelable.html if( Backendless.isAndroid() && entityEntry.getKey().equals( Persistence.PARCELABLE_CREATOR_FIELD_NAME ) ) { entityIterator.remove(); continue; } Object entityEntryValue = entityEntry.getValue(); // ignore null entries and GeoPoints if( entityEntryValue == null || entityEntryValue instanceof GeoPoint ) { continue; } // check for anonymous class entry if( entityEntryValue.getClass().isAnonymousClass() ) { throw new BackendlessException( String.format( ExceptionMessage.ANONYMOUS_CLASSES_PROHIBITED, entityEntry.getKey() ) ); } //check if entity entry is collection if( entityEntryValue instanceof List ) { List listEntry = (List) entityEntryValue; //do nothing with empty lists and lists of GeoPoints if( listEntry.isEmpty() || listEntry.iterator().next() instanceof GeoPoint ) { continue; } // check for anonymous class entry if( listEntry.iterator().next().getClass().isAnonymousClass() ) { throw new BackendlessException( String.format( ExceptionMessage.ANONYMOUS_CLASSES_PROHIBITED, entityEntry.getKey() ) ); } List newCollection = new ArrayList(); for( Object listEntryItem : listEntry ) { if( !isBelongsJdk( listEntryItem.getClass() ) ) { newCollection.add( getOrMakeSerializedObject( listEntryItem, serializedCache ) ); } } entityEntry.setValue( newCollection ); } else //not collection { if( !isBelongsJdk( entityEntryValue.getClass() ) ) { entityEntry.setValue( getOrMakeSerializedObject( entityEntryValue, serializedCache ) ); } } } return serializedEntity; } private static Object serializeArray( Object entity, Map> serializedCache ) { int length = Array.getLength( entity ); Object[] objects = new Object[length]; for( int i = 0; i < length; i++ ) { objects[i] = getOrMakeSerializedObject( Array.get( entity, i ), serializedCache ); } return objects; } /** * Returns serialized object from cache or serializes object if it's not present in cache. * * @param entityEntryValue object to be serialized * @return Map formed from given object */ private static Object getOrMakeSerializedObject( Object entityEntryValue, Map> serializedCache ) { if( serializedCache.containsKey( entityEntryValue ) ) //cyclic relation { //take from cache and substitute return serializedCache.get( entityEntryValue ); } else //not cyclic relation { //serialize and put into result return serializeToMap( entityEntryValue, serializedCache ); } } /** * Serializes entities inside BackendlessUser properties. * * @param user BackendlessUser whose properties need to be serialized */ public static void serializeUserProperties( BackendlessUser user ) { Map serializedProperties = user.getProperties(); Set> properties = serializedProperties.entrySet(); for( Map.Entry property : properties ) { Object propertyValue = property.getValue(); if( propertyValue != null && !isBelongsJdk( propertyValue.getClass() ) ) { property.setValue( serializeToMap( propertyValue, new HashMap>() ) ); } } user.setProperties( serializedProperties ); } /** * Checks whether class is defined in JDK or it is user-defined class. * http://stackoverflow.com/questions/8703678/how-can-i-check-if-a-class-belongs-to-java-jdk * * @param clazz Class to be checked * @return true if this class is from JDK, false if class is user-defined */ public static boolean isBelongsJdk( Class clazz ) { return clazz.getClassLoader() == "".getClass().getClassLoader(); } }