HHH-4711 HHH-4667 validate persistence.xml and make sure it works for both persistence_1_0.xsd and persistence_2_0.xsd

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18259 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2009-12-17 15:34:04 +00:00
parent 3bb271ee9c
commit fbf7b91d4d
23 changed files with 412 additions and 69 deletions

View File

@ -32,6 +32,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Resolve JPA xsd files locally
*
* @author Emmanuel Bernard
*/
public class EJB3DTDEntityResolver extends DTDEntityResolver {
@ -41,49 +43,38 @@ public class EJB3DTDEntityResolver extends DTDEntityResolver {
boolean resolved = false;
/**
* Persistence.xml has been resolved locally
* @return true if it has
*/
public boolean isResolved() {
return resolved;
}
public InputSource resolveEntity(String publicId, String systemId) {
log.trace("Resolving XML entity {} : {}", publicId, systemId);
InputSource is = super.resolveEntity( publicId, systemId );
if ( is == null ) {
if ( systemId != null ) {
if ( systemId.endsWith( "orm_1_0.xsd" ) ) {
log.debug(
"recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb"
);
String path = "org/hibernate/ejb/" + "orm_1_0.xsd";
InputStream dtdStream = resolveInHibernateNamespace( path );
if ( dtdStream == null ) {
log.debug( "unable to locate [{}] on classpath", systemId );
}
else {
log.debug( "located [{}] in classpath", systemId );
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
resolved = false;
return source;
}
InputStream dtdStream = getStreamFromClasspath( "orm_1_0.xsd" );
final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
if (source != null) return source;
}
else if ( systemId.endsWith( "orm_2_0.xsd" ) ) {
InputStream dtdStream = getStreamFromClasspath( "orm_2_0.xsd" );
final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
if (source != null) return source;
}
else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
log.debug(
"recognized EJB3 ORM namespace; attempting to resolve on classpath under org/hibernate/ejb"
);
String path = "org/hibernate/ejb/" + "persistence_1_0.xsd";
InputStream dtdStream = resolveInHibernateNamespace( path );
if ( dtdStream == null ) {
log.debug( "unable to locate [{}] on classpath", systemId );
}
else {
log.debug( "located [{}] in classpath", systemId );
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
resolved = true;
return source;
}
InputStream dtdStream = getStreamFromClasspath( "persistence_1_0.xsd" );
final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
if (source != null) return source;
}
else if ( systemId.endsWith( "persistence_2_0.xsd" ) ) {
InputStream dtdStream = getStreamFromClasspath( "persistence_2_0.xsd" );
final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
if (source != null) return source;
}
}
}
@ -94,4 +85,28 @@ public class EJB3DTDEntityResolver extends DTDEntityResolver {
//use the default behavior
return null;
}
private InputSource buildInputSource(String publicId, String systemId, InputStream dtdStream, boolean resolved) {
if ( dtdStream == null ) {
log.trace( "unable to locate [{}] on classpath", systemId );
return null;
}
else {
log.trace( "located [{}] in classpath", systemId );
InputSource source = new InputSource( dtdStream );
source.setPublicId( publicId );
source.setSystemId( systemId );
this.resolved = resolved;
return source;
}
}
private InputStream getStreamFromClasspath(String fileName) {
log.trace(
"recognized JPA ORM namespace; attempting to resolve on classpath under org/hibernate/ejb"
);
String path = "org/hibernate/ejb/" + fileName;
InputStream dtdStream = resolveInHibernateNamespace( path );
return dtdStream;
}
}

View File

@ -45,6 +45,10 @@
<param name="extension" value="par"/>
<param name="jarname" value="defaultpar"/>
</antcall>
<antcall target="packjar" inheritall="true">
<param name="extension" value="par"/>
<param name="jarname" value="defaultpar_1_0"/>
</antcall>
<antcall target="packjar" inheritall="true">
<param name="extension" value="par"/>
<param name="jarname" value="space par"/>

View File

@ -181,6 +181,7 @@
<additionalClasspathElements>
<additionalClasspathElement>${basedir}/target/test-packages/cfgxmlpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/defaultpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/defaultpar_1_0.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/excludehbmpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explicitpar.par</additionalClasspathElement>
<additionalClasspathElement>${basedir}/target/test-packages/explodedpar.par</additionalClasspathElement>

View File

@ -84,19 +84,54 @@ public final class PersistenceXmlLoader {
final Validator v2Validator = v2Schema.newValidator();
final Schema v1Schema = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI )
.newSchema( new StreamSource( getStreamFromClasspath( "persistence_1_0.xsd" ) ) );
final Validator v1Validator = v2Schema.newValidator();
final Validator v1Validator = v1Schema.newValidator();
InputSource source = new InputSource( is );
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.setEntityResolver( resolver );
Document doc = docBuilder.parse( source );
List<SAXParseException> errors = new ArrayList<SAXParseException>();
Document doc = null;
try {
doc = docBuilder.parse( source );
}
catch ( SAXParseException e ) {
errors.add( e );
}
List errors = new ArrayList();
v2Validator.setErrorHandler( new ErrorLogger( "XML InputStream", errors, resolver ) );
v2Validator.validate( new DOMSource( doc ) );
if (errors.size() == 0) {
v2Validator.setErrorHandler( new ErrorLogger( "XML InputStream", errors, resolver ) );
log.trace("Validate with persistence_2_0.xsd schema on file {}", configURL);
v2Validator.validate( new DOMSource( doc ) );
boolean isV1Schema = false;
if ( errors.size() != 0 ) {
//v2 fails, it could be because the file is v1.
log.trace("Found error with persistence_2_0.xsd schema on file {}", configURL);
SAXParseException exception = errors.get( 0 );
final String errorMessage = exception.getMessage();
isV1Schema = errorMessage.contains("1.0")
&& errorMessage.contains("2.0")
&& errorMessage.contains("version");
}
if (isV1Schema) {
log.trace("Validate with persistence_1_0.xsd schema on file {}", configURL);
errors.clear();
v1Validator.setErrorHandler( new ErrorLogger( "XML InputStream", errors, resolver ) );
v1Validator.validate( new DOMSource( doc ) );
}
}
if ( errors.size() != 0 ) {
throw new PersistenceException( "Invlid persistence.xml. Check the error logs for parsing errors", (Throwable) errors.get( 0 ) );
StringBuilder errorMessage = new StringBuilder( );
for (SAXParseException error : errors) {
errorMessage.append("Error parsing XML (line")
.append(error.getLineNumber())
.append(" : column ")
.append(error.getColumnNumber())
.append("): ")
.append(error.getMessage())
.append("\n");
}
throw new PersistenceException( "Invalid persistence.xml.\n" + errorMessage.toString() );
}
return doc;
}
@ -289,30 +324,14 @@ public final class PersistenceXmlLoader {
// if ( resolver instanceof EJB3DTDEntityResolver ) {
// if ( ( (EJB3DTDEntityResolver) resolver ).isResolved() == false ) return;
// }
log.error( "Error parsing XML (line {}: column {}): {}",
new Object[] {
error.getLineNumber(),
error.getColumnNumber(),
error.getMessage() } );
errors.add( error );
}
public void fatalError(SAXParseException error) {
log.error( "Error parsing XML (line {}: column {}): {}",
new Object[] {
error.getLineNumber(),
error.getColumnNumber(),
error.getMessage() } );
errors.add( error );
}
public void warning(SAXParseException warn) {
log.warn( "Warning parsing XML (line {}: column {}): {}",
new Object[] {
warn.getLineNumber(),
warn.getColumnNumber(),
warn.getMessage() } );
}
}

View File

@ -2,10 +2,11 @@
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="defaultpar">
<class>org.hibernate.ejb.test.pack.defaultpar.Lighter</class>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="hibernate.dialect" value="${db.dialect}"/>
<property name="hibernate.connection.driver_class" value="${jdbc.driver}"/>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
version="1.0"
>
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="org.hibernate.ejb.test.pack.defaultpar_1_0.IncrementListener1">
<pre-persist method-name="increment"/>
</entity-listener>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
<package>org.hibernate.ejb.test.pack.defaultpar_1_0</package>
<entity class="org.hibernate.ejb.test.pack.defaultpar_1_0.Lighter1" access="FIELD" metadata-complete="true">
<attributes>
<id name="name">
<column name="fld_id"/>
</id>
<basic name="power"></basic>
</attributes>
</entity>
<entity class="org.hibernate.ejb.test.pack.defaultpar_1_0.ApplicationServer1">
<entity-listeners>
<entity-listener class="OtherIncrementListener1">
<pre-persist method-name="increment"/>
</entity-listener>
</entity-listeners>
</entity>
</entity-mappings>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="defaultpar_1_0">
<class>org.hibernate.ejb.test.pack.defaultpar.Lighter</class>
<properties>
<property name="hibernate.dialect" value="${db.dialect}"/>
<property name="hibernate.connection.driver_class" value="${jdbc.driver}"/>
<property name="hibernate.connection.username" value="${jdbc.user}"/>
<property name="hibernate.connection.password" value="${jdbc.pass}"/>
<property name="hibernate.connection.url" value="${jdbc.url}"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.ejb.test.pack.defaultpar_1_0"
>
<class name="Mouse1">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

View File

@ -2,8 +2,8 @@
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="excludehbmpar" transaction-type="RESOURCE_LOCAL">
<mapping-file>META-INF/orm2.xml</mapping-file>
<properties>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
<jar-file>./target/test-packages/externaljar.jar</jar-file>
<class>org.hibernate.ejb.test.Cat</class>

View File

@ -2,8 +2,8 @@
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="explodedpar" transaction-type="RESOURCE_LOCAL">
<properties>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="overridenpar">
<jta-data-source>java:/unreachableDS</jta-data-source>
<properties>

View File

@ -2,8 +2,8 @@
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="space par">
<properties>
<property name="hibernate.dialect" value="${db.dialect}"/>

View File

@ -2,8 +2,8 @@
<!-- example of a default persistence.xml -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="defaultpar">
<class>org.hibernate.ejb.test.pack.defaultpar.Lighter</class>
<properties>

View File

@ -25,6 +25,10 @@ import org.hibernate.ejb.test.pack.externaljar.Scooter;
import org.hibernate.ejb.test.pack.spacepar.Bug;
import org.hibernate.ejb.test.pack.various.Airplane;
import org.hibernate.ejb.test.pack.various.Seat;
import org.hibernate.ejb.test.pack.defaultpar_1_0.ApplicationServer1;
import org.hibernate.ejb.test.pack.defaultpar_1_0.Version1;
import org.hibernate.ejb.test.pack.defaultpar_1_0.Mouse1;
import org.hibernate.ejb.test.pack.defaultpar_1_0.Lighter1;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventListeners;
import org.hibernate.stat.Statistics;
@ -74,6 +78,36 @@ public class PackagedEntityManagerTest extends TestCase {
emf.close();
}
public void testDefaultParForPersistence_1_0() throws Exception {
EntityManagerFactory emf = Persistence.createEntityManagerFactory( "defaultpar_1_0", new HashMap() );
EntityManager em = emf.createEntityManager();
ApplicationServer1 as = new ApplicationServer1();
as.setName( "JBoss AS" );
Version1 v = new Version1();
v.setMajor( 4 );
v.setMinor( 0 );
v.setMicro( 3 );
as.setVersion( v );
Mouse1 mouse = new Mouse1();
mouse.setName( "mickey" );
em.getTransaction().begin();
em.persist( as );
em.persist( mouse );
assertEquals( 1, em.createNamedQuery( "allMouse_1_0" ).getResultList().size() );
Lighter1 lighter = new Lighter1();
lighter.name = "main";
lighter.power = " 250 W";
em.persist( lighter );
em.flush();
em.remove( lighter );
em.remove( mouse );
assertNotNull( as.getId() );
em.remove( as );
em.getTransaction().commit();
em.close();
emf.close();
}
public void testListenersDefaultPar() throws Exception {
IncrementListener.reset();
OtherIncrementListener.reset();

View File

@ -0,0 +1,42 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Emmanuel Bernard
*/
@Entity
public class ApplicationServer1 {
private Integer id;
private String name;
private Version1 version;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Version1 getVersion() {
return version;
}
public void setVersion(Version1 version) {
this.version = version;
}
}

View File

@ -0,0 +1,24 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import javax.persistence.PrePersist;
/**
* @author Emmanuel Bernard
*/
public class IncrementListener1 {
private static int increment;
public static int getIncrement() {
return increment;
}
public static void reset() {
increment = 0;
}
@PrePersist
public void increment(Object entity) {
increment++;
}
}

View File

@ -0,0 +1,10 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
/**
* @author Emmanuel Bernard
*/
public class Lighter1 {
public String name;
public String power;
}

View File

@ -0,0 +1,24 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
/**
* @author Emmanuel Bernard
*/
@Entity
public class Money1 {
private Integer id;
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

View File

@ -0,0 +1,29 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import javax.persistence.ExcludeDefaultListeners;
/**
* @author Emmanuel Bernard
*/
@ExcludeDefaultListeners
public class Mouse1 {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,21 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
/**
* @author Emmanuel Bernard
*/
public class OtherIncrementListener1 {
private static int increment;
public static int getIncrement() {
return OtherIncrementListener1.increment;
}
public static void reset() {
increment = 0;
}
public void increment(Object entity) {
OtherIncrementListener1.increment++;
}
}

View File

@ -0,0 +1,43 @@
//$Id$
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import javax.persistence.Embeddable;
/**
* @author Emmanuel Bernard
*/
@Embeddable
public class Version1 {
private static final String DOT = ".";
private int major;
private int minor;
private int micro;
public int getMajor() {
return major;
}
public void setMajor(int major) {
this.major = major;
}
public int getMinor() {
return minor;
}
public void setMinor(int minor) {
this.minor = minor;
}
public int getMicro() {
return micro;
}
public void setMicro(int micro) {
this.micro = micro;
}
public String toString() {
return new StringBuffer( major ).append( DOT ).append( minor ).append( DOT ).append( micro ).toString();
}
}

View File

@ -0,0 +1,5 @@
@NamedQuery(name = "allMouse_1_0",
query = "select m from ApplicationServer1 m")
package org.hibernate.ejb.test.pack.defaultpar_1_0;
import org.hibernate.annotations.NamedQuery;