gu.sql2java.json.JacksonDeserializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql2java-base Show documentation
Show all versions of sql2java-base Show documentation
sql2java common class package
package gu.sql2java.json;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers.IntegerDeserializer;
import com.gitee.l0km.beanfilter.json.JacksonFilterableDeserializer;
import com.google.common.collect.FluentIterable;
import gu.sql2java.BaseBean;
import gu.sql2java.Constant;
import gu.sql2java.config.RuntimeConfig;
import static gu.sql2java.Sql2javaSupport.findSuperClass;
import static gu.sql2java.ArraySupport.toHex;
/**
* implementation of BaseBean class for Jackson {@link JsonDeserializer},
*
* @author guyadong
* @since 3.21.2
*/
public class JacksonDeserializer extends JacksonFilterableDeserializer implements Constant {
private static final long serialVersionUID = 7410414787512241455L;
public JacksonDeserializer(Class extends BaseBean> beanClass) {
super(beanClass, true, true);
}
private final static IntegerDeserializer primitiveInstance = new IntegerDeserializer(Integer.TYPE, 0);
/**
* 根据{@link JsonToken}类型灵活解析指定字段
* 如果token为整数则用 {@link IntegerDeserializer}解析否则调用原{@link SettableBeanProperty}对象解析
*/
private Object flexibleDeserializeByToken(SettableBeanProperty prop,JsonToken token, JsonParser jp,DeserializationContext ctxt) throws IOException {
if(JsonToken.VALUE_NUMBER_INT.equals(token)) {
return primitiveInstance.deserialize(jp, ctxt);
}
return prop.deserialize(jp,ctxt);
}
@Override
public BaseBean doDeserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// see also BeanDeserializer.vanillaDeserialize
BaseBean bean = (BaseBean) _valueInstantiator.createUsingDefault(ctxt);
Boolean _new = null;
Object initialized = null;
Object modified = null;
/** 输入中存在的字段 */
LinkedHashSet deserialized = new LinkedHashSet<>();
/** 被过滤的字段 */
HashSet modifiedReset = new HashSet<>();
/** 值过滤时被额外添加非null值的字段 */
LinkedHashSet modifiedSet = new LinkedHashSet<>();
for(String propName = jp.nextFieldName();propName != null;propName = jp.nextFieldName()) {
JsonToken token = jp.nextToken();
SettableBeanProperty prop = findProperty(this,propName);
if (prop != null) { // normal case
try {
switch(propName) {
case FIELD_NEW:
_new = (Boolean) prop.deserialize(jp,ctxt);
break;
case FIELD_INITIALIZED:
if(getSupplyFilter().permit(handledType(), prop.getName())) {
initialized = flexibleDeserializeByToken(prop, token,jp,ctxt);
}
break;
case FIELD_MODIFIED:
if(getSupplyFilter().permit(handledType(), prop.getName())) {
modified = flexibleDeserializeByToken(prop, token,jp,ctxt);
}
break;
default:
deserialized.add(prop.getName());
if(!deserializeProperty(jp, ctxt, bean, prop)) {
modifiedReset.add(propName);
}
break;
}
} catch (Exception e) {
wrapAndThrow(e, bean, propName, ctxt);
}
continue;
}
handleUnknownVanilla(jp, ctxt, bean, propName);
}
if(null != _new) {
bean.setNew(_new);
}
if(null != initialized){
bean.setInitialized(toHex(initialized));
}
if(null != modified){
bean.setModified(toHex(modified));
}
processUndeserialized(bean,deserialized, modifiedSet);
if(!modifiedReset.isEmpty()) {
bean.resetModified(modifiedReset.toArray(new String[modifiedReset.size()]));
}
if(!modifiedSet.isEmpty()) {
bean.modified(modifiedSet.toArray(new String[modifiedSet.size()]));
}
if (null != findSuperClass(RuntimeConfig.getLocalConfig().getResetModifiedIfEqual(),handledType())) {
bean.resetModifiedIfEqual();
}
return bean;
}
@Override
protected T processUndeserialized(T bean, Set deserialized, Set additional) throws IOException {
/** 忽略new,initialized,modified字段 */
deserialized = FluentIterable.from(deserialized).append(FIELD_NEW,FIELD_INITIALIZED,FIELD_MODIFIED).toSet();
return super.processUndeserialized(bean, deserialized, additional);
}
}