This repository has been archived by the owner on Nov 5, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
da82a23
commit 628b764
Showing
4 changed files
with
181 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
167 changes: 167 additions & 0 deletions
167
src/main/java/com/fasterxml/jackson/module/afterburner/deser/DeserializerModifier.java.orig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
package com.fasterxml.jackson.module.afterburner.deser; | ||
|
||
import java.lang.reflect.Modifier; | ||
import java.util.*; | ||
|
||
import com.fasterxml.jackson.databind.*; | ||
import com.fasterxml.jackson.databind.deser.*; | ||
import com.fasterxml.jackson.databind.deser.impl.FieldProperty; | ||
import com.fasterxml.jackson.databind.deser.impl.MethodProperty; | ||
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator; | ||
import com.fasterxml.jackson.databind.introspect.*; | ||
import com.fasterxml.jackson.databind.util.ClassUtil; | ||
|
||
import com.fasterxml.jackson.module.afterburner.util.MyClassLoader; | ||
|
||
public class DeserializerModifier extends BeanDeserializerModifier | ||
{ | ||
/** | ||
* Class loader to use for generated classes; if null, will try to | ||
* use class loader of the target class. | ||
*/ | ||
protected final MyClassLoader _classLoader; | ||
|
||
protected final boolean _useCustomDeserializer; | ||
|
||
public DeserializerModifier(ClassLoader cl, boolean useCustomDeserializer) | ||
{ | ||
// If we were given parent class loader explicitly, use that: | ||
_classLoader = (cl == null) ? null : new MyClassLoader(cl, false); | ||
_useCustomDeserializer = useCustomDeserializer; | ||
} | ||
|
||
/* | ||
/********************************************************************** | ||
/* BeanDeserializerModifier methods | ||
/********************************************************************** | ||
*/ | ||
|
||
@Override | ||
public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, | ||
BeanDescription beanDesc, BeanDeserializerBuilder builder) | ||
{ | ||
final Class<?> beanClass = beanDesc.getBeanClass(); | ||
// [Issue#21]: Can't force access to sealed packages, or anything within "java." | ||
if (!MyClassLoader.canAddClassInPackageOf(beanClass)) { | ||
return builder; | ||
} | ||
/* Hmmh. Can we access stuff from private classes? | ||
* Possibly, if we can use parent class loader. | ||
* (should probably skip all non-public?) | ||
*/ | ||
if (_classLoader != null) { | ||
if (Modifier.isPrivate(beanClass.getModifiers())) { | ||
return builder; | ||
} | ||
} | ||
PropertyMutatorCollector collector = new PropertyMutatorCollector(beanClass); | ||
List<OptimizedSettableBeanProperty<?>> newProps = findOptimizableProperties( | ||
config, collector, builder.getProperties()); | ||
// and if we found any, create mutator proxy, replace property objects | ||
if (!newProps.isEmpty()) { | ||
BeanPropertyMutator mutator = collector.buildMutator(_classLoader); | ||
for (OptimizedSettableBeanProperty<?> prop : newProps) { | ||
builder.addOrReplaceProperty(prop.withMutator(mutator), true); | ||
} | ||
} | ||
// Second thing: see if we could (re)generate Creator(s): | ||
ValueInstantiator inst = builder.getValueInstantiator(); | ||
/* Hmmh. Probably better to require exact default implementation | ||
* and not sub-class; chances are sub-class uses its own | ||
* construction anyway. | ||
*/ | ||
if (inst.getClass() == StdValueInstantiator.class) { | ||
// also, only override if using default creator (no-arg ctor, no-arg static factory) | ||
if (inst.canCreateUsingDefault()) { | ||
inst = new CreatorOptimizer(beanClass, _classLoader, (StdValueInstantiator) inst).createOptimized(); | ||
if (inst != null) { | ||
builder.setValueInstantiator(inst); | ||
} | ||
} | ||
} | ||
|
||
// also: may want to replace actual BeanDeserializer as well? For this, need to replace builder | ||
// (but only if builder is the original standard one; don't want to break other impls) | ||
if (_useCustomDeserializer && builder.getClass() == BeanDeserializerBuilder.class) { | ||
return new SuperSonicDeserializerBuilder(builder); | ||
} | ||
return builder; | ||
} | ||
|
||
/* | ||
/********************************************************************** | ||
/* Internal methods | ||
/********************************************************************** | ||
*/ | ||
|
||
protected List<OptimizedSettableBeanProperty<?>> findOptimizableProperties( | ||
DeserializationConfig config, PropertyMutatorCollector collector, | ||
Iterator<SettableBeanProperty> propIterator) | ||
{ | ||
ArrayList<OptimizedSettableBeanProperty<?>> newProps = new ArrayList<OptimizedSettableBeanProperty<?>>(); | ||
|
||
// Ok, then, find any properties for which we could generate accessors | ||
while (propIterator.hasNext()) { | ||
SettableBeanProperty prop = propIterator.next(); | ||
AnnotatedMember member = prop.getMember(); | ||
|
||
// First: we can't access private fields or methods.... | ||
if (Modifier.isPrivate(member.getMember().getModifiers())) { | ||
continue; | ||
} | ||
// (although, interestingly enough, can seem to access private classes...) | ||
|
||
// 30-Jul-2012, tatu: [Issue-6]: Needs to skip custom deserializers, if any. | ||
if (prop.hasValueDeserializer()) { | ||
if (!isDefaultDeserializer(config, prop.getValueDeserializer())) { | ||
continue; | ||
} | ||
} | ||
|
||
if (prop instanceof MethodProperty) { // simple setter methods | ||
Class<?> type = ((AnnotatedMethod) member).getRawParameterType(0); | ||
if (type.isPrimitive()) { | ||
if (type == Integer.TYPE) { | ||
newProps.add(collector.addIntSetter(prop)); | ||
} else if (type == Long.TYPE) { | ||
newProps.add(collector.addLongSetter(prop)); | ||
} | ||
} else { | ||
if (type == String.class) { | ||
newProps.add(collector.addStringSetter(prop)); | ||
} else { // any other Object types; we can at least call accessor | ||
newProps.add(collector.addObjectSetter(prop)); | ||
} | ||
} | ||
} else if (prop instanceof FieldProperty) { // regular fields | ||
Class<?> type = member.getRawType(); | ||
if (type.isPrimitive()) { | ||
if (type == Integer.TYPE) { | ||
newProps.add(collector.addIntField(prop)); | ||
} else if (type == Long.TYPE) { | ||
newProps.add(collector.addLongField(prop)); | ||
} | ||
} else { | ||
if (type == String.class) { | ||
newProps.add(collector.addStringField(prop)); | ||
} else { // any other Object types; we can at least call accessor | ||
newProps.add(collector.addObjectField(prop)); | ||
} | ||
} | ||
} | ||
} | ||
return newProps; | ||
} | ||
|
||
|
||
/** | ||
* Helper method used to check whether given deserializer is the default | ||
* deserializer implementation: this is necessary to avoid overriding other | ||
* kinds of deserializers. | ||
*/ | ||
protected boolean isDefaultDeserializer(DeserializationConfig config, | ||
JsonDeserializer<?> ser) | ||
{ | ||
return ClassUtil.isJacksonStdImpl(ser); | ||
} | ||
} |