Skip to content

Commit

Permalink
Merge remote-tracking branch 'alibaba/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorZeng committed Jul 11, 2016
2 parents 255cbf2 + 377ef18 commit bf7d441
Show file tree
Hide file tree
Showing 39 changed files with 509 additions and 38 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.13-SNAPSHOT</version>
<version>1.2.14-SNAPSHOT</version>

<packaging>jar</packaging>
<name>fastjson</name>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/alibaba/fastjson/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ public <T> T toJavaObject(Class<T> clazz) {
return TypeUtils.cast(this, clazz, ParserConfig.getGlobalInstance());
}

public final static String VERSION = "1.2.13";
public final static String VERSION = "1.2.14";

private final static ThreadLocal<byte[]> bytesLocal = new ThreadLocal<byte[]>();
private static byte[] allocateBytes(int length) {
Expand Down
102 changes: 102 additions & 0 deletions src/main/java/com/alibaba/fastjson/JSONPath.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,43 @@ public void arrayAdd(Object rootObject, Object... values) {

throw new UnsupportedOperationException();
}

public boolean remove(Object rootObject) {
if (rootObject == null) {
return false;
}

init();

Object currentObject = rootObject;
Object parentObject = null;
for (int i = 0; i < segments.length; ++i) {
if (i == segments.length - 1) {
parentObject = currentObject;
break;
}
currentObject = segments[i].eval(this, rootObject, currentObject);
if (currentObject == null) {
break;
}
}

if (parentObject == null) {
return false;
}

Segement lastSegement = segments[segments.length - 1];
if (lastSegement instanceof PropertySegement) {
PropertySegement propertySegement = (PropertySegement) lastSegement;
return propertySegement.remove(this, parentObject);
}

if (lastSegement instanceof ArrayAccessSegement) {
return ((ArrayAccessSegement) lastSegement).remove(this, parentObject);
}

throw new UnsupportedOperationException();
}

public boolean set(Object rootObject, Object value) {
if (rootObject == null) {
Expand Down Expand Up @@ -277,6 +314,11 @@ public static boolean set(Object rootObject, String path, Object value) {
JSONPath jsonpath = compile(path);
return jsonpath.set(rootObject, value);
}

public static boolean remove(Object root, String path) {
JSONPath jsonpath = compile(path);
return jsonpath.remove(root);
}

public static JSONPath compile(String path) {
if (path == null) {
Expand Down Expand Up @@ -1027,6 +1069,10 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) {
public void setValue(JSONPath path, Object parent, Object value) {
path.setPropertyValue(parent, propertyName, value);
}

public boolean remove(JSONPath path, Object parent) {
return path.removePropertyValue(parent, propertyName);
}
}

static class MultiPropertySegement implements Segement {
Expand Down Expand Up @@ -1074,6 +1120,10 @@ public Object eval(JSONPath path, Object rootObject, Object currentObject) {
public boolean setValue(JSONPath path, Object currentObject, Object value) {
return path.setArrayItem(path, currentObject, index, value);
}

public boolean remove(JSONPath path, Object currentObject) {
return path.removeArrayItem(path, currentObject, index);
}
}

static class MultiIndexSegement implements Segement {
Expand Down Expand Up @@ -1594,6 +1644,31 @@ public boolean setArrayItem(JSONPath path, Object currentObject, int index, Obje
throw new JSONPathException("unsupported set operation." + clazz);
}

@SuppressWarnings("rawtypes")
public boolean removeArrayItem(JSONPath path, Object currentObject, int index) {
if (currentObject instanceof List) {
List list = (List) currentObject;
if (index >= 0) {
if (index >= list.size()) {
return false;
}
list.remove(index);
} else {
int newIndex = list.size() + index;

if (newIndex < 0) {
return false;
}

list.remove(newIndex);
}
return true;
}

Class<?> clazz = currentObject.getClass();
throw new JSONPathException("unsupported set operation." + clazz);
}

@SuppressWarnings({ "rawtypes", "unchecked" })
protected Collection<Object> getPropertyValues(final Object currentObject) {
final Class<?> currentClass = currentObject.getClass();
Expand Down Expand Up @@ -1772,6 +1847,33 @@ protected boolean setPropertyValue(Object parent, String name, Object value) {

throw new UnsupportedOperationException();
}

@SuppressWarnings({"rawtypes" })
protected boolean removePropertyValue(Object parent, String name) {
if (parent instanceof Map) {
Object origin = ((Map) parent).remove(name);
return origin != null;
}

ObjectDeserializer derializer = parserConfig.getDeserializer(parent.getClass());

JavaBeanDeserializer beanDerializer = null;
if (derializer instanceof JavaBeanDeserializer) {
beanDerializer = (JavaBeanDeserializer) derializer;
}

if (beanDerializer != null) {
FieldDeserializer fieldDeserializer = beanDerializer.getFieldDeserializer(name);
if (fieldDeserializer == null) {
return false;
}

fieldDeserializer.setValue(parent, null);
return true;
}

throw new UnsupportedOperationException();
}

protected JavaBeanSerializer getJavaBeanSerializer(final Class<?> currentClass) {
JavaBeanSerializer beanSerializer = null;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/alibaba/fastjson/annotation/JSONType.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,14 @@
* @since 1.2.11
*/
Class<?>[] seeAlso() default{};

/**
* @since 1.2.14
*/
Class<?> serializer() default Void.class;

/**
* @since 1.2.14
*/
Class<?> deserializer() default Void.class;
}
12 changes: 8 additions & 4 deletions src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,15 @@ public final Object parseObject(final Map object, Object fieldName) {
}

if (!setContextFlag) {
ParseContext contextR = setContext(object, fieldName);
if (context == null) {
context = contextR;
if (this.context != null && fieldName == this.context.fieldName && object == this.context.object) {
context = this.context;
} else {
ParseContext contextR = setContext(object, fieldName);
if (context == null) {
context = contextR;
}
setContextFlag = true;
}
setContextFlag = true;
}

if (object.getClass() == JSONObject.class) {
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/com/alibaba/fastjson/parser/ParserConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,20 @@ public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type)
if (asmEnable) {
JSONType jsonType = clazz.getAnnotation(JSONType.class);

if (jsonType != null && !jsonType.asm()) {
asmEnable = false;
if (jsonType != null) {
Class<?> deserializerClass = jsonType.deserializer();
if (deserializerClass != Void.class) {
try {
Object deseralizer = deserializerClass.newInstance();
if (deseralizer instanceof ObjectDeserializer) {
return (ObjectDeserializer) deseralizer;
}
} catch (Throwable e) {
// skip
}
}

asmEnable = jsonType.asm();
}

if (asmEnable) {
Expand Down Expand Up @@ -624,7 +636,7 @@ public static boolean isPrimitive(Class<?> clazz) {
* fieldName,field ,先生成fieldName的快照,减少之后的findField的轮询
*
* @param clazz
* @param fieldCacheMap :map<fieldName ,Field>
* @param fieldCacheMap :map&lt;fieldName ,Field&gt;
*/
public static void parserAllFieldToCache(Class<?> clazz,Map</**fieldName*/String , Field> fieldCacheMap){
Field[] fields=clazz.getDeclaredFields() ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ private void _deserialze(ClassWriter cw, Context context) {
mw.visitVarInsn(ASTORE, context.var(fieldInfo.name + "_asm_enumName"));

mw.visitJumpInsn(IFNULL, enumNull_);

mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
mw.visitMethodInsn(INVOKEVIRTUAL, type(String.class), "length", "()I");
mw.visitJumpInsn(IFEQ, enumNull_);

mw.visitVarInsn(ALOAD, context.var(fieldInfo.name + "_asm_enumName"));
mw.visitMethodInsn(INVOKESTATIC, type(fieldClass), "valueOf",
"(Ljava/lang/String;)" + desc(fieldClass));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ public Object createInstance(DefaultJSONParser parser, Type type) {
} else {
ParseContext context = parser.getContext();
String parentName = context.object.getClass().getName();
String typeName = type.getTypeName();
String typeName = "";

if (type instanceof Class) {
typeName = ((Class<?>) type).getName();
}

if(parentName.length() != typeName.lastIndexOf('$') - 1){
char[] typeChars = typeName.toCharArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class StackTraceElementDeserializer implements ObjectDeserializer {

public final static StackTraceElementDeserializer instance = new StackTraceElementDeserializer();

@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "unused" })
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.NULL) {
Expand Down
29 changes: 22 additions & 7 deletions src/main/java/com/alibaba/fastjson/serializer/SerializeConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,26 @@ private final ObjectSerializer createJavaBeanSerializer(Class<?> clazz) {
}

public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) {
JSONType jsonType = beanInfo.jsonType;

if (jsonType != null) {
Class<?> serializerClass = jsonType.serializer();
if (serializerClass != Void.class) {
try {
Object seralizer = serializerClass.newInstance();
if (seralizer instanceof ObjectSerializer) {
return (ObjectSerializer) seralizer;
}
} catch (Throwable e) {
// skip
}
}

if (jsonType.asm() == false) {
asm = false;
}
}

Class<?> clazz = beanInfo.beanType;
if (!Modifier.isPublic(beanInfo.beanType.getModifiers())) {
return new JavaBeanSerializer(beanInfo);
Expand All @@ -130,13 +150,6 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) {
asm = false;
}

{
JSONType annotation = clazz.getAnnotation(JSONType.class);
if (annotation != null && annotation.asm() == false) {
asm = false;
}
}

if (asm && !ASMUtils.checkName(clazz.getName())) {
asm = false;
}
Expand Down Expand Up @@ -164,6 +177,8 @@ public ObjectSerializer createJavaBeanSerializer(SerializeBeanInfo beanInfo) {
if (asmSerializer != null) {
return asmSerializer;
}
} catch (ClassFormatError e) {
// skip
} catch (ClassCastException e) {
// skip
} catch (Throwable e) {
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/com/alibaba/fastjson/util/JavaBeanInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,22 @@ public static JavaBeanInfo build(Class<?> clazz, Type type) {
}

for (Field field : clazz.getFields()) { // public static fields
if (Modifier.isStatic(field.getModifiers())) {
int modifiers = field.getModifiers();
if ((modifiers & Modifier.STATIC) != 0) {
continue;
}

if((modifiers & Modifier.FINAL) != 0) {
Class<?> fieldType = field.getType();
boolean supportReadOnly = Map.class.isAssignableFrom(fieldType)
|| Collection.class.isAssignableFrom(fieldType)
|| AtomicLong.class.equals(fieldType) //
|| AtomicInteger.class.equals(fieldType) //
|| AtomicBoolean.class.equals(fieldType);
if (!supportReadOnly) {
continue;
}
}

boolean contains = false;
for (FieldInfo item : fieldList) {
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/com/alibaba/json/bvt/FinalTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.alibaba.json.bvt;

import org.junit.Assert;

import com.alibaba.fastjson.JSON;

import junit.framework.TestCase;

public class FinalTest extends TestCase {
public void test_final() throws Exception {
VO vo = new VO();
String text = JSON.toJSONString(vo);
Assert.assertEquals("{\"value\":1001}", text);
JSON.parseObject(text, VO.class);
JSON.parseObject("{\"id\":1001,\"value\":1001}", VO.class);
}


public static class VO {
public final static int id = 1001;
public final int value = 1001;
}
}
Loading

0 comments on commit bf7d441

Please sign in to comment.