Skip to content
Commits on Source (11)
......@@ -43,19 +43,31 @@
<fail unless="password" message="Must define -Dpassword" />
<!-- uploads done using webdav, need to register -->
<!--
<artifact:install-provider artifactId="wagon-webdav" version="1.0-beta-1" />
-->
<echo message="(authenticating as user '${user}')" />
<artifact:remoteRepository id="repo.release"
<!--
url="dav:https://dav.codehaus.org/repository/jackson"
url="https://nexus.codehaus.org/service/local/staging/deploy/maven2/"
url="https://oss.sonatype.org/service/local/staging/deploy/maven2/"
-->
<artifact:remoteRepository id="repo.release"
url="https://oss.sonatype.org/service/local/staging/deploy/maven2/"
>
<authentication username="${user}" password="${password}" />
<releases enabled="true"/>
<snapshots enabled="false"/>
</artifact:remoteRepository>
<artifact:remoteRepository id="repo.snapshot"
<!--
url="dav:https://dav.codehaus.org/snapshots.repository/jackson"
url="https://nexus.codehaus.org/content/repositories/snapshots/"
url="https://oss.sonatype.org/content/repositories/snapshots"
-->
<artifact:remoteRepository id="repo.snapshot"
url="https://oss.sonatype.org/content/repositories/snapshots"
>
<authentication username="${user}" password="${password}" />
<releases enabled="false"/>
......@@ -163,56 +175,96 @@
file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-core-asl-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.asl.mapper" uniqueVersion="false"
file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.lgpl.core" uniqueVersion="false"
file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.lgpl.mapper" uniqueVersion="false"
file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.jaxrs" uniqueVersion="false"
file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.xc" uniqueVersion="false"
file="${dir.dist}/jackson-xc-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-xc-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.smile" uniqueVersion="false"
file="${dir.dist}/jackson-smile-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-smile-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
<artifact:deploy pomRefId="pom.mrbean" uniqueVersion="false"
file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}.jar"
>
<remoteRepository refid="repo.release" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}.jar.asc" type="jar.asc" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}.pom.asc" type="pom.asc" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}-sources.jar" type="jar" classifier="sources" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}-sources.jar.asc" type="jar.asc" classifier="sources" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}-javadoc.jar" type="jar" classifier="javadoc" />
<attach file="${dir.dist}/jackson-mrbean-${IMPL_VERSION}-javadoc.jar.asc" type="jar.asc" classifier="javadoc" />
</artifact:deploy>
</target>
......
......@@ -98,6 +98,7 @@ org.codehaus.jackson.map.deser;version=${IMPL_VERSION},
org.codehaus.jackson.map.deser.impl;version=${IMPL_VERSION},
org.codehaus.jackson.map.deser.std;version=${IMPL_VERSION},
org.codehaus.jackson.map.exc;version=${IMPL_VERSION},
org.codehaus.jackson.map.ext;version=${IMPL_VERSION},
org.codehaus.jackson.map.introspect;version=${IMPL_VERSION},
org.codehaus.jackson.map.jsontype;version=${IMPL_VERSION},
org.codehaus.jackson.map.jsontype.impl;version=${IMPL_VERSION},
......@@ -198,6 +199,7 @@ org.codehaus.jackson.map.deser;version=${IMPL_VERSION},
org.codehaus.jackson.map.deser.impl;version=${IMPL_VERSION},
org.codehaus.jackson.map.deser.std;version=${IMPL_VERSION},
org.codehaus.jackson.map.exc;version=${IMPL_VERSION},
org.codehaus.jackson.map.ext;version=${IMPL_VERSION},
org.codehaus.jackson.map.introspect;version=${IMPL_VERSION},
org.codehaus.jackson.map.jsontype;version=${IMPL_VERSION},
org.codehaus.jackson.map.jsontype.impl;version=${IMPL_VERSION},
......
......@@ -178,6 +178,7 @@ test.run.interop, test.run.jaxrs, test.run.failing, test.run.versions"
<!-- failing tests run during dev, disabled for maintenance versions -->
<target name="test.run.failing" depends="test.compile">
<!--
<junit fork="no" printsummary="yes" haltonfailure="no" showoutput="yes">
<batchtest fork="no" todir="${dir.test.xmlresults}">
<fileset dir="${dir.test.classes}">
......@@ -200,6 +201,7 @@ test.run.interop, test.run.jaxrs, test.run.failing, test.run.versions"
</fileset>
</classpath>
</junit>
-->
</target>
<target name="test.run.versions" depends="test.compile">
......
#!/bin/sh
java -Xmx48m -server -cp build/classes/perf:build/classes/core\
:build/classes/mapper:lib/perf/\* \
-XX:CompileThreshold=2000 \
-Xrunhprof:cpu=samples,depth=10,verbose=n,interval=2 \
TestJsonPerf \
$*
#!/bin/sh
java -Xmx16m -server \
-cp build/classes/perf:perflib/\* \
-XX:CompileThreshold=2000 \
-Xrunhprof:cpu=samples,depth=10,verbose=n,interval=2 \
TestReadPerf $*
#!/bin/sh
java -Xmx48m -server -cp build/classes \
TestCopyPerf $*
#!/bin/sh
java -Xmx48m -server -cp build/classes/perf:build/classes/core\
:build/classes/mapper:lib/perf/\* \
TestJsonPerf \
$*
#!/bin/sh
java -Xmx16m -server \
-cp build/classes/perf:perflib/\* \
TestReadPerf $*
#!/bin/sh
java -Xmx48m -server -cp build/classes/perf:build/classes/core\
:build/classes/mapper:lib/perf/\* \
TestSerPerf \
$*
......@@ -50,7 +50,7 @@
<property name="IMPL_TITLE_SMILE" value="Jackson Binary format (aka Smile) handling functionality" />
<property name="IMPL_TITLE_MRBEAN" value="Jackson Bean Materializer (aka Mr. Bean)" />
<property name="IMPL_VERSION" value="1.9.2" />
<property name="IMPL_VERSION" value="1.9.13" />
<property name="IMPL_VENDOR" value="http://fasterxml.com" />
<patternset id="dist-all-source-files">
......@@ -357,7 +357,7 @@ compile.smile, compile.mrbean" />
<!-- Joda time... -->
<link href="http://joda-time.sourceforge.net/api-release" />
<!-- Regular JDK 6 classes -->
<link href="http://java.sun.com/javase/6/docs/api" />
<link href="http://docs.oracle.com/javase/6/docs/api" />
<!-- And JAX-RS (jsr-311) as well -->
<link href="http://jackson.codehaus.org/javadoc/jax-rs/1.0" />
......@@ -481,9 +481,33 @@ compile.smile, compile.mrbean" />
<jar destfile="${dir.dist}/jackson-core-asl-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}" includes="**/*"
/>
<jar destfile="${dir.dist}/jackson-core-lgpl-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}" includes="**/*"
/>
<jar destfile="${dir.dist}/jackson-mapper-asl-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}" includes="**/*"
/>
<jar destfile="${dir.dist}/jackson-mapper-lgpl-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}" includes="**/*"
/>
<jar destfile="${dir.dist}/jackson-jaxrs-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}"
includes="org/codehaus/jackson/jaxrs/**/*"
/>
<jar destfile="${dir.dist}/jackson-mrbean-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}"
includes="org/codehaus/jackson/mrbean/**/*"
/>
<jar destfile="${dir.dist}/jackson-smile-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}"
includes="org/codehaus/jackson/smile/**/*"
/>
<jar destfile="${dir.dist}/jackson-xc-${IMPL_VERSION}-javadoc.jar"
filesonly="true" compress="true" basedir="${dir.javadoc}">
<include name="org/codehaus/jackson/xc/**" />
<include name="org/codehaus/jackson/xml/**" />
</jar>
<!-- Then copy javadocs -->
<copy todir="${dir.dist}">
......
package org.codehaus.jackson.map.deser;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class BeanHelper implements Opcodes {
public static class BeanBuilder {
protected Map<String, Class> properties = new LinkedHashMap<String, Class>();
protected Map<String, ThrowMethodType> throwMethods = new LinkedHashMap<String, ThrowMethodType>();
protected List<Class> implementing = new ArrayList<Class>();
protected String className;
protected String internalClass;
public BeanBuilder(String className) {
this.className = className;
this.internalClass = getInternalClassName(className);
}
public BeanBuilder implement(Class parent) {
this.implementing.add(parent);
for (Method m : parent.getMethods()) {
if (m.getName().startsWith("get")
|| m.getName().startsWith("set")) {
String name = getFieldName(m.getName());
Class propType = m.getName().startsWith("get") ? m
.getReturnType() : m.getParameterTypes()[0];
if (this.properties.containsKey(name)
&& !this.properties.get(name).equals(propType)) {
throw new IllegalArgumentException("Duplicate property");
}
addProperty(name, propType);
} else {
addThrow(m.getName(), m.getParameterTypes(), m
.getReturnType(),
UnsupportedOperationException.class);
}
}
return this;
}
public BeanBuilder addProperty(String name, Class type) {
properties.put(name, type);
return this;
}
public BeanBuilder addThrow(String name, Class[] paramTypes,
Class returnType, Class exceptionType) {
this.throwMethods.put(name, new ThrowMethodType(name, paramTypes,
returnType, exceptionType));
return this;
}
public Class load() {
ClassWriter cw = new ClassWriter(0);
String[] parents = new String[implementing.size()];
for (int i = 0; i < implementing.size(); i++) {
parents[i] = getInternalClassName(implementing.get(i).getName());
}
cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, internalClass, null,
"java/lang/Object", parents);
cw.visitSource(className + ".java", null);
BeanHelper.generateDefaultConstructor(cw);
for (Map.Entry<String, Class> propEntry : this.properties
.entrySet()) {
String propName = propEntry.getKey();
Class propClass = propEntry.getValue();
BeanHelper.createField(cw, propName, propClass);
BeanHelper.createGetter(cw, internalClass, propName, propClass);
BeanHelper.createSetter(cw, internalClass, propName, propClass);
}
for (Map.Entry<String, ThrowMethodType> throwEntry : this.throwMethods
.entrySet()) {
ThrowMethodType thr = throwEntry.getValue();
BeanHelper.createThrow(cw, this.internalClass, throwEntry
.getKey(), thr.paramTypes, thr.returnType,
thr.exceptionType);
}
cw.visitEnd();
return loadClass(className, cw.toByteArray());
}
}
private static void generateDefaultConstructor(ClassWriter cw) {
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
private static void createField(ClassWriter cw, String fieldName,
Class fieldType) {
String javaType = getLValue(fieldType);
FieldVisitor fv = cw.visitField(0, fieldName, javaType, null, null);
fv.visitEnd();
}
private static void createSetter(ClassWriter cw, String internalClassName,
String fieldName, Class fieldType) {
String methodName = getSetterName(fieldName);
String returnType = getLValue(fieldType);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "("
+ returnType + ")V", null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, internalClassName, fieldName, returnType);
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
private static void createGetter(ClassWriter cw, String internalClassName,
String fieldName, Class fieldType) {
String methodName = getGetterName(fieldName);
String returnType = getLValue(fieldType);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()"
+ returnType, null, null);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, internalClassName, fieldName, returnType);
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
private static void createThrow(ClassWriter cw, String internalClassName,
String methodName, Class[] inTypes, Class returnType,
Class exceptionType) {
String rTypeName = getLValue(returnType);
String exceptionName = getInternalClassName(exceptionType.getName());
String sig = "(" + getArgumentsType(inTypes) + ")" + rTypeName;
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, sig, null,
null);
mv.visitTypeInsn(NEW, exceptionName);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, exceptionName, "<init>", "()V");
mv.visitInsn(ATHROW);
mv.visitMaxs(2, 1 + inTypes.length);
mv.visitEnd();
}
private static Class loadClass(String className, byte[] b) {
// override classDefine (as it is protected) and define the class.
Class clazz = null;
try {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class cls = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method = cls.getDeclaredMethod(
"defineClass", new Class[] { String.class, byte[].class,
int.class, int.class });
// protected method invocaton
method.setAccessible(true);
try {
Object[] args = new Object[] { className, b, new Integer(0),
new Integer(b.length) };
clazz = (Class) method.invoke(loader, args);
} finally {
method.setAccessible(false);
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
return clazz;
}
private static String getInternalClassName(String className) {
return className.replace(".", "/");
}
private static String getFieldName(String getterMethodName) {
char[] name = getterMethodName.substring(3).toCharArray();
name[0] = Character.toLowerCase(name[0]);
final String propName = new String(name);
return propName;
}
private static String getLValue(Class fieldType) {
if (fieldType == null || fieldType.equals(void.class)) {
return "V";
}
String plainR = fieldType.getName();
String rType = getInternalClassName(plainR);
String javaType = "L" + rType + ";";
return javaType;
}
private static String getGetterName(String fieldName) {
return "get" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
}
private static String getSetterName(String fieldName) {
return "set" + fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);
}
private static String getArgumentsType(Class[] inTypes) {
StringBuilder list = new StringBuilder();
for (Class clazz : inTypes) {
list.append(getLValue(clazz));
}
return list.toString();
}
private static class ThrowMethodType {
public final String name;
public final Class[] paramTypes;
public final Class returnType;
public final Class exceptionType;
public ThrowMethodType(String name, Class[] paramTypes,
Class returnType, Class exceptionType) {
this.name = name;
this.paramTypes = paramTypes;
this.returnType = returnType;
this.exceptionType = exceptionType;
}
}
}
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.jackson.map.deser;
import java.lang.reflect.Method;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.DeserializerProvider;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.type.JavaType;
/**
* A very basic Jackson deserializer factory that extends the BeanSerializer
* factory to allow deserialization using interfaces.
*/
public class MaterializingDeserializerFactory extends BeanDeserializerFactory {
public MaterializingDeserializerFactory() {
super();
}
@Override
public JsonDeserializer<Object> createBeanDeserializer(
DeserializationConfig config, JavaType type, DeserializerProvider p)
throws JsonMappingException {
if (type.isInterface()) {
String className = "$org.codehaus.jackson.generated$"
+ type.getRawClass().getName();
BeanHelper.BeanBuilder builder = new BeanHelper.BeanBuilder(
className);
builder.implement(type.getRawClass());
return new BeanDeserializerProxyImpl(TypeFactory.fromClass(builder
.load()));
}
return super.createBeanDeserializer(config, type, p);
}
protected static class BeanDeserializerProxyImpl extends BeanDeserializer {
public BeanDeserializerProxyImpl(JavaType type) {
super(type);
try {
this.setDefaultConstructor(type.getRawClass().getConstructor());
} catch (Exception e) {
throw new RuntimeException(e);
}
try {
populateSetters(type);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
private void populateSetters(JavaType type)
throws NoSuchMethodException {
Class clazz = type.getRawClass();
for (Method m : clazz.getMethods()) {
String methodName = m.getName();
if (methodName.startsWith("set")
&& m.getParameterTypes() != null
&& m.getParameterTypes().length == 1) {
Class fieldClass = m.getParameterTypes()[0];
JavaType fieldType = TypeFactory.fromClass(fieldClass);
Method setterMethod = getSetterMethod(clazz, methodName,
fieldClass);
this.addProperty(new SettableBeanProperty.MethodProperty(
getFieldName(methodName), fieldType,
setterMethod));
}
}
}
private Method getSetterMethod(Class clazz, String methodName,
Class returnType) throws NoSuchMethodException {
return clazz.getMethod("set" + methodName.substring(3), returnType);
}
}
private static String getFieldName(String getterMethodName) {
char[] name = getterMethodName.substring(3).toCharArray();
name[0] = Character.toLowerCase(name[0]);
final String propName = new String(name);
System.out.println(propName);
return propName;
}
}
Work in progress for "materialized interface" extension, contributed by Sunny Gleason.
Exciting stuff, real source at GitHub (see [http://github.com/sunnygleason/g414-jackson]), but temporarily also cached here for convenience.
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.example;
import java.io.StringWriter;
import junit.framework.TestCase;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.deser.MaterializingDeserializerFactory;
import org.codehaus.jackson.map.deser.StdDeserializerProvider;
import com.g414.jackson.proxy.ProxySerializerFactory;
/**
* Exercise the deserializer...
*/
public class TestMaterializingDeserializer extends TestCase {
public void testExample() throws Exception {
ExampleImpl impl = new ExampleImpl();
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializerFactory(new ProxySerializerFactory());
MaterializingDeserializerFactory df = new MaterializingDeserializerFactory();
StdDeserializerProvider dp = new StdDeserializerProvider(df);
mapper.setDeserializerProvider(dp);
// Testing Example1
StringWriter w1 = new StringWriter();
mapper.writeValue(w1, impl.asExample1());
String w1Value = w1.toString();
Example1 w1in = mapper.readValue(w1Value, Example1.class);
assertEquals("4660", w1in.getA().toString());
assertEquals("Foo", w1in.getB().toString());
// Testing Example2 ...
StringWriter w2 = new StringWriter();
mapper.writeValue(w2, impl.asExample2());
String w2Value = w2.toString();
Example2 w2in = mapper.readValue(w2Value, Example2.class);
assertEquals("305419896", w2in.getC().toString());
}
}
This directory contains source code that has been in use at some point,
but not used or needed any more. However, there is a chance that such code
might be useful for some other use later on, and as such it is still retained
in a somewhat visible place (not just SCM system version history).
#!/bin/sh
java -Xmx64m -server \
-cp build/classes/core:build/classes/mapper:build/classes/extra\
:build/classes/smile:build/classes/xc:build/classes/perf\
:lib/xml/\*\
-Xrunhprof:cpu=samples,depth=10,verbose=n,interval=2 \
$*
......@@ -571,6 +571,8 @@ Steven Schlansker:
[1.7.7]
* Reported [JACKSON-572] Problems serializing generic non-static inner classes
[1.7.7]
* Suggested [JACKSON-726] Add java.util.UUID key deserializer
[1.9.3]
Elliot Barlas:
* Reported [JACKSON-491]: Bug in NumberInput.inLongRange, causing false overflows
......@@ -733,19 +735,55 @@ Edward Alexandrov:
"Internal Error"
[1.8.4]
Anand Hatrwalne:
* Requested [JACKSON-558] Add 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE' as
matching counterpart for 'SerializationConfig.Feature.WRAP_ROOT_VALUE'
[1.9.0]
Earl Baugh:
* Suggested [JACKSON-584] Serialize type info for non-static anonymous inner classes
as that of declared (static) type
[1.9.0]
Matt Goldspink:
* Suggested [JACKSON-578] Allow use of @JsonView on JAX-RS resource, with JacksonJsonProvider
[1.9.0]
Paul Marynchev:
* Reported [JACKSON-637] NumberSerializer was missing proper handling of
Integer, Long
[1.8.5]
Ransom Briggs:
* Reported [JACKSON-668] Problems with 'JsonParser.getDecimalValue'
not clearing earlier state
[1.8.6]
William Burns:
* Reported [JACKSON-677], suggested fix for: Inner generic type references
not working properly
[1.8.6]
Tom Boettcher:
* Reported [JACKSON-709] Problems converting base64-encoded Strings
between JsonNode, POJOs
[1.8.7]
Ryan Kennedy:
* Reported [JACKSON-462] (REGRESSION?) Buffer overflow in
Utf8Generator#writeFieldName(String)
[1.8.7]
Jacques-Olivier Goussard:
* Reported [JACKSON-733] Smile-based mapper could not properly bind
byte[] values
[1.8.7]
Alex Temnokhod:
* Reported [JACKSON-738] Parsing fails for Unicode 1Fxxx symbols when
skipping
[1.8.7]
Lloyd Smith:
* Reported [JACKSON-701] ArrayIndexOutOfBoundsException when trying to serialize
non-static inner classes with annotations on last ctor param
[1.8.8]
Erik Gorset:
* Reported [JACKSON-763] State of base64/byte[] decoding not reset when
using 'convertValue()' for list of byte[] values.
[1.8.9]
Matt Schemmel:
* Reported [JACKSON-820] WriterBasedGenerator with CharacterEscapes produces
unescaped output for strings > 2k in length
[1.8.9]
"Programmer Bruce":
* Suggested these for 1.8.x:
......@@ -762,6 +800,20 @@ Matt Goldspink:
- [JACKSON-616] Better handling of primitive deserializers, to avoid NPEs
- [JACKSON-621] Add new fluent method, VisibilityChecker.with(Visibility)
Anand Hatrwalne:
* Requested [JACKSON-558] Add 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE' as
matching counterpart for 'SerializationConfig.Feature.WRAP_ROOT_VALUE'
[1.9.0]
Earl Baugh:
* Suggested [JACKSON-584] Serialize type info for non-static anonymous inner classes
as that of declared (static) type
[1.9.0]
Matt Goldspink:
* Suggested [JACKSON-578] Allow use of @JsonView on JAX-RS resource, with JacksonJsonProvider
[1.9.0]
Ed Anuff:
* Suggested [JACKSON-602] Add 'JsonSerialize.Inclusion.NON_EMPTY' option
[1.9.0]
......@@ -789,3 +841,98 @@ Ben Hale:
* Reported [JACKSON-700] Type problems with properties that have different
types for constructor property, setter and/or field
[1.9.1]
Andreas Knoepfle, Tobias Schmid:
* Contributed implementation for [JACKSON-657], key deserializers for
java.util.Date and java.util.Calendar types
[1.9.3]
Steve Loeppky:
* Reported [JACKSON-746] Problems with JsonTypeInfo.Id.NONE, default typing
[1.9.4]
Sebastian Thelen:
* Reported [JACKSON-753] JsonParserDelegate missing delegation of getBooleanValue(),
getEmbeddedObject()
[1.9.4]
Stephan Bailliez:
* Reported [JACKSON-757] Problems with Enum values, annotations on constructors
[1.9.4]
Mika Mannermaa:
* Reported [JACKSON-756] Problems with enums, @JsonCreator, when used as keys
of EnumMap, regular Map, or contents of EnumSet
[1.9.4]
Nathaniel Bauernfeind:
* Reported [JACKSON-774]: PropertyBasedCreator not using JsonDeserializer.getNullValue()
[1.9.5]
Ittai Zeidman:
* Reported [JACKSON-775]: MissingNode.asText() should return "", not null
[1.9.5]
Alexander Klauer:
* Reported [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments
[1.9.5]
Vladimir Petrukhin:
* Reported [JACKSON-778], provided test case: Incorrect detection of generic
types with TypeReference
[1.9.5]
Christopher Brown:
* Reported [JACKSON-796]: Problems with byte[] conversion to/from JsonNode.
[1.9.5]
Harold Marger:
* Reported [JACKSON-806]: REQUIRE_SETTERS_FOR_GETTERS ignores explicitly annotated getters
[1.9.6]
Adam Vandenberg:
* Reported [JACKSON-823] MissingNode does not return default value for
'asXxx()' methods
[1.9.7]
James Roper:
* Reported [JACKSON-829] Custom serializers not working for List<String>
properties, @JsonSerialize(contentUsing)
[1.9.7]
Laurent Pireyn:
* Reported [JACKSON-831] External type id, explicit property do not work well together
[1.9.7]
* Reported [JACKSON-875]: Enums are not properly serialized when
Feature.USE_ANNOTATIONS is disabled
[1.9.12]
Jan Jan:
* Reported [JACKSON-832] (partial) Fix numeric range check for Longs (was not working)
[1.9.7]
Klaus Reimer:
* [JACKSON-834] Could not use @JsonFactory with non-String argument with Enums
[1.9.7]
Stuart Dootson:
* Reported [Issue-13] Runtime error passing multiple injected values to a constructor
[1.9.7]
Lóránt Pintér:
* Reported [JACKSON-838]: Utf8StreamParser._reportInvalidToken() skips
letters from reported token name
[1.9.8]
Scott Stanton:
* Reported [JACKSON-841] Data is doubled in SegmentedStringWriter output
[1.9.8]
Sébastien R:
* Reported [JACKSON-842] ArrayIndexOutOfBoundsException when skipping C-style comments
[1.9.8]
Duncan Bloem:
* Reported [JACKSON-867] missing Export-Package header for
"org.codehaus.jackson.map.ext"
[1.9.10]
Version: 1.9.2
Version: 1.9.13
Release date: 14-Jul-2013
Release date:
04-Nov-2011
Another patch release for 1.9.
Description:
The second patch release for 1.9.
Fixes:
* [JACKSON-887]: StackOverflow with parameterized sub-class field
(reported by Alexander M)
* [JACKSON-889]: Parsing error in 'nextFieldName()'
* [Issue#182]: Add support for updating values of polymorphic types.
(reported by nssheth@github)
------------------------------------------------------------------------
=== History: ===
------------------------------------------------------------------------
1.9.12 (25-Jan-2013)
* One more case for [JACKSON-802] (class loading using Class.forName())
* [JACKSON-875]: Enums are not properly serialized when
Feature.USE_ANNOTATIONS is disabled
(reported by Laurent P)
* [JACKSON-884]: JsonStringEncoder.quoteAsStringValue() fails to encode
ctrl chars correctly.
* [Issue#38]: Infinite loop in `JsonParser.nextFieldName()` with trailing
space after field name
(reported by matjazs@github)
* [Issue#42]: NPE in UTF-32 parser
(reported by James R)
1.9.11 (06-Nov-2012)
* [Issue#8]: Problem with 'SmileGenerator', addSeenName()
1.9.10 (23-Sep-2012)
* [JACKSON-855]: add StackOverflowError as root cause
* [JACKSON-867]: missing Export-Package header for "org.codehaus.jackson.map.ext"
(reported by Duncan B)
* [Issue#57]: Allow serialization of JDK proxy types
* [Issue#71]: java.util.concurrent.ConcurrentNavigableMap support was failing
1.9.9 (28-Jul-2012)
* [Issue-21]: Improve handling of String hash code collisions for
symbol tables; exception for degenerate cases (attacks), improvements
for calculation otherwise
* [Issue-24]: ArrayIndexOutOfBoundsException with TextBuffer.append()
* [JACKSON-853]: JsonStringEncoder.quoteAsString() problem with buffer boundary
* Improved multi-threader handling of byte-based symbol table; should
reduce lock contention for heavily multi-threaded cases, esp. when
parsing short documents.
1.9.8 (28-Jun-2012)
* [Issue-6]: element count for PrettyPrinter, endObject wrong
(reported by "thebluemountain")
* [JACKSON-838]: Utf8StreamParser._reportInvalidToken() skips letters
from reported token name
(reported by Lóránt Pintér)
* [JACKSON-841] Data is doubled in SegmentedStringWriter output
(reported by Scott S)
* [JACKSON-842] ArrayIndexOutOfBoundsException when skipping C-style comments
(reported by Sebastien R)
* [JACKSON-845] Problem with Object[][] deserialization, default typing
(reported by Pawel J)
1.9.7 (02-May-2012)
* [Smile/Issue-2] SmileParser failed to decode surrogate-pair characters for
long Strings
(reported by Steven S)
* [Issue-11] JsonParser.getValueAsLong() returning int, not long
(reported by Daniel L)
* [Issue-13] Runtime error passing multiple injected values to a constructor
(reported by Stuart D)
* [Issue-14]: Annotations were not included from parent classes of
mix-in classes
(reported by @guillaup)
* [JACKSON-823] MissingNode does not return default value for 'asXxx()'
methods
(reported by Adam V)
* [JACKSON-829] Custom serializers not working for List<String> properties,
@JsonSerialize(contentUsing)
(reported by James R)
* [JACKSON-831] External type id, explicit property do not work well together
(reported by Laurent P)
* [JACKSON-832] (partial) Fix numeric range check for Longs (was not working)
(reported by Jan J)
* [JACKSON-834] Could not use @JsonFactory with non-String argument with Enums
(reported by Klaus R)
1.9.6 [26-Mar-2012]
Fixes:
* [JACKSON-763] State of base64/byte[] decoding not reset when
using 'convertValue()' for list of byte[] values.
(reported by Erik G)
* [JACKSON-794]: JDK 7 has new property for Exceptions ("suppressable"),
needs to be ignored during deserialization
* [JACKSON-799]: JsonSerialize.as not working as class annotation, for root values
* [JACKSON-802]: Improvements to class loading to use both contextual
class loader and Class.forName, as necessary
* [JACKSON-803]: Problems with Smile, parsing of long names
(reported by D Lam)
* [JACKSON-804]: Allow byte range up to 255, for interoperability with unsigned bytes
* [JACKSON-806]: REQUIRE_SETTERS_FOR_GETTERS ignores explicitly annotated getters
(reported by Harold M)
* [JACKSON-812]: BigIntegerNode.equals(...) using '==' for equality
* [JACKSON-820]: WriterBasedGenerator with CharacterEscapes produces unescaped output
for strings > 2k in length
(reported by Matt S)
1.9.5 [24-Feb-2012]
Fixes:
* [JACKSON-757]: further fixing (1.9.4 had partial fix)
* [JACKSON-773]: Bug in SimpleFilterProvider constructor
(reported by Kenny M)
* [JACKSON-774]: PropertyBasedCreator was not using JsonDeserializer.getNullValue()
(reported by Nathaniel B)
* [JACKSON-775]: MissingNode.asText() should return "", not null
(reported by Ittai Z)
* [JACKSON-778]: Incorrect detection of generic types with TypeReference
(reported by Vladimir P)
* [JACKSON-779]: Problems with multi-byte UTF-8 chars in JSON comments
(reported by Alexander K)
* [JACKSON-789]: Add support for 'java.nio.charset.Charset'
* [JACKSON-796]: Problems with byte[] conversion to/from JsonNode.
(reported by Christopher B)
1.9.4 [20-Jan-2012]
Fixes:
* [JACKSON-712] Issue with @JsonCreator + DefaultImpl
(suggested by Eric T)
* [JACKSON-744] @JsonAnySetter problems with 1.9
* [JACKSON-746] Problems with JsonTypeInfo.Id.NONE, default typing
(reported by Steve L)
(reported by Sebastian T)
* [JACKSON-756] Problems with enums, @JsonCreator, when used as keys
of EnumMap, regular Map, or contents of EnumSet
(reported by Mika M)
* [JACKSON-757] Problems with Enum values, annotations on constructors
-- but note, some issues remained for 1.9.5 to tackle
(reported by Stephan B)
(all fixes up to 1.8.8)
1.9.3 [16-Dec-2011]
Improvements:
* [JACKSON-657] Add Date/Calendar key deserializers
(contributed by Andreas K, Tobias S)
* [JACKSON-717] ObjectReader.updateValues(): use configured 'valueToUpdate'
* [JACKSON-726] Add java.util.UUID key deserializer
(suggested by Steven S)
* [JACKSON-729] Add 'ObjectMapper.readValues(byte[])' convenience method
Fixes:
(all fixes up to 1.8.7)
1.9.2 [04-Nov-2011]
Improvements:
......@@ -19,10 +182,6 @@ Description:
* [JACKSON-703] 'SerializationConfig.isEnabled(...)',
'DeserializationConfig.isEnabled(...)' incompatible due to signature change
------------------------------------------------------------------------
=== History: ===
------------------------------------------------------------------------
1.9.1 [23-Oct-2011]
Fixes:
......@@ -154,6 +313,38 @@ Description:
JsonContentClass (deprecated since 1.1)
* Move TokenBufferDeserializer to separate class (from inside StdDeserializer)
1.8.8 [20-Jan-2012]
Fixes:
* [JACKSON-701] ArrayIndexOutOfBoundsException when trying to serialize
non-static inner classes with annotations on last ctor param
(reported Lloyd S)
* [JACKSON-741] Add missing linkage from ObjectMapper to JsonFactory
by calling 'JsonFactory.setCodec()' from ObjectMapper constructor
* [JACKSON-753] JsonParserDelegate missing delegation of getBooleanValue(),
getEmbeddedObject()
(reported by Sebastian T)
* Partial fix for [JACSON-756]: EnumMap, EnumSet work with enums that use
@JsonCreator; regular Maps only with 1.9
(reported by Mika M)
1.8.7 [16-Dec-2011]
Fixes:
* [JACKSON-462] (REGRESSION?) Buffer overflow in Utf8Generator#writeFieldName(String)
(reported by Ryan K)
* [JACKSON-696] Problems accessing "any getter" that is not public
(reported by Brian M)
* [JACKSON-709] Problems converting base64-encoded Strings between
JsonNode, POJOs
(reported by Tom B)
* [JACKSON-733] Smile-based mapper could not properly bind byte[] values
(reported by Jacques-Olivier G)
* [JACKSON-738] Parsing fails for Unicode 1Fxxx symbols when skipping
(reported by Alex T)
1.8.6 [04-Oct-2011]
Fixes:
......
#!/bin/sh
java -Xmx128m -server\
-XX:-PrintGC -XX:-PrintGCDetails \
-cp lib/junit/junit-3.8.1.jar\
:lib/repackaged/\*:lib/xml/\*\
:build/classes/core:build/classes/mapper:build/classes/xc:build/classes/extra\
:build/classes/perf:build/classes/smile \
$*
{
"id":1125687077,
"text":"@stroughtonsmith You need to add a \"Favourites\" tab to TC/iPhone. Like what TwitterFon did. I can't WAIT for your Twitter App!! :) Any ETA?",
"fromUserId":855523,
"toUserId":815309,
"languageCode":"en"
}