From 7dd862eeb5c046f2ddab5670161530c9a5ac24c0 Mon Sep 17 00:00:00 2001 From: zuchos Date: Mon, 30 Sep 2013 10:01:01 +0200 Subject: [PATCH] HHH-8505: Better test for proxy generator --- .../envers/internal/tools/MapProxyTool.java | 44 +++++++++------ .../internal/tools/ReflectionTools.java | 2 +- .../envers/internal/tools/MapProxyTest.java | 56 +++++++++++++++++-- 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MapProxyTool.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MapProxyTool.java index dd5250b7ce..7fdba67aca 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MapProxyTool.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/MapProxyTool.java @@ -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 propertyDatas. - * 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 map instance that will be proxied by java bean - * @param propertyDatas properties that should java bean declare + * @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 propertyDatas. + * Instance will proxy calls to instance of the map passed as parameter. */ - public static Object newInstanceOfBeanProxyForMap(String name, Map map, Set propertyDatas, ClassLoaderService classLoaderService) { - Class aClass = loadClass(name, classLoaderService); - if (aClass == null) { - Map> properties = prepareProperties(propertyDatas); - aClass = generate(name, properties); - } - return createNewInstance(map, aClass); + public static Object newInstanceOfBeanProxyForMap(String className, Map map, Set propertyDatas, ClassLoaderService classLoaderService) { + Map> properties = prepareProperties(propertyDatas); + return createNewInstance(map, classForName(className, properties, classLoaderService)); } private static Object createNewInstance(Map 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> 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> 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) diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java index 9db7c3a23d..64e0b4dcee 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/internal/tools/ReflectionTools.java @@ -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 key = Pair.make( cls, propertyName ); Setter value = SETTER_CACHE.get( key ); if ( value == null ) { diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/internal/tools/MapProxyTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/internal/tools/MapProxyTest.java index 2dc3552022..3640241ebf 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/internal/tools/MapProxyTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/internal/tools/MapProxyTest.java @@ -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 map = new HashMap(); - map.put("age",14); + int ageExpected = 14; + map.put("age", ageExpected); Map> properties = new HashMap>(); - properties.put("age",Integer.class); - Class testClass = MapProxyTool.generate("TestClass", properties); + properties.put("age", Integer.class); + //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 map = new HashMap(); + Map> properties = new HashMap>(); + 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 map = new HashMap(); + map.put("checkbox",true); + Map> properties = new HashMap>(); + 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)); } }