HHH-8505: Better test for proxy generator

This commit is contained in:
zuchos 2013-09-30 10:01:01 +02:00 committed by adamw
parent f70189f416
commit 7dd862eeb5
3 changed files with 78 additions and 24 deletions

View File

@ -20,22 +20,18 @@ import static org.hibernate.envers.internal.tools.StringTools.getLastComponent;
public class MapProxyTool {
/**
* @author Lukasz Zuchowski (author at zuchos dot com)
* Creates instance of map proxy class. This proxy class will be a java bean with properties from <code>propertyDatas</code>.
* Instance will proxy calls to instance of the map passed as parameter.
* @param name Name of the class to construct (should be unique within class loader)
* @param className Name of the class to construct (should be unique within class loader)
* @param map instance that will be proxied by java bean
* @param propertyDatas properties that should java bean declare
* @param classLoaderService
* @return new instance of proxy
* @author Lukasz Zuchowski (author at zuchos dot com)
* Creates instance of map proxy class. This proxy class will be a java bean with properties from <code>propertyDatas</code>.
* Instance will proxy calls to instance of the map passed as parameter.
*/
public static Object newInstanceOfBeanProxyForMap(String name, Map<String, Object> map, Set<PropertyData> propertyDatas, ClassLoaderService classLoaderService) {
Class aClass = loadClass(name, classLoaderService);
if (aClass == null) {
public static Object newInstanceOfBeanProxyForMap(String className, Map<String, Object> map, Set<PropertyData> propertyDatas, ClassLoaderService classLoaderService) {
Map<String, Class<?>> properties = prepareProperties(propertyDatas);
aClass = generate(name, properties);
}
return createNewInstance(map, aClass);
return createNewInstance(map, classForName(className, properties, classLoaderService));
}
private static Object createNewInstance(Map<String, Object> map, Class aClass) {
@ -63,6 +59,21 @@ public class MapProxyTool {
}
/**
* Generates/loads proxy class for given name with properties for map.
* @param className name of the class that will be generated/loaded
* @param properties list of properties that should be exposed via java bean
* @param classLoaderService
* @return proxy class that wraps map into java bean
*/
public static Class classForName(String className, Map<String,Class<?>> properties, ClassLoaderService classLoaderService) {
Class aClass = loadClass(className, classLoaderService);
if (aClass == null) {
aClass = generate(className, properties);
}
return aClass;
}
/**
* Protected for test only
*/
@ -76,7 +87,6 @@ public class MapProxyTool {
cc.addConstructor(generateConstructor(className, cc));
for (Entry<String, Class<?>> entry : properties.entrySet()) {
cc.addField(new CtField(resolveCtClass(entry.getValue()), entry.getKey(), cc));
// add getter
cc.addMethod(generateGetter(cc, entry.getKey(), entry.getValue()));
@ -103,9 +113,9 @@ public class MapProxyTool {
String getterName = "get" + capitalizeFirst(fieldName);
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
sb.append("public ").append(fieldClass.getName()).append(" ")
.append(getterName).append("(){").append("return (" + fieldClass.getName() + ")this.theMap.get(\"")
.append(getterName).append("(){").append("return (").append(fieldClass.getName()).append(")this.theMap.get(\"")
.append(fieldName).append("\")").append(";").append("}");
return CtMethod.make(sb.toString(), declaringClass);
}
@ -115,7 +125,7 @@ public class MapProxyTool {
String setterName = "set" + capitalizeFirst(fieldName);
StringBuffer sb = new StringBuffer();
StringBuilder sb = new StringBuilder();
sb.append("public void ").append(setterName).append("(")
.append(fieldClass.getName()).append(" ").append(fieldName)
.append(")").append("{").append("this.theMap.put(\"").append(fieldName)

View File

@ -79,7 +79,7 @@ public abstract class ReflectionTools {
return getSetter( cls, propertyData.getBeanName(), propertyData.getAccessType() );
}
private static Setter getSetter(Class cls, String propertyName, String accessorType) {
public static Setter getSetter(Class cls, String propertyName, String accessorType) {
final Pair<Class, String> key = Pair.make( cls, propertyName );
Setter value = SETTER_CACHE.get( key );
if ( value == null ) {

View File

@ -1,6 +1,9 @@
package org.hibernate.envers.internal.tools;
import junit.framework.Assert;
import org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl;
import org.hibernate.property.Getter;
import org.hibernate.property.Setter;
import org.junit.Test;
import java.util.HashMap;
@ -9,15 +12,56 @@ import java.util.Map;
public class MapProxyTest {
@Test
public void testGenerate() throws Exception {
public void shouldGenerateClassWithAppropriateGetter() throws Exception {
//given
Map<String, Object> map = new HashMap<String, Object>();
map.put("age",14);
int ageExpected = 14;
map.put("age", ageExpected);
Map<String, Class<?>> properties = new HashMap<String, Class<?>>();
properties.put("age", Integer.class);
Class testClass = MapProxyTool.generate("TestClass", properties);
//when
Class testClass = MapProxyTool.classForName("TestClass1", properties, new ClassLoaderServiceImpl());
Object testClassInstance = testClass.getConstructor(Map.class).newInstance(map);
//then
Getter getter = ReflectionTools.getGetter(testClass, "age", "property");
Object o = getter.get(testClassInstance);
System.out.println(o);
int age = (Integer) getter.get(testClassInstance);
Assert.assertEquals(ageExpected, age);
}
@Test
public void shouldGenerateClassWithAppropriateSetter() throws Exception {
//given
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Class<?>> properties = new HashMap<String, Class<?>>();
properties.put("age", Integer.class);
//when
Class testClass = MapProxyTool.classForName("TestClass2", properties, new ClassLoaderServiceImpl());
Object testClassInstance = testClass.getConstructor(Map.class).newInstance(map);
//then
Setter setter = ReflectionTools.getSetter(testClass, "age", "property");
int ageExpected = 14;
setter.set(testClassInstance, ageExpected, null);
Object age = map.get("age");
Assert.assertEquals(ageExpected, age);
}
@Test
public void shouldGenerateClassWithAppropriateAccessorsForBoolean() throws Exception {
//given
Map<String, Object> map = new HashMap<String, Object>();
map.put("checkbox",true);
Map<String, Class<?>> properties = new HashMap<String, Class<?>>();
properties.put("checkbox", Boolean.class);
//when
Class testClass = MapProxyTool.classForName("TestClass3", properties, new ClassLoaderServiceImpl());
Object testClassInstance = testClass.getConstructor(Map.class).newInstance(map);
//then
Getter getter = ReflectionTools.getGetter(testClass, "checkbox", "property");
Assert.assertTrue((Boolean) getter.get(testClassInstance));
}
}