blob: 809732a98d562b80ac1a46d91fe5fac3ee305dd7 [file] [log] [blame]
/**
* 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;
}
}