com.fasterxml.jackson.module.blackbird.ser.BBSerializerModifier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jackson-module-blackbird Show documentation
Show all versions of jackson-module-blackbird Show documentation
Jackson (https://github.com/FasterXML/jackson) extension module
that uses LambdaMetafactory based code generation to replace reflection calls.
The newest version!
package com.fasterxml.jackson.module.blackbird.ser;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.UnaryOperator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.ser.*;
import com.fasterxml.jackson.module.blackbird.util.ReflectionHack;
import com.fasterxml.jackson.module.blackbird.util.Unchecked;
import static java.lang.invoke.MethodType.*;
public class BBSerializerModifier extends BeanSerializerModifier
{
private static final long serialVersionUID = 1L;
private final Function, Lookup> _lookups;
private final UnaryOperator _accessGrant;
public BBSerializerModifier(Function, MethodHandles.Lookup> lookups, UnaryOperator accessGrant)
{
_lookups = lookups;
_accessGrant = accessGrant;
}
@Override
public List changeProperties(SerializationConfig config,
BeanDescription beanDesc, List beanProperties)
{
final Class> beanClass = beanDesc.getBeanClass();
/* Hmmh. Can we access stuff from private classes?
* Possibly, if we can use parent class loader.
* (should probably skip all non-public?)
*/
if (Modifier.isPrivate(beanClass.getModifiers())) { // TODO?
return beanProperties;
}
findProperties(beanClass, config, beanProperties);
return beanProperties;
}
protected void findProperties(Class> beanClass,
SerializationConfig config, List beanProperties)
{
MethodHandles.Lookup lookup = _lookups.apply(beanClass);
if (lookup == null) {
return;
}
ListIterator it = beanProperties.listIterator();
while (it.hasNext()) {
Unchecked.runnable(() ->
createProperty(it, ReflectionHack.privateLookupIn(beanClass, lookup), config))
.run();
}
}
protected void createProperty(ListIterator it, Lookup lookup, SerializationConfig config) throws Throwable {
BeanPropertyWriter bpw = it.next();
AnnotatedMember member = bpw.getMember();
Member jdkMember = member.getMember();
// 11-Sep-2015, tatu: Let's skip virtual members (related to #57)
if (jdkMember == null) {
return;
}
// We can't access private fields or methods, skip:
if (Modifier.isPrivate(jdkMember.getModifiers())) {
return;
}
// (although, interestingly enough, can seem to access private classes...)
// 30-Jul-2012, tatu: [#6]: Needs to skip custom serializers, if any.
if (bpw.hasSerializer() && !SerializerUtil.isDefaultSerializer(bpw.getSerializer())) {
return;
}
// [#9]: also skip unwrapping stuff...
if (bpw.isUnwrapping()) {
return;
}
if (!bpw.getClass().isAnnotationPresent(JacksonStdImpl.class)) {
return;
}
Class> type = bpw.getMember().getRawType();
MethodHandle getter;
if (member instanceof AnnotatedMethod) {
getter = lookup.unreflect((Method) member.getMember());
} else {
// TODO: currently VarHandles aren't considered direct MH
return;
//getter = lookup.unreflectGetter((Field) member.getMember());
}
lookup = _accessGrant.apply(lookup);
if (type.isPrimitive()) {
if (type == Integer.TYPE) {
ToIntFunction
© 2015 - 2025 Weber Informatics LLC | Privacy Policy