[hibernate-commits] Hibernate SVN: r20321 - in core/trunk: core/src/main/java/org/hibernate/util and 8 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Sep 8 14:03:29 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-09-08 14:03:28 -0400 (Wed, 08 Sep 2010)
New Revision: 20321

Added:
   core/trunk/core/src/main/java/org/hibernate/util/xml/
   core/trunk/core/src/main/java/org/hibernate/util/xml/ErrorLogger.java
   core/trunk/core/src/main/java/org/hibernate/util/xml/MappingReader.java
   core/trunk/core/src/main/java/org/hibernate/util/xml/Origin.java
   core/trunk/core/src/main/java/org/hibernate/util/xml/OriginImpl.java
   core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocument.java
   core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocumentImpl.java
   core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/jee/
   core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/jee/OrmVersionTest.java
   core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/
   core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/invalid-orm-1.xml
   core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-1.xml
   core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-2.xml
Modified:
   core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
   core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java
   core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java
   core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/LogHelper.java
   core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml
Log:
HHH-5310 - orm_2_0.xsd compliant mapping files break in JEE use cases


Modified: core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -169,6 +169,11 @@
 import org.hibernate.util.SerializationHelper;
 import org.hibernate.util.StringHelper;
 import org.hibernate.util.XMLHelper;
+import org.hibernate.util.xml.MappingReader;
+import org.hibernate.util.xml.Origin;
+import org.hibernate.util.xml.OriginImpl;
+import org.hibernate.util.xml.XmlDocument;
+import org.hibernate.util.xml.XmlDocumentImpl;
 
 /**
  * An instance of <tt>Configuration</tt> allows the application
@@ -483,7 +488,6 @@
 	 */
 	public Configuration addFile(final File xmlFile) throws MappingException {
 		log.info( "Reading mappings from file: " + xmlFile.getPath() );
-
 		final String name =  xmlFile.getAbsolutePath();
 		final InputSource inputSource;
 		try {
@@ -492,45 +496,28 @@
 		catch ( FileNotFoundException e ) {
 			throw new MappingNotFoundException( "file", xmlFile.toString() );
 		}
-
-		add(
-				new XMLHelper.MetadataXmlSource() {
-					private final Origin origin = new Origin() {
-						public String getType() {
-							return "file";
-						}
-
-						public String getName() {
-							return name;
-						}
-					};
-
-					public Origin getOrigin() {
-						return origin;
-					}
-
-					public InputSource getInputSource() {
-						return inputSource;
-					}
-				}
-		);
+		add( inputSource, "file", name );
 		return this;
 	}
 
-	private XMLHelper.MetadataXml add(XMLHelper.MetadataXmlSource metadataXmlSource) {
-		XMLHelper.MetadataXml metadataXml = xmlHelper.readMappingDocument( entityResolver, metadataXmlSource );
+	private XmlDocument add(InputSource inputSource, String originType, String originName) {
+		return add( inputSource, new OriginImpl( originType, originName ) );
+	}
+
+	private XmlDocument add(InputSource inputSource, Origin origin) {
+		XmlDocument metadataXml = MappingReader.INSTANCE.readMappingDocument( entityResolver, inputSource, origin );
 		add( metadataXml );
 		return metadataXml;
 	}
 
-	private void add(XMLHelper.MetadataXml metadataXml) {
-		if ( inSecondPass || !metadataXml.isOrmXml() ) {
+	private void add(XmlDocument metadataXml) {
+		if ( inSecondPass || !isOrmXml( metadataXml ) ) {
 			metadataSourceQueue.add( metadataXml );
 		}
 		else {
 			final MetadataProvider metadataProvider = ( (MetadataProviderInjector) reflectionManager ).getMetadataProvider();
 			JPAMetadataProvider jpaMetadataProvider = ( JPAMetadataProvider ) metadataProvider;
-			List<String> classNames = jpaMetadataProvider.getXMLContext().addDocument( metadataXml.getXmlDocument() );
+			List<String> classNames = jpaMetadataProvider.getXMLContext().addDocument( metadataXml.getDocumentTree() );
 			for ( String className : classNames ) {
 				try {
 					metadataSourceQueue.add( reflectionManager.classForName( className, this.getClass() ) );
@@ -542,6 +529,10 @@
 		}
 	}
 
+	private static boolean isOrmXml(XmlDocument xmlDocument) {
+		return "entity-mappings".equals( xmlDocument.getDocumentTree().getRootElement().getName() );
+	}
+
 	/**
 	 * Add a cached mapping file.  A cached file is a serialized representation
 	 * of the DOM structure of a particular mapping.  It is saved from a previous
@@ -581,31 +572,11 @@
 		}
 
 		log.info( "Reading mappings from file: " + xmlFile );
-		XMLHelper.MetadataXml metadataXml = add(
-				new XMLHelper.MetadataXmlSource() {
-					private final Origin origin = new Origin() {
-						public String getType() {
-							return "file";
-						}
+		XmlDocument metadataXml = add( inputSource, "file", name );
 
-						public String getName() {
-							return name;
-						}
-					};
-					public Origin getOrigin() {
-						return origin;
-					}
-
-					public InputSource getInputSource() {
-						return inputSource;
-					}
-				}
-		);
-
-
 		try {
 			log.debug( "Writing cache file for: " + xmlFile + " to: " + cachedFile );
-			SerializationHelper.serialize( ( Serializable ) metadataXml.getXmlDocument(), new FileOutputStream( cachedFile ) );
+			SerializationHelper.serialize( ( Serializable ) metadataXml.getDocumentTree(), new FileOutputStream( cachedFile ) );
 		}
 		catch ( SerializationException e ) {
 			log.warn( "Could not write cached file: " + cachedFile, e );
@@ -647,7 +618,7 @@
 
 		log.info( "Reading mappings from cache file: " + cachedFile );
 		Document document = ( Document ) SerializationHelper.deserialize( new FileInputStream( cachedFile ) );
-		add( xmlHelper.buildMetadataXml( document, "file", xmlFile.getAbsolutePath() ) );
+		add( new XmlDocumentImpl( document, "file", xmlFile.getAbsolutePath() ) );
 		return this;
 	}
 
@@ -678,30 +649,8 @@
 		if ( log.isDebugEnabled() ) {
 			log.debug( "Mapping XML:\n" + xml );
 		}
-
 		final InputSource inputSource = new InputSource( new StringReader( xml ) );
-
-		add(
-				new XMLHelper.MetadataXmlSource() {
-					final Origin origin = new Origin() {
-						public String getType() {
-							return "string";
-						}
-
-						public String getName() {
-							return "XML String";
-						}
-					};
-
-					public Origin getOrigin() {
-						return origin;
-					}
-
-					public InputSource getInputSource() {
-						return inputSource;
-					}
-				}
-		);
+		add( inputSource, "string", "XML String" );
 		return this;
 	}
 
@@ -729,30 +678,10 @@
 		return this;
 	}
 
-	private XMLHelper.MetadataXml add(InputStream inputStream, final String type, final String name) {
-		final XMLHelper.MetadataXmlSource.Origin origin = new XMLHelper.MetadataXmlSource.Origin() {
-			public String getType() {
-				return type;
-			}
-
-			public String getName() {
-				return name;
-			}
-		};
+	private XmlDocument add(InputStream inputStream, final String type, final String name) {
 		final InputSource inputSource = new InputSource( inputStream );
-
 		try {
-			return add(
-					new XMLHelper.MetadataXmlSource() {
-						public Origin getOrigin() {
-							return origin;
-						}
-
-						public InputSource getInputSource() {
-							return inputSource;
-						}
-					}
-			);
+			return add( inputSource, type, name );
 		}
 		finally {
 			try {
@@ -763,6 +692,7 @@
 			}
 		}
 	}
+
 	/**
 	 * Read mappings from a DOM <tt>Document</tt>
 	 *
@@ -777,7 +707,7 @@
 		}
 
 		final Document document = xmlHelper.createDOMReader().read( doc );
-		add( xmlHelper.buildMetadataXml( document, "unknown", null ) );
+		add( new XmlDocumentImpl( document, "unknown", null ) );
 
 		return this;
 	}
@@ -3877,9 +3807,9 @@
 	}
 
 	protected class MetadataSourceQueue implements Serializable {
-		private LinkedHashMap<XMLHelper.MetadataXml, Set<String>> hbmMetadataToEntityNamesMap
-				= new LinkedHashMap<XMLHelper.MetadataXml, Set<String>>();
-		private Map<String, XMLHelper.MetadataXml> hbmMetadataByEntityNameXRef = new HashMap<String, XMLHelper.MetadataXml>();
+		private LinkedHashMap<XmlDocument, Set<String>> hbmMetadataToEntityNamesMap
+				= new LinkedHashMap<XmlDocument, Set<String>>();
+		private Map<String, XmlDocument> hbmMetadataByEntityNameXRef = new HashMap<String, XmlDocument>();
 
 		//XClass are not serializable by default
 		private transient List<XClass> annotatedClasses = new ArrayList<XClass>();
@@ -3908,8 +3838,8 @@
 			out.writeObject( serializableAnnotatedClasses );
 		}
 
-		public void add(XMLHelper.MetadataXml metadataXml) {
-			final Document document = metadataXml.getXmlDocument();
+		public void add(XmlDocument metadataXml) {
+			final Document document = metadataXml.getDocumentTree();
 			final Element hmNode = document.getRootElement();
 			Attribute packNode = hmNode.attribute( "package" );
 			String defaultPackage = packNode != null ? packNode.getValue() : "";
@@ -3990,7 +3920,7 @@
 
 		private void processHbmXmlQueue() {
 			log.debug( "Processing hbm.xml files" );
-			for ( Map.Entry<XMLHelper.MetadataXml, Set<String>> entry : hbmMetadataToEntityNamesMap.entrySet() ) {
+			for ( Map.Entry<XmlDocument, Set<String>> entry : hbmMetadataToEntityNamesMap.entrySet() ) {
 				// Unfortunately we have to create a Mappings instance for each iteration here
 				processHbmXml( entry.getKey(), entry.getValue() );
 			}
@@ -3998,12 +3928,16 @@
 			hbmMetadataByEntityNameXRef.clear();
 		}
 
-		private void processHbmXml(XMLHelper.MetadataXml metadataXml, Set<String> entityNames) {
+		private void processHbmXml(XmlDocument metadataXml, Set<String> entityNames) {
 			try {
 				HbmBinder.bindRoot( metadataXml, createMappings(), CollectionHelper.EMPTY_MAP, entityNames );
 			}
 			catch ( MappingException me ) {
-				throw new InvalidMappingException( metadataXml.getOriginType(), metadataXml.getOriginName(), me );
+				throw new InvalidMappingException(
+						metadataXml.getOrigin().getType(),
+						metadataXml.getOrigin().getName(), 
+						me
+				);
 			}
 
 			for ( String entityName : entityNames ) {

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -25,7 +25,7 @@
 
 import java.util.Set;
 
-import org.hibernate.util.XMLHelper;
+import org.hibernate.util.xml.XmlDocument;
 
 /**
  * Represents a mapping queued for delayed processing to await
@@ -36,10 +36,10 @@
 public class ExtendsQueueEntry {
 	private final String explicitName;
 	private final String mappingPackage;
-	private final XMLHelper.MetadataXml metadataXml;
+	private final XmlDocument metadataXml;
 	private final Set<String> entityNames;
 
-	public ExtendsQueueEntry(String explicitName, String mappingPackage, XMLHelper.MetadataXml metadataXml, Set<String> entityNames) {
+	public ExtendsQueueEntry(String explicitName, String mappingPackage, XmlDocument metadataXml, Set<String> entityNames) {
 		this.explicitName = explicitName;
 		this.mappingPackage = mappingPackage;
 		this.metadataXml = metadataXml;
@@ -54,7 +54,7 @@
 		return mappingPackage;
 	}
 
-	public XMLHelper.MetadataXml getMetadataXml() {
+	public XmlDocument getMetadataXml() {
 		return metadataXml;
 	}
 

Modified: core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -93,11 +93,10 @@
 import org.hibernate.type.DiscriminatorType;
 import org.hibernate.type.ForeignKeyDirection;
 import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
 import org.hibernate.util.JoinedIterator;
 import org.hibernate.util.ReflectHelper;
 import org.hibernate.util.StringHelper;
-import org.hibernate.util.XMLHelper;
+import org.hibernate.util.xml.XmlDocument;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -130,12 +129,12 @@
 	 * @throws MappingException
 	 */
 	public static void bindRoot(
-			XMLHelper.MetadataXml metadataXml,
+			XmlDocument metadataXml,
 			Mappings mappings,
 			java.util.Map inheritedMetas,
 			java.util.Set<String> entityNames) throws MappingException {
 
-		final Document doc = metadataXml.getXmlDocument();
+		final Document doc = metadataXml.getDocumentTree();
 		final Element hibernateMappingElement = doc.getRootElement();
 
 		java.util.List<String> names = HbmBinder.getExtendsNeeded( metadataXml, mappings );
@@ -3076,10 +3075,10 @@
 	 * @param mappings The already processed mappings.
 	 * @return The list of unresolved extends names.
 	 */
-	public static java.util.List<String> getExtendsNeeded(XMLHelper.MetadataXml metadataXml, Mappings mappings) {
+	public static java.util.List<String> getExtendsNeeded(XmlDocument metadataXml, Mappings mappings) {
 		java.util.List<String> extendz = new ArrayList<String>();
 		Iterator[] subclasses = new Iterator[3];
-		final Element hmNode = metadataXml.getXmlDocument().getRootElement();
+		final Element hmNode = metadataXml.getDocumentTree().getRootElement();
 
 		Attribute packNode = hmNode.attribute( "package" );
 		final String packageName = packNode == null ? null : packNode.getValue();

Modified: core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -23,21 +23,8 @@
  */
 package org.hibernate.util;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.net.URL;
 import java.util.List;
-import javax.xml.XMLConstants;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
 
-import org.dom4j.Document;
 import org.dom4j.DocumentFactory;
 import org.dom4j.Element;
 import org.dom4j.io.DOMReader;
@@ -48,21 +35,15 @@
 import org.slf4j.LoggerFactory;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 
-import org.hibernate.HibernateException;
-import org.hibernate.InvalidMappingException;
 
 /**
  * Small helper class that lazy loads DOM and SAX reader and keep them for fast use afterwards.
  */
 public final class XMLHelper {
-	public static final String ORM_1_SCHEMA_NAME = "org/hibernate/ejb/orm_1_0.xsd";
-	public static final String ORM_2_SCHEMA_NAME = "org/hibernate/ejb/orm_2_0.xsd";
-
 	private static final Logger log = LoggerFactory.getLogger(XMLHelper.class);
+
 	public static final EntityResolver DEFAULT_DTD_RESOLVER = new DTDEntityResolver();
 
 	private DOMReader domReader;
@@ -135,249 +116,4 @@
 		}
 
 	}
-
-	public static interface MetadataXmlSource {
-		public static interface Origin {
-			public String getType();
-			public String getName();
-		}
-		public Origin getOrigin();
-		public InputSource getInputSource();
-	}
-
-	public static interface MetadataXml extends Serializable {
-		public boolean isOrmXml();
-		public Document getXmlDocument();
-		public String getOriginType();
-		public String getOriginName();
-	}
-
-	private static class MetadataXmlImpl implements MetadataXml, Serializable {
-		private final Document xmlDocument;
-		private final boolean isOrmXml;
-		private final String originType;
-		private final String originName;
-
-		private MetadataXmlImpl(Document xmlDocument, String originType, String originName) {
-			this.xmlDocument = xmlDocument;
-			this.originType = originType;
-			this.originName = originName;
-			this.isOrmXml = "entity-mappings".equals( xmlDocument.getRootElement().getName() );
-		}
-
-		public Document getXmlDocument() {
-			return xmlDocument;
-		}
-
-		public boolean isOrmXml() {
-			return isOrmXml;
-		}
-
-		public String getOriginType() {
-			return originType;
-		}
-
-		public String getOriginName() {
-			return originName;
-		}
-	}
-
-	public MetadataXml buildMetadataXml(Document xmlDocument, String originType, String originName) {
-		return new MetadataXmlImpl( xmlDocument, originType, originName );
-	}
-
-	public MetadataXml readMappingDocument(EntityResolver entityResolver, MetadataXmlSource source) {
-		// IMPL NOTE : this is the legacy logic as pulled from the old AnnotationConfiguration code
-
-		Exception failure;
-		ErrorLogger2 errorHandler = new ErrorLogger2();
-
-		SAXReader saxReader = new SAXReader();
-		saxReader.setEntityResolver( entityResolver );
-		saxReader.setErrorHandler( errorHandler );
-		saxReader.setMergeAdjacentText( true );
-		saxReader.setValidation( true );
-
-		Document document = null;
-		try {
-			// first try with orm 2.0 xsd validation
-			setValidationFor( saxReader, "orm_2_0.xsd" );
-			document = saxReader.read( source.getInputSource() );
-			if ( errorHandler.error != null ) {
-				throw errorHandler.error;
-			}
-			return buildMetadataXml( document, source.getOrigin().getType(), source.getOrigin().getName() );
-		}
-		catch ( Exception orm2Problem ) {
-			log.debug( "Problem parsing XML using orm 2 xsd : {}", orm2Problem.getMessage() );
-			failure = orm2Problem;
-			errorHandler.error = null;
-
-			if ( document != null ) {
-				// next try with orm 1.0 xsd validation
-				try {
-					setValidationFor( saxReader, "orm_1_0.xsd" );
-					document = saxReader.read(  new StringReader( document.asXML() ) );
-					if ( errorHandler.error != null ) {
-						throw errorHandler.error;
-					}
-					return buildMetadataXml( document, source.getOrigin().getType(), source.getOrigin().getName() );
-				}
-				catch ( Exception orm1Problem ) {
-					log.debug( "Problem parsing XML using orm 1 xsd : {}", orm1Problem.getMessage() );
-					errorHandler.error = null;
-				}
-			}
-		}
-		throw new InvalidMappingException( "Unable to read XML", source.getOrigin().getType(), source.getOrigin().getName(), failure );
-
-	}
-
-	private void setValidationFor(SAXReader saxReader, String xsd) {
-		try {
-			saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
-			//saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
-			//set the default schema locators
-			saxReader.setProperty(
-					"http://apache.org/xml/properties/schema/external-schemaLocation",
-					"http://java.sun.com/xml/ns/persistence/orm " + xsd
-			);
-		}
-		catch ( SAXException e ) {
-			saxReader.setValidation( false );
-		}
-	}
-
-//	public MetadataXml readMappingDocument(EntityResolver entityResolver, MetadataXmlSource source) {
-//		Exception failure;
-//		ErrorLogger2 errorHandler = new ErrorLogger2();
-//
-//		SAXReader saxReader = resolveSAXReader();
-//		saxReader.setEntityResolver( entityResolver );
-//		saxReader.setErrorHandler( errorHandler );
-//
-//		try {
-//			Document document = saxReader.read( source.getInputSource() );
-//			if ( errorHandler.error != null ) {
-//				Exception problem = errorHandler.error;
-//				errorHandler.error = null;
-//				throw problem;
-//			}
-//		}
-//		catch ( Exception parseError ) {
-//			log.debug( "Problem parsing XML document : {}", parseError.getMessage() );
-//		}
-//		// first try with orm 2.0 xsd validation
-//		try {
-//			SAXReader saxReader = orm2SaxReader();
-//			if ( errorHandler.error != null ) {
-//				Exception problem = errorHandler.error;
-//				errorHandler.error = null;
-//				throw problem;
-//			}
-//			return buildMetadataXml( document, source.getOrigin().getType(), source.getOrigin().getName() );
-//		}
-//		catch ( Exception orm2Problem ) {
-//			log.debug( "Problem parsing XML using orm 2 xsd : {}", orm2Problem.getMessage() );
-//			failure = orm2Problem;
-//
-//			// next try with orm 1.0 xsd validation
-//			try {
-//				SAXReader saxReader = orm1SaxReader();
-//				saxReader.setEntityResolver( entityResolver );
-//				saxReader.setErrorHandler( errorHandler );
-//				Document document = saxReader.read( source.getInputSource() );
-//				if ( errorHandler.error != null ) {
-//					Exception problem = errorHandler.error;
-//					errorHandler.error = null;
-//					throw problem;
-//				}
-//				return buildMetadataXml( document, source.getOrigin().getType(), source.getOrigin().getName() );
-//			}
-//			catch ( Exception orm1Problem ) {
-//				log.debug( "Problem parsing XML using orm 1 xsd : {}", orm1Problem.getMessage() );
-//			}
-//		}
-//		throw new InvalidMappingException( "Unable to read XML", source.getOrigin().getType(), source.getOrigin().getName(), failure );
-//	}
-
-	private static class ErrorLogger2 implements ErrorHandler {
-		private SAXParseException error; // capture the initial error
-
-		public void error(SAXParseException error) {
-			log.error( "Error parsing XML (" + error.getLineNumber() + ") : " + error.getMessage() );
-			if ( this.error == null ) {
-				this.error = error;
-			}
-		}
-		public void fatalError(SAXParseException error) {
-			error( error );
-		}
-		public void warning(SAXParseException warn) {
-			log.error( "Warning parsing XML (" + error.getLineNumber() + ") : " + error.getMessage() );
-		}
-	}
-
-	private static SAXReader orm2SaxReader;
-
-	private static SAXReader orm2SaxReader() throws IOException, SAXException {
-		if ( orm2SaxReader == null ) {
-			orm2SaxReader = buildReaderWithSchema( orm2Schema() );
-		}
-		return orm2SaxReader;
-	}
-
-	private static Schema orm2Schema;
-
-	private static Schema orm2Schema() throws IOException, SAXException {
-		if ( orm2Schema == null ) {
-			orm2Schema = resolveLocalSchema( ORM_2_SCHEMA_NAME );
-		}
-		return orm2Schema;
-	}
-
-	private static Schema resolveLocalSchema(String schemaName) throws IOException, SAXException {
-        URL url = ConfigHelper.findAsResource( schemaName );
-        InputStream schemaStream = url.openStream();
-        try {
-            StreamSource source = new StreamSource(url.openStream());
-            SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
-            return schemaFactory.newSchema(source);
-        }
-		finally {
-            schemaStream.close();
-        }
-	}
-
-	private static SAXReader buildReaderWithSchema(Schema schema) throws SAXException {
-		SAXParserFactory factory = SAXParserFactory.newInstance();
-		factory.setSchema( schema );
-		try {
-			SAXReader saxReader = new SAXReader( factory.newSAXParser().getXMLReader() );
-			saxReader.setMergeAdjacentText( true );
-			saxReader.setValidation( true );
-			return saxReader;
-		}
-		catch ( ParserConfigurationException e ) {
-			throw new HibernateException( "Unable to build SAXReader with XSD support", e );
-		}
-	}
-
-	private static SAXReader orm1SaxReader;
-
-	private static SAXReader orm1SaxReader() throws IOException, SAXException {
-		if ( orm1SaxReader == null ) {
-			orm1SaxReader = buildReaderWithSchema( orm1Schema() );
-		}
-		return orm1SaxReader;
-	}
-
-	private static Schema orm1Schema;
-
-	private static Schema orm1Schema() throws IOException, SAXException {
-		if ( orm1Schema == null ) {
-			orm1Schema = resolveLocalSchema( ORM_1_SCHEMA_NAME );
-		}
-		return orm1Schema;
-	}
 }

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/ErrorLogger.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/ErrorLogger.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/ErrorLogger.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,80 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Implements an {@link ErrorHandler} that mainly just logs errors/warnings.  However, it does track
+ * the intial error it encounters and makes it available via {@link #getError}.
+ *
+ * @author Steve Ebersole
+ */
+public class ErrorLogger implements ErrorHandler, Serializable {
+	private static final Logger log = LoggerFactory.getLogger( ErrorLogger.class );
+
+	private SAXParseException error; // capture the initial error
+
+	/**
+	 * Retrieve the initial error encountered, or null if no error was encountered.
+	 *
+	 * @return The initial error, or null if none.
+	 */
+	public SAXParseException getError() {
+		return error;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void error(SAXParseException error) {
+		log.error( "Error parsing XML (" + error.getLineNumber() + ") : " + error.getMessage() );
+		if ( this.error == null ) {
+			this.error = error;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void fatalError(SAXParseException error) {
+		error( error );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void warning(SAXParseException warn) {
+		log.error( "Warning parsing XML (" + error.getLineNumber() + ") : " + error.getMessage() );
+	}
+
+	public void reset() {
+		error = null;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/MappingReader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/MappingReader.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/MappingReader.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,257 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.StringReader;
+
+import org.dom4j.Document;
+import org.dom4j.io.SAXReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import org.hibernate.InvalidMappingException;
+
+/**
+ * Handles reading mapping documents, both {@code hbm} and {@code orm} varieties.
+ *
+ * @author Steve Ebersole
+ */
+public class MappingReader {
+	private static final Logger log = LoggerFactory.getLogger( MappingReader.class );
+
+	public static final String ASSUMED_ORM_XSD_VERSION = "2.0";
+	public static final MappingReader INSTANCE = new MappingReader();
+
+	/**
+	 * Disallow direct instantiation.
+	 * <p/>
+	 * Eventually we perhaps need to have this configurable by the "configuration" and simply reference it
+	 * from there (registry).  This would allow, for example, injection of the entity resolver to use as
+	 * instance state.
+	 */
+	private MappingReader() {
+	}
+
+	public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
+		// IMPL NOTE : this is the legacy logic as pulled from the old AnnotationConfiguration code
+
+		Exception failure;
+		ErrorLogger errorHandler = new ErrorLogger();
+
+		SAXReader saxReader = new SAXReader();
+		saxReader.setEntityResolver( entityResolver );
+		saxReader.setErrorHandler( errorHandler );
+		saxReader.setMergeAdjacentText( true );
+		saxReader.setValidation( true );
+
+		Document document = null;
+		try {
+			// first try with orm 2.0 xsd validation
+			setValidationFor( saxReader, "orm_2_0.xsd" );
+			document = saxReader.read( source );
+			if ( errorHandler.getError() != null ) {
+				throw errorHandler.getError();
+			}
+			return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
+		}
+		catch ( Exception orm2Problem ) {
+			log.debug( "Problem parsing XML using orm 2 xsd : {}", orm2Problem.getMessage() );
+			failure = orm2Problem;
+			errorHandler.reset();
+
+			if ( document != null ) {
+				// next try with orm 1.0 xsd validation
+				try {
+					setValidationFor( saxReader, "orm_1_0.xsd" );
+					document = saxReader.read(  new StringReader( document.asXML() ) );
+					if ( errorHandler.getError() != null ) {
+						throw errorHandler.getError();
+					}
+					return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
+				}
+				catch ( Exception orm1Problem ) {
+					log.debug( "Problem parsing XML using orm 1 xsd : {}", orm1Problem.getMessage() );
+				}
+			}
+		}
+		throw new InvalidMappingException( "Unable to read XML", origin.getType(), origin.getName(), failure );
+	}
+
+	private void setValidationFor(SAXReader saxReader, String xsd) {
+		try {
+			saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
+			//saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
+			//set the default schema locators
+			saxReader.setProperty(
+					"http://apache.org/xml/properties/schema/external-schemaLocation",
+					"http://java.sun.com/xml/ns/persistence/orm " + xsd
+			);
+		}
+		catch ( SAXException e ) {
+			saxReader.setValidation( false );
+		}
+	}
+
+	// this is the version of the code I'd like to use, but it unfortunately works very differently between
+	// JDK 1.5 ad JDK 1.6.  On 1.5 the vaildation "passes" even with invalid content.
+	//
+	// Options:
+	// 		1) continue using the code above
+	//		2) Document the issue on 1.5 and how to fix (specifying alternate SchemaFactory instance)
+	//		3) Use a specific JAXP library (Xerces2, Saxon, Jing, MSV) and its SchemaFactory instance directly
+
+//	public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
+//		ErrorLogger errorHandler = new ErrorLogger();
+//
+//		SAXReader saxReader = new SAXReader( new DOMDocumentFactory() );
+//		saxReader.setEntityResolver( entityResolver );
+//		saxReader.setErrorHandler( errorHandler );
+//		saxReader.setMergeAdjacentText( true );
+//
+//		Document documentTree = null;
+//
+//		// IMPL NOTE : here we enable DTD validation in case the mapping is a HBM file.  This will validate
+//		// the document as it is parsed.  This is needed because the DTD defines default values that have to be
+//		// applied as the document is parsed, so thats something we need to account for as we (if we) transition
+//		// to XSD.
+//		saxReader.setValidation( true );
+//		try {
+//			documentTree = saxReader.read( source );
+//		}
+//		catch ( DocumentException e ) {
+//			// we had issues reading the input, most likely malformed document or validation error against DTD
+//			throw new InvalidMappingException( "Unable to read XML", origin.getType(), origin.getName(), e );
+//		}
+//
+//		Element rootElement = documentTree.getRootElement();
+//		if ( rootElement ==  null ) {
+//			throw new InvalidMappingException( "No root element", origin.getType(), origin.getName() );
+//		}
+//
+//		if ( "entity-mappings".equals( rootElement.getName() ) ) {
+//			final String explicitVersion = rootElement.attributeValue( "version" );
+//			final String xsdVersionString = explicitVersion == null ? ASSUMED_ORM_XSD_VERSION : explicitVersion;
+//			final SupportedOrmXsdVersion xsdVersion = SupportedOrmXsdVersion.parse( xsdVersionString );
+//			final Schema schema = xsdVersion == SupportedOrmXsdVersion.ORM_1_0 ? orm1Schema() : orm2Schema();
+//			try {
+//				schema.newValidator().validate( new DOMSource( (org.w3c.dom.Document) documentTree ) );
+//			}
+//			catch ( SAXException e ) {
+//				throw new InvalidMappingException( "Validation problem", origin.getType(), origin.getName(), e );
+//			}
+//			catch ( IOException e ) {
+//				throw new InvalidMappingException( "Validation problem", origin.getType(), origin.getName(), e );
+//			}
+//		}
+//		else {
+//			if ( errorHandler.getError() != null ) {
+//				throw new InvalidMappingException(
+//						"Error validating hibernate-mapping against DTD",
+//						origin.getType(),
+//						origin.getName(),
+//						errorHandler.getError()
+//				);
+//			}
+//		}
+//
+//		return new XmlDocumentImpl( documentTree, origin );
+//	}
+//
+//	public static enum SupportedOrmXsdVersion {
+//		ORM_1_0,
+//		ORM_2_0;
+//
+//		public static SupportedOrmXsdVersion parse(String name) {
+//			if ( "1.0".equals( name ) ) {
+//				return ORM_1_0;
+//			}
+//			else if ( "2.0".equals( name ) ) {
+//				return ORM_2_0;
+//			}
+//			throw new IllegalArgumentException( "Unsupported orm.xml XSD version encountered [" + name + "]" );
+//		}
+//	}
+//
+//
+//	public static final String ORM_1_SCHEMA_NAME = "org/hibernate/ejb/orm_1_0.xsd";
+//	public static final String ORM_2_SCHEMA_NAME = "org/hibernate/ejb/orm_2_0.xsd";
+//
+//	private static Schema orm1Schema;
+//
+//	private static Schema orm1Schema() {
+//		if ( orm1Schema == null ) {
+//			orm1Schema = resolveLocalSchema( ORM_1_SCHEMA_NAME );
+//		}
+//		return orm1Schema;
+//	}
+//
+//	private static Schema orm2Schema;
+//
+//	private static Schema orm2Schema() {
+//		if ( orm2Schema == null ) {
+//			orm2Schema = resolveLocalSchema( ORM_2_SCHEMA_NAME );
+//		}
+//		return orm2Schema;
+//	}
+//
+//	private static Schema resolveLocalSchema(String schemaName) {
+//		return resolveLocalSchema( schemaName, XMLConstants.W3C_XML_SCHEMA_NS_URI );
+//	}
+//
+//	private static Schema resolveLocalSchema(String schemaName, String schemaLanguage) {
+//        URL url = ConfigHelper.findAsResource( schemaName );
+//		if ( url == null ) {
+//			throw new MappingException( "Unable to locate schema [" + schemaName + "] via classpath" );
+//		}
+//		try {
+//			InputStream schemaStream = url.openStream();
+//			try {
+//				StreamSource source = new StreamSource(url.openStream());
+//				SchemaFactory schemaFactory = SchemaFactory.newInstance( schemaLanguage );
+//				return schemaFactory.newSchema(source);
+//			}
+//			catch ( SAXException e ) {
+//				throw new MappingException( "Unable to load schema [" + schemaName + "]", e );
+//			}
+//			catch ( IOException e ) {
+//				throw new MappingException( "Unable to load schema [" + schemaName + "]", e );
+//			}
+//			finally {
+//				try {
+//					schemaStream.close();
+//				}
+//				catch ( IOException e ) {
+//					log.warn( "Problem closing schema stream [{}]", e.toString() );
+//				}
+//			}
+//		}
+//		catch ( IOException e ) {
+//			throw new MappingException( "Stream error handling schema url [" + url.toExternalForm() + "]" );
+//		}
+//
+//	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/Origin.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/Origin.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/Origin.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.Serializable;
+
+/**
+ * Describes the origin of an xml document
+ *
+ * @author Steve Ebersole
+ */
+public interface Origin extends Serializable {
+	/**
+	 * Retrieve the type of origin.  This is not a discrete set, but might be somethign like
+	 * {@code file} for file protocol URLs, or {@code resource} for classpath resource lookups.
+	 *
+	 * @return The origin type.
+	 */
+	public String getType();
+
+	/**
+	 * The name of the document origin.  Interpretation is relative to the type, but might be the
+	 * resource name or file URL.
+	 *
+	 * @return The name.
+	 */
+	public String getName();
+}

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/OriginImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/OriginImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/OriginImpl.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.Serializable;
+
+/**
+ * Basic implementation of {@link Origin}
+ *
+ * @author Steve Ebersole
+ */
+public class OriginImpl implements Origin, Serializable {
+	private final String type;
+	private final String name;
+
+	public OriginImpl(String type, String name) {
+		this.type = type;
+		this.name = name;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getName() {
+		return name;
+	}
+}

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocument.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocument.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocument.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,49 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.Serializable;
+
+import org.dom4j.Document;
+
+/**
+ * Describes a parsed xml document.
+ *
+ * @author Steve Ebersole
+ */
+public interface XmlDocument extends Serializable {
+	/**
+	 * Retrieve the parsed DOM tree.
+	 *
+	 * @return the DOM tree
+	 */
+	public Document getDocumentTree();
+
+	/**
+	 * Retrieve the document's origin.
+	 *
+	 * @return The origin
+	 */
+	public Origin getOrigin();
+}

Added: core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocumentImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocumentImpl.java	                        (rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/util/xml/XmlDocumentImpl.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,61 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.util.xml;
+
+import java.io.Serializable;
+
+import org.dom4j.Document;
+
+/**
+ * Basic implemementation of {@link XmlDocument}
+ *
+ * @author Steve Ebersole
+ */
+public class XmlDocumentImpl implements XmlDocument, Serializable {
+	private final Document documentTree;
+	private final Origin origin;
+
+	public XmlDocumentImpl(Document documentTree, String originType, String originName) {
+		this( documentTree, new OriginImpl( originType, originName ) );
+	}
+
+	public XmlDocumentImpl(Document documentTree, Origin origin) {
+		this.documentTree = documentTree;
+		this.origin = origin;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Document getDocumentTree() {
+		return documentTree;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Origin getOrigin() {
+		return origin;
+	}
+}

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -58,13 +58,11 @@
 import javax.persistence.spi.PersistenceUnitTransactionType;
 import javax.sql.DataSource;
 
-import org.dom4j.DocumentException;
 import org.dom4j.Element;
-import org.dom4j.io.SAXReader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.EntityResolver;
-import org.xml.sax.SAXException;
+import org.xml.sax.InputSource;
 
 import org.hibernate.HibernateException;
 import org.hibernate.Interceptor;
@@ -101,6 +99,10 @@
 import org.hibernate.util.ReflectHelper;
 import org.hibernate.util.StringHelper;
 import org.hibernate.util.XMLHelper;
+import org.hibernate.util.xml.MappingReader;
+import org.hibernate.util.xml.Origin;
+import org.hibernate.util.xml.OriginImpl;
+import org.hibernate.util.xml.XmlDocument;
 
 /**
  * Allow a fine tuned configuration of an EJB 3.0 EntityManagerFactory
@@ -687,37 +689,29 @@
 
 	private void addXMLEntities(List<String> xmlFiles, PersistenceUnitInfo info, List<String> entities) {
 		//TODO handle inputstream related hbm files
-		ClassLoader newTempClassLoader = info.getNewTempClassLoader();
-		if (newTempClassLoader == null) {
-			log.warn( "Persistence provider caller does not implement the EJB3 spec correctly. PersistenceUnitInfo.getNewTempClassLoader() is null." );
+		ClassLoader classLoaderToUse = info.getNewTempClassLoader();
+		if ( classLoaderToUse == null ) {
+			log.warn(
+					"Persistence provider caller does not implement the EJB3 spec correctly." +
+							"PersistenceUnitInfo.getNewTempClassLoader() is null."
+			);
 			return;
 		}
-		XMLHelper xmlHelper = new XMLHelper();
-		List errors = new ArrayList();
-		SAXReader saxReader = xmlHelper.createSAXReader( "XML InputStream", errors, cfg.getEntityResolver() );
-		try {
-			saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
-			//saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
-			//set the default schema locators
-			saxReader.setProperty( "http://apache.org/xml/properties/schema/external-schemaLocation",
-					"http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd");
-		}
-		catch (SAXException e) {
-			saxReader.setValidation( false );
-		}
+		for ( final String xmlFile : xmlFiles ) {
+			final InputStream fileInputStream = classLoaderToUse.getResourceAsStream( xmlFile );
+			if ( fileInputStream == null ) {
+				log.info( "Unable to resolve mapping file [{}]", xmlFile );
+				continue;
+			}
+			final InputSource inputSource = new InputSource( fileInputStream );
 
-		for ( String xmlFile : xmlFiles ) {
-
-			InputStream resourceAsStream = newTempClassLoader.getResourceAsStream( xmlFile );
-			if (resourceAsStream == null) continue;
-			BufferedInputStream is = new BufferedInputStream( resourceAsStream );
+			XmlDocument metadataXml = MappingReader.INSTANCE.readMappingDocument(
+					cfg.getEntityResolver(),
+					inputSource,
+					new OriginImpl( "persistence-unit-info", xmlFile )
+			);
 			try {
-				errors.clear();
-				org.dom4j.Document doc = saxReader.read( is );
-				if ( errors.size() != 0 ) {
-					throw new MappingException( "invalid mapping: " + xmlFile, (Throwable) errors.get( 0 ) );
-				}
-				Element rootElement = doc.getRootElement();
+				final Element rootElement = metadataXml.getDocumentTree().getRootElement();
 				if ( rootElement != null && "entity-mappings".equals( rootElement.getName() ) ) {
 					Element element = rootElement.element( "package" );
 					String defaultPackage = element != null ? element.getTextTrim() : null;
@@ -747,12 +741,9 @@
 					//FIXME include hbm xml entities to enhance them but entities is also used to collect annotated entities
 				}
 			}
-			catch (DocumentException e) {
-				throw new MappingException( "Could not parse mapping document in input stream", e );
-			}
 			finally {
 				try {
-					is.close();
+					fileInputStream.close();
 				}
 				catch (IOException ioe) {
 					log.warn( "Could not close input stream", ioe );

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/LogHelper.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/LogHelper.java	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/util/LogHelper.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -72,20 +72,26 @@
 				.append( "\n\t" );
 		sb.append( "Jar files URLs [" );
 		List<URL> jarFileUrls = unitInfo.getJarFileUrls();
-		for ( URL url : jarFileUrls ) {
-			sb.append( "\n\t\t" ).append( url );
+		if ( jarFileUrls != null ) {
+			for ( URL url : jarFileUrls ) {
+				sb.append( "\n\t\t" ).append( url );
+			}
 		}
 		sb.append( "]\n\t" );
 		sb.append( "Managed classes names [" );
-		List<String> classesNames = unitInfo.getManagedClassNames();
-		for ( String clazz : classesNames ) {
-			sb.append( "\n\t\t" ).append( clazz );
+		List<String> classNames = unitInfo.getManagedClassNames();
+		if ( classNames != null ) {
+			for ( String className : classNames ) {
+				sb.append( "\n\t\t" ).append( className );
+			}
 		}
 		sb.append( "]\n\t" );
 		sb.append( "Mapping files names [" );
 		List<String> mappingFiles = unitInfo.getMappingFileNames();
-		for ( String file : mappingFiles ) {
-			sb.append( "\n\t\t" ).append( file );
+		if ( mappingFiles != null ) {
+			for ( String file : mappingFiles ) {
+				sb.append( "\n\t\t" ).append( file );
+			}
 		}
 		sb.append( "]\n\t" );
 		sb.append( "Properties [" );

Modified: core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml
===================================================================
--- core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml	2010-09-08 05:39:35 UTC (rev 20320)
+++ core/trunk/entitymanager/src/test/bundles/defaultpar/META-INF/orm.xml	2010-09-08 18:03:28 UTC (rev 20321)
@@ -12,6 +12,7 @@
                     <pre-persist method-name="increment"/>
                 </entity-listener>
             </entity-listeners>
+            <delimited-identifiers>false</delimited-identifiers>
         </persistence-unit-defaults>
     </persistence-unit-metadata>
     <package>org.hibernate.ejb.test.pack.defaultpar</package>

Added: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/jee/OrmVersionTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/jee/OrmVersionTest.java	                        (rev 0)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/jee/OrmVersionTest.java	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,172 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors.  All third-party contributions are
+ * distributed under license by Red Hat Inc.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA  02110-1301  USA
+ */
+package org.hibernate.ejb.test.jee;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.SharedCacheMode;
+import javax.persistence.ValidationMode;
+import javax.persistence.spi.ClassTransformer;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.sql.DataSource;
+
+import junit.framework.TestCase;
+
+import org.hibernate.InvalidMappingException;
+import org.hibernate.ejb.HibernatePersistence;
+
+/**
+ * "smoke" tests for JEE bootstrapping of HEM via a {@link PersistenceUnitInfo}
+ *
+ * @author Steve Ebersole
+ */
+public class OrmVersionTest extends TestCase {
+	public void testOrm1() {
+		PersistenceUnitInfoImpl pui = new PersistenceUnitInfoImpl( "orm1-test", "1.0" )
+				.addMappingFileName( "org/hibernate/ejb/test/jee/valid-orm-1.xml" );
+		HibernatePersistence hp = new HibernatePersistence();
+		EntityManagerFactory emf = hp.createContainerEntityManagerFactory( pui, Collections.EMPTY_MAP );
+		emf.getMetamodel().entity( org.hibernate.ejb.test.pack.defaultpar_1_0.Lighter1.class ); // exception if not entity
+	}
+
+	public void testOrm2() {
+		PersistenceUnitInfoImpl pui = new PersistenceUnitInfoImpl( "orm2-test", "2.0" )
+				.addMappingFileName( "org/hibernate/ejb/test/jee/valid-orm-2.xml" );
+		HibernatePersistence hp = new HibernatePersistence();
+		EntityManagerFactory emf = hp.createContainerEntityManagerFactory( pui, Collections.EMPTY_MAP );
+		emf.getMetamodel().entity( org.hibernate.ejb.test.pack.defaultpar.Lighter.class ); // exception if not entity
+	}
+
+	public void testInvalidOrm1() {
+		PersistenceUnitInfoImpl pui = new PersistenceUnitInfoImpl( "invalid-orm1-test", "1.0" )
+				.addMappingFileName( "org/hibernate/ejb/test/jee/invalid-orm-1.xml" );
+		HibernatePersistence hp = new HibernatePersistence();
+		try {
+			hp.createContainerEntityManagerFactory( pui, Collections.EMPTY_MAP );
+			fail( "expecting 'invalid content' error" );
+		}
+		catch ( InvalidMappingException expected ) {
+			// expected condition
+		}
+	}
+
+	public static class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
+		private final String name;
+		private final String persistenceSchemaVersion;
+
+		public PersistenceUnitInfoImpl(String name) {
+			this( name, "2.0" );
+		}
+
+		public PersistenceUnitInfoImpl(String name, String persistenceSchemaVersion) {
+			this.name = name;
+			this.persistenceSchemaVersion = persistenceSchemaVersion;
+		}
+
+		public String getPersistenceUnitName() {
+			return name;
+		}
+
+		public String getPersistenceXMLSchemaVersion() {
+			return persistenceSchemaVersion;
+		}
+
+		private final List<String> mappingFileNames = new ArrayList<String>();
+
+		public List<String> getMappingFileNames() {
+			return mappingFileNames;
+		}
+
+		private final List<String> managedClassNames = new ArrayList<String>();
+
+		private PersistenceUnitInfoImpl addMappingFileName(String mappingFileName) {
+			mappingFileNames.add( mappingFileName );
+			return this;
+		}
+
+		public List<String> getManagedClassNames() {
+			return managedClassNames;
+		}
+
+		public String getPersistenceProviderClassName() {
+			return null;
+		}
+
+		public PersistenceUnitTransactionType getTransactionType() {
+			return PersistenceUnitTransactionType.RESOURCE_LOCAL;
+		}
+
+		public DataSource getJtaDataSource() {
+			return null;
+		}
+
+		public DataSource getNonJtaDataSource() {
+			return null;
+		}
+
+		private final List<URL> jarFileUrls = new ArrayList<URL>();
+
+		public List<URL> getJarFileUrls() {
+			return jarFileUrls;
+		}
+
+		public URL getPersistenceUnitRootUrl() {
+			return null;
+		}
+
+		public boolean excludeUnlistedClasses() {
+			return false;
+		}
+
+		public SharedCacheMode getSharedCacheMode() {
+			return null;
+		}
+
+		public ValidationMode getValidationMode() {
+			return null;
+		}
+
+		private final Properties properties = new Properties();
+
+		public Properties getProperties() {
+			return properties;
+		}
+
+		public ClassLoader getClassLoader() {
+			return Thread.currentThread().getContextClassLoader();
+		}
+
+		public void addTransformer(ClassTransformer transformer) {
+		}
+
+		public ClassLoader getNewTempClassLoader() {
+			return getClassLoader();
+		}
+	}
+}

Added: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/invalid-orm-1.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/invalid-orm-1.xml	                        (rev 0)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/invalid-orm-1.xml	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Inc.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<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"
+        >
+    <!-- use orm_1_0 on purpose (backward compatibility test -->
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <delimited-identifiers/>
+            <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>
\ No newline at end of file

Added: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-1.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-1.xml	                        (rev 0)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-1.xml	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Inc.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<entity-mappings version="1.0"
+                 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">
+    <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>
\ No newline at end of file

Added: core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-2.xml
===================================================================
--- core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-2.xml	                        (rev 0)
+++ core/trunk/entitymanager/src/test/resources/org/hibernate/ejb/test/jee/valid-orm-2.xml	2010-09-08 18:03:28 UTC (rev 20321)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Inc.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<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_2_0.xsd"
+                 version="2.0"
+        >
+    <persistence-unit-metadata>
+        <persistence-unit-defaults>
+            <delimited-identifiers/>
+            <entity-listeners>
+                <entity-listener class="org.hibernate.ejb.test.pack.defaultpar.IncrementListener">
+                    <pre-persist method-name="increment"/>
+                </entity-listener>
+            </entity-listeners>
+        </persistence-unit-defaults>
+    </persistence-unit-metadata>
+    <package>org.hibernate.ejb.test.pack.defaultpar</package>
+    <entity class="Lighter" access="FIELD" metadata-complete="true">
+        <attributes>
+            <id name="name">
+                <column name="fld_id"/>
+            </id>
+            <basic name="power"></basic>
+        </attributes>
+    </entity>
+    <entity class="ApplicationServer">
+        <entity-listeners>
+            <entity-listener class="OtherIncrementListener">
+                <pre-persist method-name="increment"/>
+            </entity-listener>
+        </entity-listeners>
+    </entity>
+</entity-mappings>
\ No newline at end of file



More information about the hibernate-commits mailing list