Skip to content

Binary handler set from map serializer#72 #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.eclipse.serializer.exceptions;

/**
* Indicates that no nested class with the specified name was found
* in class c.
*/
public class NoSuchNestedClassRuntimeException extends BaseException
{
///////////////////////////////////////////////////////////////////////////
// constructors //
/////////////////

public NoSuchNestedClassRuntimeException(final Class<?> c, final String name)
{
super("No nested class " + name + " found in class " + c.getName());
}

}
55 changes: 44 additions & 11 deletions base/src/main/java/org/eclipse/serializer/reflect/XReflect.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,41 @@
* #L%
*/

import static org.eclipse.serializer.util.X.notEmpty;
import static org.eclipse.serializer.util.X.notNull;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.eclipse.serializer.branching.ThrowBreak;
import org.eclipse.serializer.chars.XChars;
import org.eclipse.serializer.collections.BulkList;
import org.eclipse.serializer.collections.XArrays;
import org.eclipse.serializer.collections.types.XMap;
import org.eclipse.serializer.collections.types.XReference;
import org.eclipse.serializer.exceptions.*;
import org.eclipse.serializer.exceptions.IllegalAccessRuntimeException;
import org.eclipse.serializer.exceptions.InstantiationRuntimeException;
import org.eclipse.serializer.exceptions.MemoryException;
import org.eclipse.serializer.exceptions.NoSuchFieldRuntimeException;
import org.eclipse.serializer.exceptions.NoSuchMethodRuntimeException;
import org.eclipse.serializer.exceptions.NoSuchNestedClassRuntimeException;
import org.eclipse.serializer.functional.Instantiator;
import org.eclipse.serializer.functional.XFunc;
import org.eclipse.serializer.memory.XMemory;
import org.eclipse.serializer.typing.XTypes;
import org.eclipse.serializer.util.UtilStackTrace;
import org.eclipse.serializer.util.X;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;

import static org.eclipse.serializer.util.X.notEmpty;
import static org.eclipse.serializer.util.X.notNull;


/**
* Provides additional generic util methods for working with java reflection.
Expand Down Expand Up @@ -383,6 +394,28 @@ public static <L extends Consumer<Field>> L iterateDeclaredFieldsUpwards(
return logic;
}

/**
* Search declared classes of class c for
* a class that name is equals to the provided name.
*
* @param c class to search in
* @param name class name to search
* @return the found class
* @throws NoSuchNestedClassRuntimeException if no match found
*/
public static Class<?> getDeclaredNestedClass(final Class<?> c, final String name) throws NoSuchNestedClassRuntimeException
{
Class<?>[] declaredClasses = c.getDeclaredClasses();

for(Class<?> clazz : declaredClasses) {
if(clazz.getName().equals(name)) {
return clazz;
}
}

throw new NoSuchNestedClassRuntimeException(c, name);
}

public static Field getDeclaredField(final Class<?> c, final String name) throws NoSuchFieldRuntimeException
{
try
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.eclipse.serializer.persistence.binary.java.util;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.serializer.memory.XMemory;
import org.eclipse.serializer.persistence.binary.types.AbstractBinaryHandlerCustom;
import org.eclipse.serializer.persistence.binary.types.Binary;
import org.eclipse.serializer.persistence.types.PersistenceLoadHandler;
import org.eclipse.serializer.persistence.types.PersistenceReferenceLoader;
import org.eclipse.serializer.persistence.types.PersistenceStoreHandler;
import org.eclipse.serializer.reflect.XReflect;

/**
* Binary Handler for private class "java.util.Collections$SetFromMap"
*/
public class BinaryHandlerSetFromMap<T> extends AbstractBinaryHandlerCustom<T>
{
private static long offsetMap;
private static long offsetSet;

public static BinaryHandlerSetFromMap<?> New()
{
Class<?> clazz = XReflect.getDeclaredNestedClass(Collections.class, "java.util.Collections$SetFromMap");

offsetMap = XMemory.objectFieldOffset(XReflect.getAnyField(clazz, "m"));
offsetSet = XMemory.objectFieldOffset(XReflect.getAnyField(clazz, "s"));

return new BinaryHandlerSetFromMap<>(clazz);
}

///////////////////////////////////////////////////////////////////////////
// constructors //
/////////////////

protected BinaryHandlerSetFromMap(final Class<T> type)
{
super(type,
CustomFields(
CustomField(Map.class, "map"))
);
}

///////////////////////////////////////////////////////////////////////////
// methods //
////////////

@Override
public void iterateLoadableReferences(final Binary data, final PersistenceReferenceLoader iterator)
{
iterator.acceptObjectId(data.read_long(0));
}

@Override
public void updateState(final Binary data, T instance, final PersistenceLoadHandler handler)
{
final Map<?,?> hashmap = (Map<?, ?>) handler.lookupObject(data.read_long(0));

XMemory.setObject(instance, offsetMap, hashmap);
XMemory.setObject(instance, offsetSet, hashmap.keySet());
}

@Override
public void store(final Binary data, final T instance, final long objectId, final PersistenceStoreHandler<Binary> handler)
{
data.storeEntityHeader(Binary.referenceBinaryLength(1), this.typeId(), objectId);

Object mapInstance = XMemory.getObject(instance, offsetMap);
data.storeReference(0, handler, mapInstance);
}

@SuppressWarnings("unchecked")
@Override
public T create(final Binary data, final PersistenceLoadHandler handler)
{
return (T) Collections.newSetFromMap(new HashMap<Object,Boolean>());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerOptionalLong;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerPriorityQueue;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerProperties;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerSetFromMap;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerStack;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerTreeMap;
import org.eclipse.serializer.persistence.binary.java.util.BinaryHandlerTreeSet;
Expand Down Expand Up @@ -330,7 +331,8 @@ static final void initializeNativeTypeId(
BinaryHandlerArrayDeque.New() ,
BinaryHandlerConcurrentSkipListMap.New(),
BinaryHandlerConcurrentSkipListSet.New(),

BinaryHandlerSetFromMap.New(),

// JDK 1.7 collections
BinaryHandlerConcurrentLinkedDeque.New(),

Expand Down
Loading