[hibernate-commits] Hibernate SVN: r10480 - in trunk/HibernateExt/tools/src: java/org/hibernate/tool/hbm2x templates/hbm test/org/hibernate/tool/hbm2x/hbm2hbmxml
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Sep 13 07:45:27 EDT 2006
Author: max.andersen at jboss.com
Date: 2006-09-13 07:45:12 -0400 (Wed, 13 Sep 2006)
New Revision: 10480
Added:
trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/DAONewExporter.java
trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Aliens.hbm.xml
trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/InheritanceTest.java
Modified:
trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/Cfg2HbmTool.java
trunk/HibernateExt/tools/src/templates/hbm/persistentclass.hbm.ftl
Log:
HBX-754 hbm2hbmxml generates xml for subclasses that doesn't validate under the dtd
Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/Cfg2HbmTool.java
===================================================================
--- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/Cfg2HbmTool.java 2006-09-13 09:42:33 UTC (rev 10479)
+++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/Cfg2HbmTool.java 2006-09-13 11:45:12 UTC (rev 10480)
@@ -19,12 +19,21 @@
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.JoinedSubclass;
import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.PersistentClassVisitor;
import org.hibernate.mapping.Property;
+import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.UnionSubclass;
import org.hibernate.mapping.Value;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
import org.hibernate.tool.hbm2x.visitor.HBMTagForPersistentClassVisitor;
import org.hibernate.tool.hbm2x.visitor.HBMTagForValueVisitor;
@@ -33,6 +42,38 @@
*/
public class Cfg2HbmTool {
+ private final class HasEntityPersisterVisitor implements PersistentClassVisitor {
+ private final String name;
+
+ private HasEntityPersisterVisitor(String name) {
+ this.name = name;
+ }
+
+ public Object accept(Subclass subclass) {
+ return bool(!SingleTableEntityPersister.class.getName().equals(name));
+ }
+
+ private Object bool(boolean b) {
+ return Boolean.valueOf( b );
+ }
+
+ public Object accept(JoinedSubclass subclass) {
+ return bool(!JoinedSubclassEntityPersister.class.getName().equals(name));
+ }
+
+ public Object accept(SingleTableSubclass subclass) {
+ return bool(!SingleTableEntityPersister.class.getName().equals(name));
+ }
+
+ public Object accept(UnionSubclass subclass) {
+ return bool(!UnionSubclassEntityPersister.class.getName().equals(name));
+ }
+
+ public Object accept(RootClass class1) {
+ return bool(!SingleTableEntityPersister.class.getName().equals(name));
+ }
+ }
+
public String getTag(PersistentClass pc) {
return (String) pc.accept(HBMTagForPersistentClassVisitor.INSTANCE);
}
@@ -276,4 +317,33 @@
public boolean isImportData(Configuration cfg) {
return !(cfg.getImports().isEmpty());
}
+
+ public boolean needsDiscriminator(PersistentClass clazz) {
+
+ return clazz instanceof Subclass
+ && !(clazz instanceof UnionSubclass) && !(clazz instanceof JoinedSubclass);
+ }
+
+
+ public boolean needsTable(PersistentClass clazz) {
+ return !(clazz instanceof org.hibernate.mapping.Subclass
+ && clazz instanceof org.hibernate.mapping.SingleTableSubclass);
+ }
+
+ public boolean isSubclass(PersistentClass clazz) {
+ return clazz instanceof org.hibernate.mapping.Subclass;
+ }
+
+ public boolean isJoinedSubclass(PersistentClass clazz) {
+ return clazz instanceof JoinedSubclass;
+ }
+
+ public boolean hasCustomEntityPersister(PersistentClass clazz) {
+ Class entityPersisterClass = clazz.getEntityPersisterClass();
+ if(entityPersisterClass==null) return false;
+ final String name = entityPersisterClass.getName();
+
+ Boolean object = (Boolean) clazz.accept( new HasEntityPersisterVisitor( name ) );
+ return object.booleanValue();
+ }
}
Added: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/DAONewExporter.java
===================================================================
--- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/DAONewExporter.java 2006-09-13 09:42:33 UTC (rev 10479)
+++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/DAONewExporter.java 2006-09-13 11:45:12 UTC (rev 10480)
@@ -0,0 +1,125 @@
+package org.hibernate.tool.hbm2x;
+
+import java.io.File;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.hbm2x.GenericExporter;
+import org.hibernate.tool.hbm2x.pojo.POJOClass;
+
+/**
+ * Creates domain model abstract base classes from .hbm files
+ * @author Alex Kalinovsky
+ */
+public class DAONewExporter extends GenericExporter {
+
+ // Store file pattern because it's declared private in GenericTemplateExporter
+ protected String filePattern;
+
+ public DAONewExporter(Configuration cfg, File outputdir)
+ {
+ super(cfg, outputdir);
+ }
+
+ public DAONewExporter()
+ {
+ }
+
+ protected void setupContext()
+ {
+ if(!getProperties().containsKey("ejb3"))
+ getProperties().put("ejb3", "false");
+ if(!getProperties().containsKey("jdk5"))
+ getProperties().put("jdk5", "false");
+
+ initFilePattern();
+ setTemplateName(getProperty("hibernatetool.template_name"));
+
+ super.setupContext();
+ }
+
+ private void initFilePattern() {
+ filePattern = getProperty("hibernatetool.file_pattern");
+ if (filePattern == null)
+ throw new IllegalStateException("Expected parameter file_pattern is not found");
+ filePattern = replaceParameters(filePattern, getProperties());
+ setFilePattern(filePattern);
+ log.debug("File pattern set to " + filePattern);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////// USEFUL CODE STARTS HERE //////////////////////////////////////
+ /**
+ * Helper method to lookup a property
+ */
+ public String getProperty(String key)
+ {
+ return (String) getProperties().get(key);
+ }
+
+ /**
+ * Override to control file overwriting via isOverrite() method
+ */
+ public void doStart()
+ {
+ boolean doExport = true;
+ if(filePattern != null && filePattern.indexOf("{class-name}") == -1)
+ {
+ File file = new File(getOutputDirectory(), filePattern);
+ if (file.exists() && !isOverwrite()) {
+ log.warn("Skipping the generation of file " + file + " because target already exists");
+ doExport = false;
+ }
+ }
+ if (doExport) {
+ super.doStart();
+ }
+ }
+
+ /**
+ * Override to avoid overwriting the existing files
+ * In the final version this should be moved to GenericExporter
+ */
+ protected void exportPOJO(Map additionalContext, POJOClass element)
+ {
+ String filename = resolveFilename(element);
+ File file = new File(getOutputDirectory(), filename);
+ if (file.exists() && !isOverwrite()) {
+ log.warn("Skipping the generation of file " + file + " because target already exists");
+ }
+ else {
+ super.exportPOJO(additionalContext, element);
+ }
+ }
+
+ /**
+ * Checks if the file overwriting is true (default) or false
+ * @return
+ */
+ public boolean isOverwrite() {
+ return "true".equalsIgnoreCase((String) getProperties().get("hibernatetool.overwrite"));
+ }
+
+ /**
+ * Helper method that replaces all parameters in a given pattern
+ * @param pattern String with parameters surrounded with braces, for instance "Today is {day} day of {month}"
+ * @param paramValues map with key-value pairs for parameter values
+ * @return string where parameters are replaced with their values
+ */
+ public String replaceParameters(String pattern, Map paramValues) {
+ Matcher matcher = Pattern.compile("\\{(.*?)\\}").matcher(pattern);
+ String output = pattern;
+ while (matcher.find()) {
+ String param = matcher.group(1);
+ String value = (String) paramValues.get(param);
+ if (value != null) {
+ value = value.replace('.', '/');
+ output = output.replaceAll("\\{" + param + "\\}", value);
+ }
+ }
+ return output;
+ }
+
+}
Modified: trunk/HibernateExt/tools/src/templates/hbm/persistentclass.hbm.ftl
===================================================================
--- trunk/HibernateExt/tools/src/templates/hbm/persistentclass.hbm.ftl 2006-09-13 09:42:33 UTC (rev 10479)
+++ trunk/HibernateExt/tools/src/templates/hbm/persistentclass.hbm.ftl 2006-09-13 11:45:12 UTC (rev 10480)
@@ -6,7 +6,9 @@
<#if clazz.superclass?exists>
extends="${clazz.getSuperclass().className}"
</#if>
+<#if c2h.needsTable(clazz)>
table="${clazz.table.quotedName}"
+</#if>
<#if clazz.table.schema?exists>
schema="${clazz.table.quotedSchema}"
</#if>
@@ -25,7 +27,7 @@
<#if clazz.hasSelectBeforeUpdate()>
select-before-update="true"
</#if>
-<#if !c2h.getClassName(clazz).equals(clazz.discriminatorValue)>
+<#if c2h.needsDiscriminator(clazz)>
discriminator-value="${clazz.discriminatorValue}"
</#if>
<#if clazz.isExplicitPolymorphism()>
@@ -51,7 +53,7 @@
<#if clazz.table.subselect>
subselect="${clazz.table.getSubselect()}"
</#if>
-<#if clazz.getEntityPersisterClass()?exists>
+<#if c2h.hasCustomEntityPersister(clazz)>
persister="${clazz.getEntityPersisterClass().name}"
</#if>
<#if clazz.table.rowId?exists>
@@ -61,12 +63,20 @@
<comment>${clazz.table.comment}</comment>
</#if>
<#-- TODO: move this to id.hbm.ftl -->
-<#if clazz.hasIdentifierProperty()>
-<#assign property=clazz.getIdentifierProperty()/>
-<#include "id.hbm.ftl"/>
-<#elseif clazz.hasEmbeddedIdentifier()>
-<#assign embeddedid=clazz.key/>
-<#include "id.hbm.ftl"/>
+<#if !c2h.isSubclass(clazz)>
+ <#if clazz.hasIdentifierProperty()>
+ <#assign property=clazz.getIdentifierProperty()/>
+ <#include "id.hbm.ftl"/>
+ <#elseif clazz.hasEmbeddedIdentifier()>
+ <#assign embeddedid=clazz.key/>
+ <#include "id.hbm.ftl"/>
+ </#if>
+<#elseif c2h.isJoinedSubclass(clazz)>
+ <key>
+ <#foreach column in clazz.key.columnIterator>
+ <#include "column.hbm.ftl">
+ </#foreach>
+ </key>
</#if>
<#-- version has to be done explicitly since Annotation's does not list version first -->
@@ -81,4 +91,4 @@
</#if>
</#foreach>
-</${c2h.getTag(clazz)}>
\ No newline at end of file
+</${c2h.getTag(clazz)}>
Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Aliens.hbm.xml
===================================================================
--- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Aliens.hbm.xml 2006-09-13 09:42:33 UTC (rev 10479)
+++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/Aliens.hbm.xml 2006-09-13 11:45:12 UTC (rev 10480)
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+
+ This mapping demonstrates how to map a many-to-many
+ association with a shared attribute in the primary keys
+ of the associated entities.
+
+-->
+
+<hibernate-mapping
+ package="org.hibernate.tool.hbm2x.hbm2hbmxml">
+
+ <class name="Animal">
+ <id name="id" type="long">
+ <generator class="assigned"/>
+ </id>
+ <property name="legs" type="int"/>
+ </class>
+
+ <subclass name="Human" extends="Animal">
+ <property name="name" type="string"/>
+ </subclass>
+
+ <joined-subclass name="Alien" extends="Animal">
+ <key column="aid"/>
+ <property name="planet" type="string"/>
+ </joined-subclass>
+
+</hibernate-mapping>
Added: trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/InheritanceTest.java
===================================================================
--- trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/InheritanceTest.java 2006-09-13 09:42:33 UTC (rev 10479)
+++ trunk/HibernateExt/tools/src/test/org/hibernate/tool/hbm2x/hbm2hbmxml/InheritanceTest.java 2006-09-13 11:45:12 UTC (rev 10480)
@@ -0,0 +1,99 @@
+//$Id$
+
+/*
+ * Tests for generating the HBM documents from the Configuration data structure.
+ * The generated XML document will be validated and queried to make sure the
+ * basic structure is correct in each test.
+ */
+package org.hibernate.tool.hbm2x.hbm2hbmxml;
+
+import java.io.File;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.XPath;
+import org.dom4j.io.SAXReader;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.tool.NonReflectiveTestCase;
+import org.hibernate.tool.hbm2x.Exporter;
+import org.hibernate.tool.hbm2x.HibernateMappingExporter;
+import org.hibernate.util.DTDEntityResolver;
+
+/**
+ * this test should be fixed to have a proper model. currently a mix of subclass/joinedsubclass is in play.
+ * @author max
+ *
+ */
+public class InheritanceTest extends NonReflectiveTestCase {
+
+ private Exporter hbmexporter;
+
+ public InheritanceTest(String name) {
+ super( name );
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ hbmexporter = new HibernateMappingExporter(getCfg(), getOutputDir() );
+ hbmexporter.start();
+ }
+
+ public void testAllFilesExistence() {
+
+ assertFalse(new File(getOutputDir().getAbsolutePath() + "/GeneralHbmSettings.hbm.xml").exists() );
+ assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Human.hbm.xml") );
+ assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Alien.hbm.xml") );
+ assertFileAndExists(new File(getOutputDir().getAbsolutePath() + "/org/hibernate/tool/hbm2x/hbm2hbmxml/Animal.hbm.xml") );
+ }
+
+ public void testArtifactCollection() {
+
+ assertEquals(3,hbmexporter.getArtifactCollector().getFileCount("hbm.xml"));
+
+ }
+
+ public void testReadable() {
+ Configuration cfg = new Configuration();
+
+ cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "Alien.hbm.xml"));
+ cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "Human.hbm.xml"));
+ cfg.addFile(new File(getOutputDir(), getBaseForMappings() + "Animal.hbm.xml"));
+
+ cfg.buildMappings();
+
+ }
+
+
+ private SAXReader getSAXReader() {
+ SAXReader xmlReader = new SAXReader();
+ xmlReader.setEntityResolver(new DTDEntityResolver() );
+ xmlReader.setValidation(true);
+ return xmlReader;
+ }
+
+ protected String getBaseForMappings() {
+ return "org/hibernate/tool/hbm2x/hbm2hbmxml/";
+ }
+
+ protected String[] getMappings() {
+ return new String[] {
+ "Aliens.hbm.xml"
+ };
+ }
+
+ public static Test suite() {
+ return new TestSuite(InheritanceTest.class);
+ }
+
+ protected void tearDown() throws Exception {
+ // TODO Auto-generated method stub
+ // super.tearDown();
+ }
+}
More information about the hibernate-commits
mailing list