From c2e30fc248a6c9e8f42367aa385b5bcab01dbeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Sat, 9 Oct 2010 20:52:46 +0000 Subject: [PATCH] #656847 : added support for embedded types --- .../hibernate/HibernateDomainExporter.java | 43 +++++++++++++------ .../HibernateDomainExporterTest.java | 26 ++++++++--- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDomainExporter.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDomainExporter.java index c70059548..6a93bb07e 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDomainExporter.java +++ b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDomainExporter.java @@ -48,14 +48,14 @@ import com.sun.xml.internal.ws.util.StringUtils; */ public class HibernateDomainExporter { - // TODO : support embeddables properly - private static final Logger logger = LoggerFactory.getLogger(HibernateDomainExporter.class); private static final List propertyFields = Arrays.asList( "property","dynamic-component","properties","any","map","set","list","bag","idbag","array","primitive-array"); - private static final List entityFields = Arrays.asList("component","many-to-one","one-to-one"); + private static final List entityFields = Arrays.asList("many-to-one","one-to-one"); + + private static final List embeddableFields = Arrays.asList("component"); private final XMLInputFactory inFactory = XMLInputFactory.newInstance(); @@ -153,7 +153,7 @@ public class HibernateDomainExporter { try{ String packageName = null; Stack types = new Stack(); - Class cl = null; + Stack> classes = new Stack>(); while (true) { int event = reader.next(); if (event == START_ELEMENT) { @@ -163,32 +163,43 @@ public class HibernateDomainExporter { }else if (name.endsWith("class")){ String className = reader.getAttributeValue(null, "name"); - cl = Class.forName(packageName == null ? className : packageName + "." + className); + classes.push(Class.forName(packageName == null ? className : packageName + "." + className)); if (name.equals("mapped-superclass")){ - types.push(createSuperType(cl)); + types.push(createSuperType(classes.peek())); }else{ - types.push(createEntityType(cl)); + types.push(createEntityType(classes.peek())); } }else if (propertyFields.contains(name)){ String propertyName = reader.getAttributeValue(null, "name"); - Type propertyType = getType(cl, propertyName); - Map,Annotation> annotations = getAnnotations(cl, propertyName); + Type propertyType = getType(classes.peek(), propertyName); + Map,Annotation> annotations = getAnnotations(classes.peek(), propertyName); Property property = createProperty(types.peek(), propertyName, propertyType, annotations); types.peek().addProperty(property); }else if (entityFields.contains(name)){ String propertyName = reader.getAttributeValue(null, "name"); - Type propertyType = getType(cl, propertyName); - propertyType = createEntityType(Class.forName(propertyType.getFullName())); - Map,Annotation> annotations = getAnnotations(cl, propertyName); + Type propertyType = createEntityType(Class.forName(getType(classes.peek(), propertyName).getFullName())); + Map,Annotation> annotations = getAnnotations(classes.peek(), propertyName); Property property = createProperty(types.peek(), propertyName, propertyType, annotations); types.peek().addProperty(property); - } + + }else if (embeddableFields.contains(name)){ + String propertyName = reader.getAttributeValue(null, "name"); + Class clazz = Class.forName(getType(classes.peek(), propertyName).getFullName()); + EntityType propertyType = createEmbeddableType(clazz); + Map,Annotation> annotations = getAnnotations(classes.peek(), propertyName); + Property property = createProperty(types.peek(), propertyName, propertyType, annotations); + types.peek().addProperty(property); + types.push(propertyType); + classes.push(clazz); + } + }else if (event == END_ELEMENT){ String name = reader.getLocalName(); - if (name.equals("class") || name.endsWith("subclass")){ + if (name.endsWith("class") || embeddableFields.contains(name)){ types.pop(); + classes.pop(); } } else if (event == END_DOCUMENT) { break; @@ -216,6 +227,10 @@ public class HibernateDomainExporter { private EntityType createEntityType(Class cl) { return createEntityType(cl, entityTypes); } + + private EntityType createEmbeddableType(Class cl) { + return createEntityType(cl, embeddableTypes); + } private EntityType createEntityType(Class cl, Map types) { if (types.containsKey(cl.getName())){ diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/hibernate/HibernateDomainExporterTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/hibernate/HibernateDomainExporterTest.java index e8ce0625e..7ff0d07d5 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/hibernate/HibernateDomainExporterTest.java +++ b/querydsl-jpa/src/test/java/com/mysema/query/jpa/hibernate/HibernateDomainExporterTest.java @@ -12,6 +12,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; import javax.persistence.Transient; @@ -26,8 +27,6 @@ import com.mysema.query.codegen.SimpleSerializerConfig; import com.mysema.query.jpa.domain.Domain; public class HibernateDomainExporterTest { - - // TODO : support embeddables properly private SerializerConfig serializerConfig = SimpleSerializerConfig.getConfig(Domain.class.getPackage().getAnnotation(Config.class)); @@ -97,12 +96,17 @@ public class HibernateDomainExporterTest { for (Field field : cl.getDeclaredFields()){ if (field.getAnnotation(Transient.class) != null) continue; if (Modifier.isTransient(field.getModifiers())) continue; - String propertyElement = "property"; - if (field.getType().getAnnotation(Entity.class) != null){ - propertyElement = "many-to-one"; - } + String propertyElement = getPropertyElement(field.getType()); writer.begin(propertyElement); writer.attribute("name", field.getName()); + if (field.getType().getAnnotation(Embeddable.class) != null){ + for (Field cfield : field.getType().getDeclaredFields()){ + String cproperty = getPropertyElement(cfield.getType()); + writer.begin(cproperty); + writer.attribute("name", cfield.getName()); + writer.end(cproperty); + } + } writer.end(propertyElement); } writer.end(classElement); @@ -111,6 +115,16 @@ public class HibernateDomainExporterTest { w.close(); } + private String getPropertyElement(Class cl){ + if (cl.getAnnotation(Entity.class) != null){ + return "many-to-one"; + }else if (cl.getAnnotation(Embeddable.class) != null){ + return "component"; + }else{ + return "property"; + } + } + private static void assertContains(File file, String... strings) throws IOException{ assertTrue(file.getPath() + " doesn't exist", file.exists()); String result = FileUtils.readFileToString(file, "UTF-8");