From 775e02233107525055538c61f0b4c1a668145821 Mon Sep 17 00:00:00 2001
From: Steve Ebersole
Date: Wed, 13 Apr 2011 14:47:18 -0500
Subject: [PATCH] HHH-6118 - Make Metadata more user-friendly API
---
.../org/hibernate/HibernateException.java | 10 +-
.../metamodel/source/MappingException.java | 50 +++
.../source/MappingNotFoundException.java | 46 +++
.../hibernate/metamodel/source/Metadata.java | 266 ++++++-------
.../source/{util/xml => }/Origin.java | 23 +-
.../xml/JaxbRoot.java => SourceType.java} | 29 +-
.../metamodel/source/XsdException.java | 50 +++
.../source/annotations/AnnotationBinder.java | 6 +-
.../source/annotations/EntityBinder.java | 4 +-
.../source/annotations/OrmXmlParser.java | 6 +-
.../source/hbm/AbstractEntityBinder.java | 4 +-
.../source/hbm/HibernateXmlBinder.java | 29 +-
.../source/{ => internal}/ExtendsQueue.java | 51 +--
.../metamodel/source/internal/JaxbHelper.java | 213 ++++++++++
.../JaxbRoot.java} | 19 +-
.../source/internal/MetadataImpl.java | 371 ++++++++++++++++++
.../{ => internal}/MetadataSourceQueue.java | 6 +-
.../MetadataImplementor.java} | 34 +-
.../metamodel/source/util/xml/XmlHelper.java | 6 +-
.../binding/BasicAnnotationBindingTests.java | 7 +-
.../binding/BasicHbmBindingTests.java | 6 +-
.../source/annotations/OrmXmlParserTests.java | 6 +-
22 files changed, 990 insertions(+), 252 deletions(-)
create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingException.java
create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingNotFoundException.java
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{util/xml => }/Origin.java (78%)
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{util/xml/JaxbRoot.java => SourceType.java} (75%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/XsdException.java
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{ => internal}/ExtendsQueue.java (69%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbHelper.java
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{util/xml/JaxbRootImpl.java => internal/JaxbRoot.java} (76%)
create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{ => internal}/MetadataSourceQueue.java (97%)
rename hibernate-core/src/main/java/org/hibernate/metamodel/source/{util/xml/OriginImpl.java => spi/MetadataImplementor.java} (70%)
diff --git a/hibernate-core/src/main/java/org/hibernate/HibernateException.java b/hibernate-core/src/main/java/org/hibernate/HibernateException.java
index 722099fa4c..52be3448b4 100644
--- a/hibernate-core/src/main/java/org/hibernate/HibernateException.java
+++ b/hibernate-core/src/main/java/org/hibernate/HibernateException.java
@@ -35,16 +35,16 @@ package org.hibernate;
* @author Gavin King
*/
public class HibernateException extends RuntimeException {
- public HibernateException(String s) {
- super(s);
+ public HibernateException(String message) {
+ super( message );
}
public HibernateException(Throwable root) {
- super(root);
+ super( root );
}
- public HibernateException(String string, Throwable root) {
- super(string, root);
+ public HibernateException(String message, Throwable root) {
+ super( message, root );
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingException.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingException.java
new file mode 100644
index 0000000000..279879e41f
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingException.java
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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.metamodel.source;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates a problem parsing a mapping document.
+ *
+ * @author Steve Ebersole
+ */
+public class MappingException extends HibernateException {
+ private final Origin origin;
+
+ public MappingException(String message, Origin origin) {
+ super( message );
+ this.origin = origin;
+ }
+
+ public MappingException(String message, Throwable root, Origin origin) {
+ super( message, root );
+ this.origin = origin;
+ }
+
+ public Origin getOrigin() {
+ return origin;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingNotFoundException.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingNotFoundException.java
new file mode 100644
index 0000000000..3e56633c35
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/MappingNotFoundException.java
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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.metamodel.source;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MappingNotFoundException extends MappingException {
+ public MappingNotFoundException(String message, Origin origin) {
+ super( message, origin );
+ }
+
+ public MappingNotFoundException(Origin origin) {
+ super( String.format( "Mapping (%s) not found : %s", origin.getType(), origin.getName() ), origin );
+ }
+
+ public MappingNotFoundException(String message, Throwable root, Origin origin) {
+ super( message, root, origin );
+ }
+
+ public MappingNotFoundException(Throwable root, Origin origin) {
+ super( String.format( "Mapping (%s) not found : %s", origin.getType(), origin.getName() ), root, origin );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java
index e19d7def70..2ef0eb9e97 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Metadata.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * Copyright (c) 2011, 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.
@@ -21,156 +21,160 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
+
package org.hibernate.metamodel.source;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
-import org.jboss.logging.Logger;
-
-import org.hibernate.DuplicateMappingException;
-import org.hibernate.cfg.EJB3NamingStrategy;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.internal.CoreMessageLogger;
-import org.hibernate.mapping.FetchProfile;
-import org.hibernate.mapping.MetadataSource;
-import org.hibernate.metamodel.binding.EntityBinding;
-import org.hibernate.metamodel.binding.PluralAttributeBinding;
-import org.hibernate.metamodel.relational.Database;
-import org.hibernate.metamodel.source.annotations.AnnotationBinder;
-import org.hibernate.metamodel.source.hbm.HibernateXmlBinder;
-import org.hibernate.service.BasicServiceRegistry;
+import org.w3c.dom.Document;
/**
- * Container for configuration data while building and binding the metamodel
- *
* @author Steve Ebersole
*/
-public class Metadata implements Serializable {
- private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, Metadata.class.getName() );
+public interface Metadata {
+ /**
+ * Read metadata from the annotations attached to the given class.
+ *
+ * @param annotatedClass The class containing annotations
+ *
+ * @return this (for method chaining)
+ */
+ public Metadata addAnnotatedClass(Class annotatedClass);
- private final BasicServiceRegistry serviceRegistry;
+ /**
+ * Read package-level metadata.
+ *
+ * @param packageName java package name
+ *
+ * @return this (for method chaining)
+ */
+ public Metadata addPackage(String packageName);
- private final AnnotationBinder annotationBinder;
- private final HibernateXmlBinder hibernateXmlBinder;
+ /**
+ * Read mappings as a application resourceName (i.e. classpath lookup).
+ *
+ * @param name The resource name
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addResource(String name);
- private final Database database = new Database();
+ /**
+ * Read a mapping as an application resource using the convention that a class named {@code foo.bar.Foo} is
+ * mapped by a file named {@code foo/bar/Foo.hbm.xml} which can be resolved as a classpath resource.
+ *
+ * @param entityClass The mapped class
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addClass(Class entityClass);
- private final ExtendsQueue extendsQueue;
- private final MetadataSourceQueue metadataSourceQueue;
+ /**
+ * Read mappings from a particular XML file
+ *
+ * @param path The path to a file. Expected to be resolvable by {@link File#File(String)}
+ *
+ * @return this (for method chaining purposes)
+ *
+ * @see #addFile(java.io.File)
+ */
+ public Metadata addFile(String path);
- private NamingStrategy namingStrategy = EJB3NamingStrategy.INSTANCE;
- private Map entityBindingMap = new HashMap();
- private Map collectionBindingMap = new HashMap();
- private Map fetchProfiles = new HashMap();
- private Map imports;
+ /**
+ * Read mappings from a particular XML file
+ *
+ * @param file The reference to the XML file
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addFile(File file);
- public Metadata(BasicServiceRegistry serviceRegistry) {
- this.serviceRegistry = serviceRegistry;
- this.annotationBinder = new AnnotationBinder( this );
- this.hibernateXmlBinder = new HibernateXmlBinder( this );
- this.extendsQueue = new ExtendsQueue( this );
- this.metadataSourceQueue = new MetadataSourceQueue( this );
- }
+ /**
+ * See {@link #addCacheableFile(java.io.File)} for description
+ *
+ * @param path The path to a file. Expected to be resolvable by {@link File#File(String)}
+ *
+ * @return this (for method chaining purposes)
+ *
+ * @see #addCacheableFile(java.io.File)
+ */
+ public Metadata addCacheableFile(String path);
- public BasicServiceRegistry getServiceRegistry() {
- return serviceRegistry;
- }
+ /**
+ * 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 call as a file with the name {@code {xmlFile}.bin}
+ * where {@code {xmlFile}} is the name of the original mapping file.
+ *
+ * If a cached {@code {xmlFile}.bin} exists and is newer than {@code {xmlFile}}, the {@code {xmlFile}.bin}
+ * file will be read directly. Otherwise {@code {xmlFile}} is read and then serialized to {@code {xmlFile}.bin} for
+ * use the next time.
+ *
+ * @param file The cacheable mapping file to be added, {@code {xmlFile}} in above discussion.
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addCacheableFile(File file);
- public HibernateXmlBinder getHibernateXmlBinder() {
- return hibernateXmlBinder;
- }
+ /**
+ * Read metadata from an {@link InputStream}.
+ *
+ * @param xmlInputStream The input stream containing a DOM.
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addInputStream(InputStream xmlInputStream);
- public AnnotationBinder getAnnotationBinder() {
- return annotationBinder;
- }
- public ExtendsQueue getExtendsQueue() {
- return extendsQueue;
- }
+ /**
+ * Read mappings from a {@link URL}
+ *
+ * @param url The url for the mapping document to be read.
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addURL(URL url);
- public MetadataSourceQueue getMetadataSourceQueue() {
- return metadataSourceQueue;
- }
+ /**
+ * Read mappings from a string representation of the XML
+ *
+ * @param xml an XML string
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addXML(String xml);
- public Database getDatabase() {
- return database;
- }
+ /**
+ * Read mappings from a DOM {@link Document}
+ *
+ * @param doc The DOM document
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addDocument(Document doc);
- public NamingStrategy getNamingStrategy() {
- return namingStrategy;
- }
- public void setNamingStrategy(NamingStrategy namingStrategy) {
- this.namingStrategy = namingStrategy;
- }
+ /**
+ * Read all mappings from a jar file.
+ *
+ * Assumes that any file named *.hbm.xml is a mapping document.
+ *
+ * @param jar a jar file
+ *
+ * @return this (for method chaining purposes)
+ */
+ public Metadata addJar(File jar);
- public EntityBinding getEntityBinding(String entityName) {
- return entityBindingMap.get( entityName );
- }
-
- public Iterable getEntityBindings() {
- return entityBindingMap.values();
- }
-
- public void addEntity(EntityBinding entityBinding) {
- final String entityName = entityBinding.getEntity().getName();
- if ( entityBindingMap.containsKey( entityName ) ) {
- throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
- }
- entityBindingMap.put( entityName, entityBinding );
- }
-
- public PluralAttributeBinding getCollection(String collectionRole) {
- return collectionBindingMap.get( collectionRole );
- }
-
- public Iterable getCollections() {
- return collectionBindingMap.values();
- }
-
- public void addCollection(PluralAttributeBinding pluralAttributeBinding) {
- final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName();
- final String attributeName = pluralAttributeBinding.getAttribute().getName();
- final String collectionRole = owningEntityName + '.' + attributeName;
- if ( collectionBindingMap.containsKey( collectionRole ) ) {
- throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, collectionRole );
- }
- collectionBindingMap.put( collectionRole, pluralAttributeBinding );
- }
-
- public void addImport(String importName, String entityName) {
- if ( imports == null ) {
- imports = new HashMap();
- }
- LOG.trace( "Import: " + importName + " -> " + entityName );
- String old = imports.put( importName, entityName );
- if ( old != null ) {
- LOG.debug( "import name [" + importName + "] overrode previous [{" + old + "}]" );
- }
- }
-
- public Iterable getFetchProfiles() {
- return fetchProfiles.values();
- }
-
- public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
- FetchProfile profile = fetchProfiles.get( profileName );
- if ( profile == null ) {
- profile = new FetchProfile( profileName, source );
- fetchProfiles.put( profileName, profile );
- }
- return profile;
- }
-
- private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
- ois.defaultReadObject();
- }
-
- private void writeObject(java.io.ObjectOutputStream out) throws IOException {
- out.defaultWriteObject();
- }
+ /**
+ * Read all mapping documents from a directory tree.
+ *
+ * Assumes that any file named *.hbm.xml is a mapping document.
+ *
+ * @param dir The directory
+ * @return this (for method chaining purposes)
+ * @throws org.hibernate.MappingException Indicates problems reading the jar file or
+ * processing the contained mapping documents.
+ */
+ public Metadata addDirectory(File dir);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/Origin.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Origin.java
similarity index 78%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/Origin.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/Origin.java
index 950fa3f1d4..824d433bd8 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/Origin.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/Origin.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source.util.xml;
+package org.hibernate.metamodel.source;
import java.io.Serializable;
@@ -30,14 +30,23 @@ import java.io.Serializable;
*
* @author Steve Ebersole
*/
-public interface Origin extends Serializable {
+public class Origin implements Serializable {
+ private final SourceType type;
+ private final String name;
+
+ public Origin(SourceType type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
/**
- * 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.
+ * Retrieve the type of origin.
*
* @return The origin type.
*/
- public String getType();
+ public SourceType getType() {
+ return type;
+ }
/**
* The name of the document origin. Interpretation is relative to the type, but might be the
@@ -45,5 +54,7 @@ public interface Origin extends Serializable {
*
* @return The name.
*/
- public String getName();
+ public String getName() {
+ return name;
+ }
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRoot.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/SourceType.java
similarity index 75%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRoot.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/SourceType.java
index 8fd807e438..e7a158f64f 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRoot.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/SourceType.java
@@ -21,25 +21,20 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source.util.xml;
+
+package org.hibernate.metamodel.source;
/**
- * Describes a parsed xml document.
+ * From where did the metadata come from?
*
- * @author Hardy Ferentschik
+ * @author Steve Ebersole
*/
-public interface JaxbRoot {
- /**
- * Retrieve the jaxb root
- *
- * @return the jaxb root object
- */
- public T getRoot();
-
- /**
- * Retrieve the document's origin.
- *
- * @return The origin
- */
- public Origin getOrigin();
+public enum SourceType {
+ RESOURCE,
+ FILE,
+ INPUT_STREAM,
+ URL,
+ STRING,
+ DOM,
+ JAR
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/XsdException.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/XsdException.java
new file mode 100644
index 0000000000..fac0104bf9
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/XsdException.java
@@ -0,0 +1,50 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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.metamodel.source;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates an issue finding or loading an XSD schema.
+ *
+ * @author Steve Ebersole
+ */
+public class XsdException extends HibernateException {
+ private final String xsdName;
+
+ public XsdException(String message, String xsdName) {
+ super( message );
+ this.xsdName = xsdName;
+ }
+
+ public XsdException(String message, Throwable root, String xsdName) {
+ super( message, root );
+ this.xsdName = xsdName;
+ }
+
+ public String getXsdName() {
+ return xsdName;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
index 61353de2a1..9539bdc97a 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java
@@ -32,7 +32,7 @@ import org.jboss.jandex.Index;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
* Main class responsible to creating and binding the Hibernate meta-model from annotations.
@@ -45,9 +45,9 @@ import org.hibernate.metamodel.source.Metadata;
*/
public class AnnotationBinder {
private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
- private final Metadata metadata;
+ private final MetadataImpl metadata;
- public AnnotationBinder(Metadata metadata) {
+ public AnnotationBinder(MetadataImpl metadata) {
this.metadata = metadata;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java
index 42fa1a3841..c6127626bf 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java
@@ -30,7 +30,7 @@ import org.hibernate.AssertionFailure;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.domain.Entity;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
/**
* @author Hardy Ferentschik
@@ -38,7 +38,7 @@ import org.hibernate.metamodel.source.Metadata;
public class EntityBinder {
private final ClassInfo classToBind;
- public EntityBinder(Metadata metadata, ClassInfo classInfo, AnnotationInstance jpaEntityAnnotation, AnnotationInstance hibernateEntityAnnotation) {
+ public EntityBinder(MetadataImpl metadata, ClassInfo classInfo, AnnotationInstance jpaEntityAnnotation, AnnotationInstance hibernateEntityAnnotation) {
this.classToBind = classInfo;
EntityBinding entityBinding = new EntityBinding();
bindJpaAnnotation( jpaEntityAnnotation, entityBinding );
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java
index d07dd8f529..e424313f48 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/OrmXmlParser.java
@@ -8,7 +8,7 @@ import javax.xml.bind.JAXBException;
import org.jboss.jandex.Index;
import org.hibernate.AnnotationException;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.metamodel.source.annotation.xml.EntityMappings;
import org.hibernate.metamodel.source.util.xml.XmlHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@@ -21,9 +21,9 @@ public class OrmXmlParser {
private static final String ORM1_MAPPING_XSD = "org/hibernate/ejb/orm_1_0.xsd";
private static final String ORM2_MAPPING_XSD = "org/hibernate/ejb/orm_2_0.xsd";
- private final Metadata meta;
+ private final MetadataImpl meta;
- public OrmXmlParser(Metadata meta) {
+ public OrmXmlParser(MetadataImpl meta) {
this.meta = meta;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java
index 56f585af6b..5ab8ecefa9 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/AbstractEntityBinder.java
@@ -44,7 +44,7 @@ import org.hibernate.metamodel.relational.Schema;
import org.hibernate.metamodel.relational.Table;
import org.hibernate.metamodel.relational.TableSpecification;
import org.hibernate.metamodel.relational.UniqueKey;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.metamodel.source.hbm.state.domain.HbmPluralAttributeDomainState;
import org.hibernate.metamodel.source.hbm.state.domain.HbmSimpleAttributeDomainState;
import org.hibernate.metamodel.source.hbm.state.relational.HbmSimpleValueRelationalStateContainer;
@@ -82,7 +82,7 @@ abstract class AbstractEntityBinder {
return hibernateMappingBinder.getHibernateXmlBinder();
}
- protected Metadata getMetadata() {
+ protected MetadataImpl getMetadata() {
return hibernateMappingBinder.getHibernateXmlBinder().getMetadata();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateXmlBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateXmlBinder.java
index 4b94e5a5be..5ad022fc13 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateXmlBinder.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/hbm/HibernateXmlBinder.java
@@ -40,7 +40,7 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.mapping.MetaAttribute;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.metamodel.source.hbm.xml.mapping.HibernateMapping;
/**
@@ -51,14 +51,14 @@ import org.hibernate.metamodel.source.hbm.xml.mapping.HibernateMapping;
public class HibernateXmlBinder {
private static final Logger log = LoggerFactory.getLogger( HibernateXmlBinder.class );
- private final Metadata metadata;
+ private final MetadataImpl metadata;
private final Map globalMetas;
- public HibernateXmlBinder(Metadata metadata) {
+ public HibernateXmlBinder(MetadataImpl metadata) {
this( metadata, Collections.emptyMap() );
}
- public HibernateXmlBinder(Metadata metadata, Map globalMetas) {
+ public HibernateXmlBinder(MetadataImpl metadata, Map globalMetas) {
this.metadata = metadata;
this.globalMetas = globalMetas;
}
@@ -75,20 +75,21 @@ public class HibernateXmlBinder {
public void bindRoot(XmlDocument metadataXml, Set entityNames) {
final HibernateMappingBinder mappingBinder = new HibernateMappingBinder( this, metadataXml );
- List names = locateEntityNamesAwaitingExtends( metadataXml, mappingBinder );
- if ( !names.isEmpty() ) {
- // classes mentioned in extends not available - so put it in queue
- for ( String name : names ) {
- metadata.getExtendsQueue()
- .add( new ExtendsQueueEntry( name, mappingBinder.getPackageName(), metadataXml, entityNames ) );
- }
- return;
- }
+// this is irrelevant due to HHH-6118 and the fact that now all sources should be
+// List names = locateEntityNamesAwaitingExtends( metadataXml, mappingBinder );
+// if ( !names.isEmpty() ) {
+// // classes mentioned in extends not available - so put it in queue
+// for ( String name : names ) {
+// metadata.getExtendsQueue()
+// .add( new ExtendsQueueEntry( name, mappingBinder.getPackageName(), metadataXml, entityNames ) );
+// }
+// return;
+// }
mappingBinder.processElement();
}
- Metadata getMetadata() {
+ MetadataImpl getMetadata() {
return metadata;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/ExtendsQueue.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/ExtendsQueue.java
similarity index 69%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/ExtendsQueue.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/ExtendsQueue.java
index 3b3c719147..33ab5fdeba 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/ExtendsQueue.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/ExtendsQueue.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source;
+package org.hibernate.metamodel.source.internal;
import java.io.Serializable;
import java.util.HashSet;
@@ -32,6 +32,7 @@ import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.MappingException;
import org.hibernate.cfg.ExtendsQueueEntry;
import org.hibernate.metamodel.source.hbm.HbmHelper;
+
import org.jboss.logging.Logger;
/**
@@ -43,10 +44,10 @@ public class ExtendsQueue implements Serializable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, ExtendsQueue.class.getName());
- private final Metadata metadata;
+ private final MetadataImpl metadata;
private Set extendsQueue = new HashSet();
- public ExtendsQueue(Metadata metadata) {
+ public ExtendsQueue(MetadataImpl metadata) {
this.metadata = metadata;
}
@@ -57,28 +58,28 @@ public class ExtendsQueue implements Serializable {
public int processExtendsQueue() {
LOG.debug( "processing extends queue" );
int added = 0;
- ExtendsQueueEntry extendsQueueEntry = findPossibleExtends();
- while ( extendsQueueEntry != null ) {
- metadata.getMetadataSourceQueue().processHbmXml( extendsQueueEntry.getMetadataXml(), extendsQueueEntry.getEntityNames() );
- extendsQueueEntry = findPossibleExtends();
- }
-
- if ( extendsQueue.size() > 0 ) {
- Iterator iterator = extendsQueue.iterator();
- StringBuffer buf = new StringBuffer( "Following super classes referenced in extends not found: " );
- while ( iterator.hasNext() ) {
- final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
- buf.append( entry.getExplicitName() );
- if ( entry.getMappingPackage() != null ) {
- buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
- }
- if ( iterator.hasNext() ) {
- buf.append( "," );
- }
- }
- throw new MappingException( buf.toString() );
- }
-
+// ExtendsQueueEntry extendsQueueEntry = findPossibleExtends();
+// while ( extendsQueueEntry != null ) {
+// metadata.getMetadataSourceQueue().processHbmXml( extendsQueueEntry.getMetadataXml(), extendsQueueEntry.getEntityNames() );
+// extendsQueueEntry = findPossibleExtends();
+// }
+//
+// if ( extendsQueue.size() > 0 ) {
+// Iterator iterator = extendsQueue.iterator();
+// StringBuffer buf = new StringBuffer( "Following super classes referenced in extends not found: " );
+// while ( iterator.hasNext() ) {
+// final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
+// buf.append( entry.getExplicitName() );
+// if ( entry.getMappingPackage() != null ) {
+// buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
+// }
+// if ( iterator.hasNext() ) {
+// buf.append( "," );
+// }
+// }
+// throw new MappingException( buf.toString() );
+// }
+//
return added;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbHelper.java
new file mode 100644
index 0000000000..72059c018c
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbHelper.java
@@ -0,0 +1,213 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2011, 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.metamodel.source.internal;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.jboss.logging.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.EJB3DTDEntityResolver;
+import org.hibernate.internal.util.xml.ErrorLogger;
+import org.hibernate.metamodel.source.MappingException;
+import org.hibernate.metamodel.source.Origin;
+import org.hibernate.metamodel.source.SourceType;
+import org.hibernate.metamodel.source.XsdException;
+import org.hibernate.metamodel.source.annotation.xml.EntityMappings;
+import org.hibernate.metamodel.source.hbm.xml.mapping.HibernateMapping;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+
+/**
+ * @author Steve Ebersole
+ */
+class JaxbHelper {
+ private static final Logger log = Logger.getLogger( JaxbHelper.class );
+
+ public static final String ASSUMED_ORM_XSD_VERSION = "2.0";
+
+ private final MetadataImpl metadata;
+
+ JaxbHelper(MetadataImpl metadata) {
+ this.metadata = metadata;
+ }
+
+ public JaxbRoot unmarshal(InputSource source, Origin origin) {
+ ErrorLogger errorHandler = new ErrorLogger();
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating( false ); // we will validate separately
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ builder.setEntityResolver( metadata.getEntityResolver() );
+ builder.setErrorHandler( errorHandler );
+ return unmarshal( builder.parse( source ), origin );
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new MappingException( "Unable to read DOM via JAXP", e, origin );
+ }
+ }
+
+ @SuppressWarnings( {"unchecked"})
+ public JaxbRoot unmarshal(Document document, Origin origin) {
+ Element rootElement = document.getDocumentElement();
+ if ( rootElement == null ) {
+ throw new MappingException( "No root element found", origin );
+ }
+
+ final Schema validationSchema;
+ final Class jaxbTarget;
+
+ if ( "entity-mappings".equals( rootElement.getLocalName() ) ) {
+ final String explicitVersion = rootElement.getAttribute( "version" );
+ validationSchema = resolveSupportedOrmXsd( explicitVersion );
+ jaxbTarget = EntityMappings.class;
+ }
+ else {
+ validationSchema = hbmSchema();
+ jaxbTarget = HibernateMapping.class;
+ }
+
+ try {
+ validationSchema.newValidator().validate( new DOMSource( rootElement.getOwnerDocument() ) );
+ }
+ catch ( SAXException e ) {
+ throw new MappingException( "Validation problem", e, origin );
+ }
+ catch ( IOException e ) {
+ throw new MappingException( "Validation problem", e, origin );
+ }
+
+ final Object target;
+ try {
+ JAXBContext jaxbContext = JAXBContext.newInstance( jaxbTarget );
+ Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ target = unmarshaller.unmarshal( document );
+ }
+ catch (JAXBException e) {
+ throw new MappingException( "Unable to perform unmarshalling", e, origin );
+ }
+
+ return new JaxbRoot( target, origin );
+ }
+
+ private Schema resolveSupportedOrmXsd(String explicitVersion) {
+ final String xsdVersionString = explicitVersion == null ? ASSUMED_ORM_XSD_VERSION : explicitVersion;
+ if ( "1.0".equals( xsdVersionString ) ) {
+ return orm1Schema();
+ }
+ else if ( "2.0".equals( xsdVersionString ) ) {
+ return orm1Schema();
+ }
+ throw new IllegalArgumentException( "Unsupported orm.xml XSD version encountered [" + xsdVersionString + "]" );
+ }
+
+ public static final String HBM_SCHEMA_NAME = "/org/hibernate/hibernate-mapping-4.0.xsd";
+ 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 Schema hbmSchema;
+
+ private Schema hbmSchema() {
+ if ( hbmSchema == null ) {
+ hbmSchema = resolveLocalSchema( HBM_SCHEMA_NAME );
+ }
+ return hbmSchema;
+ }
+
+ private Schema orm1Schema;
+
+ private Schema orm1Schema() {
+ if ( orm1Schema == null ) {
+ orm1Schema = resolveLocalSchema( ORM_1_SCHEMA_NAME );
+ }
+ return orm1Schema;
+ }
+
+ private Schema orm2Schema;
+
+ private Schema orm2Schema() {
+ if ( orm2Schema == null ) {
+ orm2Schema = resolveLocalSchema( ORM_2_SCHEMA_NAME );
+ }
+ return orm2Schema;
+ }
+
+ private Schema resolveLocalSchema(String schemaName) {
+ return resolveLocalSchema( schemaName, XMLConstants.W3C_XML_SCHEMA_NS_URI );
+ }
+
+ private Schema resolveLocalSchema(String schemaName, String schemaLanguage) {
+ URL url = metadata.getServiceRegistry().getService( ClassLoaderService.class ).locateResource( schemaName );
+ if ( url == null ) {
+ throw new XsdException( "Unable to locate schema [" + schemaName + "] via classpath", schemaName );
+ }
+ 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 XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
+ }
+ catch ( IOException e ) {
+ throw new XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
+ }
+ finally {
+ try {
+ schemaStream.close();
+ }
+ catch ( IOException e ) {
+ log.debugf( "Problem closing schema stream [%s]", e.toString() );
+ }
+ }
+ }
+ catch ( IOException e ) {
+ throw new XsdException( "Stream error handling schema url [" + url.toExternalForm() + "]", schemaName );
+ }
+ }
+
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRootImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbRoot.java
similarity index 76%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRootImpl.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbRoot.java
index 6eb740184b..888b05aecb 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/JaxbRootImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/JaxbRoot.java
@@ -21,31 +21,38 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source.util.xml;
+package org.hibernate.metamodel.source.internal;
+
+import org.hibernate.metamodel.source.Origin;
/**
- * Basic implementation of {@link JaxbRoot}.
+ * Holds information about a JAXB-unmarshalled XML document.
*
* @author Hardy Ferentschik
+ * @author Steve Ebersole
*/
-public class JaxbRootImpl implements JaxbRoot {
+public class JaxbRoot {
private final T root;
private final Origin origin;
- public JaxbRootImpl(T root, Origin origin) {
+ public JaxbRoot(T root, Origin origin) {
this.root = root;
this.origin = origin;
}
/**
- * {@inheritDoc}
+ * Obtain the root JAXB bound object
+ *
+ * @return The JAXB root object
*/
public T getRoot() {
return root;
}
/**
- * {@inheritDoc}
+ * Obtain the metadata about the document's origin
+ *
+ * @return The origin
*/
public Origin getOrigin() {
return origin;
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
new file mode 100644
index 0000000000..300540f09c
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataImpl.java
@@ -0,0 +1,371 @@
+/*
+ * 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.metamodel.source.internal;
+
+import javax.xml.transform.dom.DOMSource;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.jboss.logging.Logger;
+import org.w3c.dom.Document;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+import org.hibernate.DuplicateMappingException;
+import org.hibernate.cfg.EJB3DTDEntityResolver;
+import org.hibernate.cfg.EJB3NamingStrategy;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.xml.XmlDocumentImpl;
+import org.hibernate.mapping.FetchProfile;
+import org.hibernate.mapping.MetadataSource;
+import org.hibernate.metamodel.binding.EntityBinding;
+import org.hibernate.metamodel.binding.PluralAttributeBinding;
+import org.hibernate.metamodel.relational.Database;
+import org.hibernate.metamodel.source.MappingException;
+import org.hibernate.metamodel.source.MappingNotFoundException;
+import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.Origin;
+import org.hibernate.metamodel.source.SourceType;
+import org.hibernate.metamodel.source.annotations.AnnotationBinder;
+import org.hibernate.metamodel.source.hbm.HibernateXmlBinder;
+import org.hibernate.metamodel.source.spi.MetadataImplementor;
+import org.hibernate.service.BasicServiceRegistry;
+import org.hibernate.service.classloading.spi.ClassLoaderService;
+
+/**
+ * Container for configuration data while building and binding the metamodel
+ *
+ * @author Steve Ebersole
+ */
+public class MetadataImpl implements Metadata, MetadataImplementor, Serializable {
+ private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, MetadataImpl.class.getName() );
+
+ private final BasicServiceRegistry serviceRegistry;
+
+ private final Database database = new Database();
+
+// private final MetadataSourceQueue metadataSourceQueue;
+
+ private final JaxbHelper jaxbHelper;
+ private final AnnotationBinder annotationBinder;
+ private final HibernateXmlBinder hibernateXmlBinder;
+
+ private final EntityResolver entityResolver;
+ private final NamingStrategy namingStrategy;
+ private Map entityBindingMap = new HashMap();
+ private Map collectionBindingMap = new HashMap();
+ private Map fetchProfiles = new HashMap();
+ private Map imports;
+
+ public MetadataImpl(BasicServiceRegistry serviceRegistry) {
+ this( serviceRegistry, EJB3NamingStrategy.INSTANCE, EJB3DTDEntityResolver.INSTANCE );
+ }
+
+ public MetadataImpl(BasicServiceRegistry serviceRegistry, NamingStrategy namingStrategy, EntityResolver entityResolver) {
+ this.serviceRegistry = serviceRegistry;
+ this.namingStrategy = namingStrategy;
+ this.entityResolver = entityResolver;
+ this.jaxbHelper = new JaxbHelper( this );
+ this.annotationBinder = new AnnotationBinder( this );
+ this.hibernateXmlBinder = new HibernateXmlBinder( this );
+// this.metadataSourceQueue = new MetadataSourceQueue( this );
+ }
+
+ public BasicServiceRegistry getServiceRegistry() {
+ return serviceRegistry;
+ }
+
+ public EntityResolver getEntityResolver() {
+ return entityResolver;
+ }
+
+ public HibernateXmlBinder getHibernateXmlBinder() {
+ return hibernateXmlBinder;
+ }
+
+ public AnnotationBinder getAnnotationBinder() {
+ return annotationBinder;
+ }
+
+// public MetadataSourceQueue getMetadataSourceQueue() {
+// return metadataSourceQueue;
+// }
+
+ public Database getDatabase() {
+ return database;
+ }
+
+ public NamingStrategy getNamingStrategy() {
+ return namingStrategy;
+ }
+
+ public EntityBinding getEntityBinding(String entityName) {
+ return entityBindingMap.get( entityName );
+ }
+
+ public Iterable getEntityBindings() {
+ return entityBindingMap.values();
+ }
+
+ public void addEntity(EntityBinding entityBinding) {
+ final String entityName = entityBinding.getEntity().getName();
+ if ( entityBindingMap.containsKey( entityName ) ) {
+ throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, entityName );
+ }
+ entityBindingMap.put( entityName, entityBinding );
+ }
+
+ public PluralAttributeBinding getCollection(String collectionRole) {
+ return collectionBindingMap.get( collectionRole );
+ }
+
+ public Iterable getCollections() {
+ return collectionBindingMap.values();
+ }
+
+ public void addCollection(PluralAttributeBinding pluralAttributeBinding) {
+ final String owningEntityName = pluralAttributeBinding.getEntityBinding().getEntity().getName();
+ final String attributeName = pluralAttributeBinding.getAttribute().getName();
+ final String collectionRole = owningEntityName + '.' + attributeName;
+ if ( collectionBindingMap.containsKey( collectionRole ) ) {
+ throw new DuplicateMappingException( DuplicateMappingException.Type.ENTITY, collectionRole );
+ }
+ collectionBindingMap.put( collectionRole, pluralAttributeBinding );
+ }
+
+ public void addImport(String importName, String entityName) {
+ if ( imports == null ) {
+ imports = new HashMap();
+ }
+ LOG.trace( "Import: " + importName + " -> " + entityName );
+ String old = imports.put( importName, entityName );
+ if ( old != null ) {
+ LOG.debug( "import name [" + importName + "] overrode previous [{" + old + "}]" );
+ }
+ }
+
+ public Iterable getFetchProfiles() {
+ return fetchProfiles.values();
+ }
+
+ public FetchProfile findOrCreateFetchProfile(String profileName, MetadataSource source) {
+ FetchProfile profile = fetchProfiles.get( profileName );
+ if ( profile == null ) {
+ profile = new FetchProfile( profileName, source );
+ fetchProfiles.put( profileName, profile );
+ }
+ return profile;
+ }
+
+ // Metadata contract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private List jaxbRootList = new ArrayList();
+
+ @Override
+ public Metadata addAnnotatedClass(Class annotatedClass) {
+ return null; // todo : implement method body
+ }
+
+ @Override
+ public Metadata addPackage(String packageName) {
+ return null; // todo : implement method body
+ }
+
+ @Override
+ public Metadata addResource(String name) {
+ LOG.tracef( "reading mappings from resource : %s", name );
+
+ final Origin origin = new Origin( SourceType.RESOURCE, name );
+ InputStream resourceInputStream = classLoaderService().locateResourceStream( name );
+ if ( resourceInputStream == null ) {
+ throw new MappingNotFoundException( origin );
+ }
+ add( resourceInputStream, origin );
+
+ return this;
+ }
+
+ private ClassLoaderService classLoaderService() {
+ return serviceRegistry.getService( ClassLoaderService.class );
+ }
+
+ private JaxbRoot add(InputStream inputStream, Origin origin) {
+ final InputSource inputSource = new InputSource( inputStream );
+ try {
+ return add( inputSource, origin );
+ }
+ finally {
+ try {
+ inputStream.close();
+ }
+ catch ( IOException ignore ) {
+ LOG.trace( "Was unable to close input stream" );
+ }
+ }
+ }
+
+ private JaxbRoot add(InputSource inputSource, Origin origin) {
+ JaxbRoot jaxbRoot = jaxbHelper.unmarshal( inputSource, origin );
+ jaxbRootList.add( jaxbRoot );
+ return jaxbRoot;
+ }
+
+ @Override
+ public Metadata addClass(Class entityClass) {
+ LOG.debugf( "adding resource mappings from class convention : %s", entityClass.getName() );
+ final String mappingResourceName = entityClass.getName().replace( '.', '/' ) + ".hbm.xml";
+ addResource( mappingResourceName );
+ return this;
+ }
+
+ @Override
+ public Metadata addFile(String path) {
+ return addFile( new File( path ) );
+ }
+
+ @Override
+ public Metadata addFile(File file) {
+ final String name = file.getAbsolutePath();
+ LOG.tracef( "reading mappings from file : %s", name );
+ final Origin origin = new Origin( SourceType.FILE, name );
+ final InputSource inputSource;
+ try {
+ inputSource = new InputSource( new FileInputStream( file ) );
+ }
+ catch ( FileNotFoundException e ) {
+ throw new MappingNotFoundException( e, origin );
+ }
+ add( inputSource, origin );
+ return this;
+ }
+
+ @Override
+ public Metadata addCacheableFile(String path) {
+ return null; // todo : implement method body
+ }
+
+ @Override
+ public Metadata addCacheableFile(File file) {
+ return null; // todo : implement method body
+ }
+
+ @Override
+ public Metadata addInputStream(InputStream xmlInputStream) {
+ add( xmlInputStream, new Origin( SourceType.INPUT_STREAM, "" ) );
+ return this;
+ }
+
+ @Override
+ public Metadata addURL(URL url) {
+ final String urlExternalForm = url.toExternalForm();
+ LOG.debugf("Reading mapping document from URL : %s", urlExternalForm);
+
+ final Origin origin = new Origin( SourceType.URL, urlExternalForm );
+ try {
+ add( url.openStream(), origin );
+ }
+ catch ( IOException e ) {
+ throw new MappingNotFoundException( "Unable to open url stream [" + urlExternalForm + "]", e, origin );
+ }
+ return this;
+ }
+
+ @Override
+ public Metadata addXML(String xml) {
+ final InputSource inputSource = new InputSource( new StringReader( xml ) );
+ add( inputSource, new Origin( SourceType.STRING, "" ) );
+ return this;
+ }
+
+ @Override
+ public Metadata addDocument(Document document) {
+ final Origin origin = new Origin( SourceType.DOM, "" );
+ JaxbRoot jaxbRoot = jaxbHelper.unmarshal( document, origin );
+ jaxbRootList.add( jaxbRoot );
+ return this;
+ }
+
+ @Override
+ public Metadata addJar(File jar) {
+ LOG.debugf( "Seeking mapping documents in jar file : %s", jar.getName() );
+ final Origin origin = new Origin( SourceType.JAR, jar.getAbsolutePath() );
+ try {
+ JarFile jarFile = new JarFile( jar );
+ try {
+ Enumeration jarEntries = jarFile.entries();
+ while ( jarEntries.hasMoreElements() ) {
+ final ZipEntry zipEntry = (ZipEntry) jarEntries.nextElement();
+ if ( zipEntry.getName().endsWith( ".hbm.xml" ) ) {
+ LOG.tracef( "found mapping document : %s", zipEntry.getName() );
+ try {
+ add( jarFile.getInputStream( zipEntry ), origin );
+ }
+ catch (Exception e) {
+ throw new MappingException( "could not read mapping documents", e, origin );
+ }
+ }
+ }
+ }
+ finally {
+ try {
+ jarFile.close();
+ }
+ catch (Exception ignore) {
+ }
+ }
+ }
+ catch (IOException e) {
+ throw new MappingNotFoundException( e, origin );
+ }
+ return this;
+ }
+
+ @Override
+ public Metadata addDirectory(File dir) {
+ File[] files = dir.listFiles();
+ for ( File file : files ) {
+ if ( file.isDirectory() ) {
+ addDirectory( file );
+ }
+ else if ( file.getName().endsWith( ".hbm.xml" ) ) {
+ addFile( file );
+ }
+ }
+ return this;
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataSourceQueue.java
similarity index 97%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataSourceQueue.java
index cf67136adf..018b93e388 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/MetadataSourceQueue.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/internal/MetadataSourceQueue.java
@@ -21,7 +21,7 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source;
+package org.hibernate.metamodel.source.internal;
import java.io.IOException;
import java.io.ObjectInputStream;
@@ -56,14 +56,14 @@ public class MetadataSourceQueue implements Serializable {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class, MetadataSourceQueue.class.getName()
);
- private final Metadata metadata;
+ private final MetadataImpl metadata;
private LinkedHashMap> hbmMetadataToEntityNamesMap
= new LinkedHashMap>();
private Map hbmMetadataByEntityNameXRef = new HashMap();
private transient List annotatedClasses = new ArrayList();
- public MetadataSourceQueue(Metadata metadata) {
+ public MetadataSourceQueue(MetadataImpl metadata) {
this.metadata = metadata;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/OriginImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
similarity index 70%
rename from hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/OriginImpl.java
rename to hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
index aa4aaa89ee..cc4b3194f2 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/OriginImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/spi/MetadataImplementor.java
@@ -21,33 +21,19 @@
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
-package org.hibernate.metamodel.source.util.xml;
+package org.hibernate.metamodel.source.spi;
+
+import org.hibernate.metamodel.binding.EntityBinding;
+import org.hibernate.metamodel.relational.Database;
+import org.hibernate.service.BasicServiceRegistry;
/**
- * Basic implementation of {@link org.hibernate.internal.util.xml.Origin}
- *
* @author Steve Ebersole
*/
-public class OriginImpl implements Origin {
- private final String type;
- private final String name;
+public interface MetadataImplementor {
+ public BasicServiceRegistry getServiceRegistry();
+ public Database getDatabase();
- public OriginImpl(String type, String name) {
- this.type = type;
- this.name = name;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getType() {
- return type;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getName() {
- return name;
- }
+ public Iterable getEntityBindings();
+ public EntityBinding getEntityBinding(String entityName);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/XmlHelper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/XmlHelper.java
index 0cfb7ba67f..e714f03ab0 100644
--- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/XmlHelper.java
+++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/util/xml/XmlHelper.java
@@ -37,6 +37,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
+import org.hibernate.metamodel.source.Origin;
+import org.hibernate.metamodel.source.internal.JaxbRoot;
import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
@@ -57,8 +59,8 @@ public class XmlHelper {
unmarshaller.setSchema( schema );
StreamSource stream = new StreamSource( in );
JAXBElement elem = unmarshaller.unmarshal( stream, clazz );
- Origin origin = new OriginImpl( "", fileName );
- return new JaxbRootImpl( elem.getValue(), origin );
+ Origin origin = new Origin( null, fileName );
+ return new JaxbRoot( elem.getValue(), origin );
}
private static Schema getMappingSchema(String schemaVersion, ClassLoaderService classLoaderService) {
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java
index 5e83142c4a..872004ae9d 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java
@@ -30,7 +30,8 @@ import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import org.junit.Test;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
+
import org.hibernate.testing.FailureExpected;
import static org.junit.Assert.fail;
@@ -56,7 +57,7 @@ public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
public EntityBinding buildSimpleEntityBinding() {
Index index = indexForClass( SimpleEntity.class );
- Metadata metadata = new Metadata( basicServiceRegistry() );
+ MetadataImpl metadata = new MetadataImpl( basicServiceRegistry() );
metadata.getAnnotationBinder().bindMappedClasses( index );
return metadata.getEntityBinding( SimpleEntity.class.getSimpleName() );
@@ -64,7 +65,7 @@ public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
public EntityBinding buildSimpleVersionedEntityBinding() {
Index index = indexForClass( SimpleEntity.class );
- Metadata metadata = new Metadata( basicServiceRegistry() );
+ MetadataImpl metadata = new MetadataImpl( basicServiceRegistry() );
metadata.getAnnotationBinder().bindMappedClasses( index );
return metadata.getEntityBinding( SimpleVersionedEntity.class.getSimpleName() );
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java
index a2b236f511..1f7f798ff9 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicHbmBindingTests.java
@@ -33,7 +33,7 @@ import org.hibernate.internal.util.xml.MappingReader;
import org.hibernate.internal.util.xml.Origin;
import org.hibernate.internal.util.xml.XMLHelper;
import org.hibernate.internal.util.xml.XmlDocument;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.metamodel.source.hbm.xml.mapping.HibernateMapping;
import org.hibernate.metamodel.source.util.xml.XmlHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
@@ -49,7 +49,7 @@ public class BasicHbmBindingTests extends AbstractBasicBindingTests {
private static final Logger log = Logger.getLogger( BasicHbmBindingTests.class.getName() );
public EntityBinding buildSimpleEntityBinding() {
- Metadata metadata = new Metadata( basicServiceRegistry() );
+ MetadataImpl metadata = new MetadataImpl( basicServiceRegistry() );
XmlDocument xmlDocument = readResource( "/org/hibernate/metamodel/binding/SimpleEntity.hbm.xml" );
metadata.getHibernateXmlBinder().bindRoot( xmlDocument );
@@ -57,7 +57,7 @@ public class BasicHbmBindingTests extends AbstractBasicBindingTests {
}
public EntityBinding buildSimpleVersionedEntityBinding() {
- Metadata metadata = new Metadata( basicServiceRegistry() );
+ MetadataImpl metadata = new MetadataImpl( basicServiceRegistry() );
String fileName = "/org/hibernate/metamodel/binding/SimpleVersionedEntity.hbm.xml";
XmlDocument xmlDocument = readResource( fileName );
diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java
index cfad6c17e6..97585e5c38 100644
--- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java
+++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/OrmXmlParserTests.java
@@ -6,7 +6,7 @@ import java.util.Set;
import org.junit.Test;
-import org.hibernate.metamodel.source.Metadata;
+import org.hibernate.metamodel.source.internal.MetadataImpl;
import org.hibernate.service.internal.BasicServiceRegistryImpl;
import org.hibernate.testing.junit4.BaseUnitTestCase;
@@ -16,7 +16,7 @@ import org.hibernate.testing.junit4.BaseUnitTestCase;
public class OrmXmlParserTests extends BaseUnitTestCase {
@Test
public void testSingleOrmXml() {
- OrmXmlParser parser = new OrmXmlParser( new Metadata( new BasicServiceRegistryImpl( Collections.emptyMap() ) ) );
+ OrmXmlParser parser = new OrmXmlParser( new MetadataImpl( new BasicServiceRegistryImpl( Collections.emptyMap() ) ) );
Set xmlFiles = new HashSet();
xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm.xml" );
parser.parseAndUpdateIndex( xmlFiles, null );
@@ -24,7 +24,7 @@ public class OrmXmlParserTests extends BaseUnitTestCase {
@Test
public void testOrmXmlWithOldSchema() {
- OrmXmlParser parser = new OrmXmlParser( new Metadata( new BasicServiceRegistryImpl( Collections.emptyMap() ) ) );
+ OrmXmlParser parser = new OrmXmlParser( new MetadataImpl( new BasicServiceRegistryImpl( Collections.emptyMap() ) ) );
Set xmlFiles = new HashSet();
xmlFiles.add( "org/hibernate/metamodel/source/annotations/orm2.xml" );
parser.parseAndUpdateIndex( xmlFiles, null );