[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