support BeforeFilter

This commit is contained in:
wenshao
2013-07-14 11:53:24 +08:00
parent d682b8df97
commit fe77561ded
10 changed files with 155 additions and 2 deletions
@@ -35,6 +35,7 @@ import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
import com.alibaba.fastjson.serializer.BeforeFilter;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.NameFilter;
import com.alibaba.fastjson.serializer.PropertyFilter;
@@ -441,6 +442,10 @@ public abstract class JSON implements JSONStreamAware, JSONAware {
if (filter instanceof PropertyFilter) {
serializer.getPropertyFilters().add((PropertyFilter) filter);
}
if (filter instanceof BeforeFilter) {
serializer.getBeforeFilters().add((BeforeFilter) filter);
}
}
serializer.write(object);
@@ -56,7 +56,6 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;
import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer;
import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
@@ -386,6 +386,8 @@ public class ASMSerializerFactory implements Opcodes {
}
mw.visitVarInsn(ISTORE, context.var("seperator"));
_before(mw, context);
for (int i = 0; i < size; ++i) {
FieldInfo property = getters.get(i);
@@ -1064,6 +1066,15 @@ public class ASMSerializerFactory implements Opcodes {
_seperator(mw, context);
}
private void _before(MethodVisitor mw, Context context) {
mw.visitVarInsn(ALOAD, context.serializer());
mw.visitVarInsn(ALOAD, context.obj());
mw.visitVarInsn(ILOAD, context.var("seperator"));
mw.visitMethodInsn(INVOKESTATIC, getType(FilterUtils.class), "writeBefore",
"(Lcom/alibaba/fastjson/serializer/JSONSerializer;Ljava/lang/Object;C)C");
mw.visitVarInsn(ISTORE, context.var("seperator"));
}
private void _apply(MethodVisitor mw, FieldInfo property, Context context) {
Class<?> propertyClass = property.getFieldClass();
@@ -0,0 +1,29 @@
package com.alibaba.fastjson.serializer;
public abstract class BeforeFilter implements SerializeFilter {
private final ThreadLocal<JSONSerializer> serializerLocal = new ThreadLocal<JSONSerializer>();
private final ThreadLocal<Character> commaLocal = new ThreadLocal<Character>();
private final static Character COMMA = Character.valueOf(',');
final char writeBefore(JSONSerializer serializer, Object object, char commaFlag) {
serializerLocal.set(serializer);
commaLocal.set(commaFlag);
writeBefore(object);
serializerLocal.set(null);
return commaLocal.get();
}
public abstract void writeBefore(Object object);
public final void writeKeyValue(String key, Object value) {
JSONSerializer serializer = serializerLocal.get();
char comma = commaLocal.get();
serializer.writeKeyValue(comma, key, value);
if (comma != ',') {
commaLocal.set(COMMA);
}
}
}
@@ -3,7 +3,17 @@ package com.alibaba.fastjson.serializer;
import java.util.List;
public class FilterUtils {
public static char writeBefore(JSONSerializer serializer, Object object, char seperator) {
List<BeforeFilter> beforeFilters = serializer.getBeforeFilters();
if (beforeFilters != null) {
for (BeforeFilter beforeFilter : beforeFilters) {
seperator = beforeFilter.writeBefore(serializer, object, seperator);
}
}
return seperator;
}
public static Object processValue(JSONSerializer serializer, Object object, String key, Object propertyValue) {
List<ValueFilter> valueFilters = serializer.getValueFiltersDirect();
if (valueFilters != null) {
@@ -48,6 +48,7 @@ public class JSONSerializer {
private final SerializeWriter out;
private List<BeforeFilter> beforeFilters = null;
private List<PropertyFilter> propertyFilters = null;
private List<ValueFilter> valueFilters = null;
private List<NameFilter> nameFilters = null;
@@ -251,6 +252,18 @@ public class JSONSerializer {
out.write(indent);
}
}
public List<BeforeFilter> getBeforeFilters() {
if (beforeFilters == null) {
beforeFilters = new ArrayList<BeforeFilter>();
}
return beforeFilters;
}
public List<BeforeFilter> getBeforeFiltersDirect() {
return beforeFilters;
}
public List<NameFilter> getNameFilters() {
if (nameFilters == null) {
@@ -349,6 +362,14 @@ public class JSONSerializer {
public final void writeWithFieldName(Object object, Object fieldName) {
writeWithFieldName(object, fieldName, null);
}
protected final void writeKeyValue(char seperator, String key, Object value) {
if (seperator != '\0') {
out.write(seperator);
}
out.writeFieldName(key);
write(value);
}
public final void writeWithFieldName(Object object, Object fieldName, Type fieldType) {
try {
@@ -128,6 +128,11 @@ public class JavaBeanSerializer implements ObjectSerializer {
commaFlag = true;
}
}
char seperator = commaFlag ? ',':'\0';
char newSeperator = FilterUtils.writeBefore(serializer, object, seperator);
commaFlag = newSeperator == ',';
for (int i = 0; i < getters.length; ++i) {
FieldSerializer fieldSerializer = getters[i];
@@ -18,7 +18,6 @@ package com.alibaba.fastjson.serializer;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -0,0 +1,37 @@
package com.alibaba.json.bvt.serializer;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.BeforeFilter;
public class BeforeFilterTest extends TestCase {
public void test_beforeFilter() throws Exception {
BeforeFilter filter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
this.writeKeyValue("id", 123);
}
};
Assert.assertEquals("{\"id\":123}",JSON.toJSONString( new VO(), filter));
}
public void test_beforeFilter2() throws Exception {
BeforeFilter filter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
this.writeKeyValue("id", 123);
this.writeKeyValue("name", "wenshao");
}
};
Assert.assertEquals("{\"id\":123,\"name\":\"wenshao\"}", JSON.toJSONString(new VO(), filter));
}
private static class VO {
}
}
@@ -0,0 +1,37 @@
package com.alibaba.json.bvt.serializer;
import junit.framework.TestCase;
import org.junit.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.BeforeFilter;
public class BeforeFilterTest2 extends TestCase {
public void test_beforeFilter() throws Exception {
BeforeFilter filter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
this.writeKeyValue("id", 123);
}
};
Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123}");
}
public void test_beforeFilter2() throws Exception {
BeforeFilter filter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
this.writeKeyValue("id", 123);
this.writeKeyValue("name", "wenshao");
}
};
Assert.assertEquals(JSON.toJSONString(new VO(), filter), "{\"id\":123,\"name\":\"wenshao\"}");
}
public static class VO {
}
}