mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-08 20:24:46 +00:00
HHH-14529 Implement the (opt-in) orm.xml handling using JAXB
This commit is contained in:
parent
10aee2a9fa
commit
ac4f4ff4ad
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.boot.jaxb.mapping.spi;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.LockModeType;
|
||||||
|
|
||||||
|
public interface NamedQuery extends Serializable {
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
void setDescription(String value);
|
||||||
|
|
||||||
|
String getQuery();
|
||||||
|
|
||||||
|
void setQuery(String value);
|
||||||
|
|
||||||
|
LockModeType getLockMode();
|
||||||
|
|
||||||
|
void setLockMode(LockModeType value);
|
||||||
|
|
||||||
|
List<JaxbQueryHint> getHint();
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
void setName(String value);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -23,20 +23,19 @@
|
|||||||
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
import org.hibernate.annotations.common.reflection.AnnotationReader;
|
||||||
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
||||||
import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
|
import org.hibernate.annotations.common.reflection.java.JavaMetadataProvider;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbSequenceGenerator;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbTableGenerator;
|
||||||
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
|
|
||||||
import org.dom4j.Element;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetadataProvider aware of the JPA Deployment descriptor (orm.xml, ...).
|
* MetadataProvider aware of the JPA Deployment descriptor (orm.xml, ...).
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
*/
|
*/
|
||||||
// FIXME HHH-14529 Change this class to use JaxbEntityMappings instead of Document.
|
|
||||||
// I'm delaying this change in order to keep the commits simpler and easier to review.
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final class JPAXMLOverriddenMetadataProvider implements MetadataProvider {
|
public final class JPAXMLOverriddenMetadataProvider implements MetadataProvider {
|
||||||
|
|
||||||
@ -112,28 +111,27 @@ public Map<Object, Object> getDefaults() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaults.put( EntityListeners.class, entityListeners );
|
defaults.put( EntityListeners.class, entityListeners );
|
||||||
for ( Element element : xmlContext.getAllDocuments() ) {
|
for ( JaxbEntityMappings entityMappings : xmlContext.getAllDocuments() ) {
|
||||||
@SuppressWarnings( "unchecked" )
|
List<JaxbSequenceGenerator> jaxbSequenceGenerators = entityMappings.getSequenceGenerator();
|
||||||
List<Element> elements = element.elements( "sequence-generator" );
|
|
||||||
List<SequenceGenerator> sequenceGenerators = ( List<SequenceGenerator> ) defaults.get( SequenceGenerator.class );
|
List<SequenceGenerator> sequenceGenerators = ( List<SequenceGenerator> ) defaults.get( SequenceGenerator.class );
|
||||||
if ( sequenceGenerators == null ) {
|
if ( sequenceGenerators == null ) {
|
||||||
sequenceGenerators = new ArrayList<>();
|
sequenceGenerators = new ArrayList<>();
|
||||||
defaults.put( SequenceGenerator.class, sequenceGenerators );
|
defaults.put( SequenceGenerator.class, sequenceGenerators );
|
||||||
}
|
}
|
||||||
for ( Element subelement : elements ) {
|
for ( JaxbSequenceGenerator element : jaxbSequenceGenerators ) {
|
||||||
sequenceGenerators.add( JPAXMLOverriddenAnnotationReader.buildSequenceGeneratorAnnotation( subelement ) );
|
sequenceGenerators.add( JPAXMLOverriddenAnnotationReader.buildSequenceGeneratorAnnotation( element ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
elements = element.elements( "table-generator" );
|
List<JaxbTableGenerator> jaxbTableGenerators = entityMappings.getTableGenerator();
|
||||||
List<TableGenerator> tableGenerators = ( List<TableGenerator> ) defaults.get( TableGenerator.class );
|
List<TableGenerator> tableGenerators = ( List<TableGenerator> ) defaults.get( TableGenerator.class );
|
||||||
if ( tableGenerators == null ) {
|
if ( tableGenerators == null ) {
|
||||||
tableGenerators = new ArrayList<>();
|
tableGenerators = new ArrayList<>();
|
||||||
defaults.put( TableGenerator.class, tableGenerators );
|
defaults.put( TableGenerator.class, tableGenerators );
|
||||||
}
|
}
|
||||||
for ( Element subelement : elements ) {
|
for ( JaxbTableGenerator element : jaxbTableGenerators ) {
|
||||||
tableGenerators.add(
|
tableGenerators.add(
|
||||||
JPAXMLOverriddenAnnotationReader.buildTableGeneratorAnnotation(
|
JPAXMLOverriddenAnnotationReader.buildTableGeneratorAnnotation(
|
||||||
subelement, xmlDefaults
|
element, xmlDefaults
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -144,8 +142,7 @@ public Map<Object, Object> getDefaults() {
|
|||||||
defaults.put( NamedQuery.class, namedQueries );
|
defaults.put( NamedQuery.class, namedQueries );
|
||||||
}
|
}
|
||||||
List<NamedQuery> currentNamedQueries = JPAXMLOverriddenAnnotationReader.buildNamedQueries(
|
List<NamedQuery> currentNamedQueries = JPAXMLOverriddenAnnotationReader.buildNamedQueries(
|
||||||
element,
|
entityMappings.getNamedQuery(),
|
||||||
false,
|
|
||||||
xmlDefaults,
|
xmlDefaults,
|
||||||
classLoaderAccess
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
@ -156,9 +153,8 @@ public Map<Object, Object> getDefaults() {
|
|||||||
namedNativeQueries = new ArrayList<>();
|
namedNativeQueries = new ArrayList<>();
|
||||||
defaults.put( NamedNativeQuery.class, namedNativeQueries );
|
defaults.put( NamedNativeQuery.class, namedNativeQueries );
|
||||||
}
|
}
|
||||||
List<NamedNativeQuery> currentNamedNativeQueries = JPAXMLOverriddenAnnotationReader.buildNamedQueries(
|
List<NamedNativeQuery> currentNamedNativeQueries = JPAXMLOverriddenAnnotationReader.buildNamedNativeQueries(
|
||||||
element,
|
entityMappings.getNamedNativeQuery(),
|
||||||
true,
|
|
||||||
xmlDefaults,
|
xmlDefaults,
|
||||||
classLoaderAccess
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
@ -172,7 +168,7 @@ public Map<Object, Object> getDefaults() {
|
|||||||
defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
|
defaults.put( SqlResultSetMapping.class, sqlResultSetMappings );
|
||||||
}
|
}
|
||||||
List<SqlResultSetMapping> currentSqlResultSetMappings = JPAXMLOverriddenAnnotationReader.buildSqlResultsetMappings(
|
List<SqlResultSetMapping> currentSqlResultSetMappings = JPAXMLOverriddenAnnotationReader.buildSqlResultsetMappings(
|
||||||
element,
|
entityMappings.getSqlResultSetMapping(),
|
||||||
xmlDefaults,
|
xmlDefaults,
|
||||||
classLoaderAccess
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
@ -185,7 +181,7 @@ public Map<Object, Object> getDefaults() {
|
|||||||
}
|
}
|
||||||
List<NamedStoredProcedureQuery> currentNamedStoredProcedureQueries = JPAXMLOverriddenAnnotationReader
|
List<NamedStoredProcedureQuery> currentNamedStoredProcedureQueries = JPAXMLOverriddenAnnotationReader
|
||||||
.buildNamedStoreProcedureQueries(
|
.buildNamedStoreProcedureQueries(
|
||||||
element,
|
entityMappings.getNamedStoredProcedureQuery(),
|
||||||
xmlDefaults,
|
xmlDefaults,
|
||||||
classLoaderAccess
|
classLoaderAccess
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.cfg.annotations.reflection.internal;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.AttributesContainer;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributes;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbBasic;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollection;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbedded;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedId;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbId;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToMany;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOne;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToMany;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOne;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostLoad;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostPersist;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostRemove;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPostUpdate;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPrePersist;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPreRemove;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPreUpdate;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbTransient;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbVersion;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.LifecycleCallback;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.LifecycleCallbackContainer;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.PersistentAttribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reproduces what we used to do with a {@code List<Element>} in {@link JPAXMLOverriddenAnnotationReader},
|
||||||
|
* with the following constraints:
|
||||||
|
* <ul>
|
||||||
|
* <li>Preserve type safety</li>
|
||||||
|
* <li>Only create lists if we actually have elements (most lists should be empty in most cases)</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
final class PropertyMappingElementCollector {
|
||||||
|
static final Function<PersistentAttribute, String> PERSISTENT_ATTRIBUTE_NAME = PersistentAttribute::getName;
|
||||||
|
static final Function<JaxbTransient, String> JAXB_TRANSIENT_NAME = JaxbTransient::getName;
|
||||||
|
static final Function<LifecycleCallback, String> LIFECYCLE_CALLBACK_NAME = LifecycleCallback::getMethodName;
|
||||||
|
|
||||||
|
private final String propertyName;
|
||||||
|
|
||||||
|
private List<JaxbId> id;
|
||||||
|
private List<JaxbEmbeddedId> embeddedId;
|
||||||
|
private List<JaxbBasic> basic;
|
||||||
|
private List<JaxbVersion> version;
|
||||||
|
private List<JaxbManyToOne> manyToOne;
|
||||||
|
private List<JaxbOneToMany> oneToMany;
|
||||||
|
private List<JaxbOneToOne> oneToOne;
|
||||||
|
private List<JaxbManyToMany> manyToMany;
|
||||||
|
private List<JaxbElementCollection> elementCollection;
|
||||||
|
private List<JaxbEmbedded> embedded;
|
||||||
|
private List<JaxbTransient> _transient;
|
||||||
|
|
||||||
|
private List<JaxbPrePersist> prePersist;
|
||||||
|
private List<JaxbPostPersist> postPersist;
|
||||||
|
private List<JaxbPreRemove> preRemove;
|
||||||
|
private List<JaxbPostRemove> postRemove;
|
||||||
|
private List<JaxbPreUpdate> preUpdate;
|
||||||
|
private List<JaxbPostUpdate> postUpdate;
|
||||||
|
private List<JaxbPostLoad> postLoad;
|
||||||
|
|
||||||
|
PropertyMappingElementCollector(String propertyName) {
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return allNullOrEmpty( id, embeddedId, basic, version, manyToOne, oneToMany, oneToOne, manyToMany,
|
||||||
|
elementCollection, embedded, _transient,
|
||||||
|
prePersist, postPersist, preRemove, postRemove, preUpdate, postUpdate, postLoad );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean allNullOrEmpty(List<?>... lists) {
|
||||||
|
for ( List<?> list : lists ) {
|
||||||
|
if ( list != null && !list.isEmpty() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> List<T> defaultToEmpty(List<T> list) {
|
||||||
|
return list == null ? Collections.emptyList() : list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collectPersistentAttributesIfMatching(AttributesContainer container) {
|
||||||
|
if ( container instanceof JaxbAttributes ) {
|
||||||
|
JaxbAttributes jaxbAttributes = (JaxbAttributes) container;
|
||||||
|
id = collectIfMatching( id, jaxbAttributes.getId(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
embeddedId = collectIfMatching( embeddedId, jaxbAttributes.getEmbeddedId(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
version = collectIfMatching( version, jaxbAttributes.getVersion(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
}
|
||||||
|
basic = collectIfMatching( basic, container.getBasic(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
manyToOne = collectIfMatching( manyToOne, container.getManyToOne(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
oneToMany = collectIfMatching( oneToMany, container.getOneToMany(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
oneToOne = collectIfMatching( oneToOne, container.getOneToOne(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
manyToMany = collectIfMatching( manyToMany, container.getManyToMany(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
elementCollection = collectIfMatching( elementCollection, container.getElementCollection(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
embedded = collectIfMatching( embedded, container.getEmbedded(), PERSISTENT_ATTRIBUTE_NAME );
|
||||||
|
_transient = collectIfMatching( _transient, container.getTransient(), JAXB_TRANSIENT_NAME );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void collectLifecycleCallbacksIfMatching(LifecycleCallbackContainer container) {
|
||||||
|
prePersist = collectIfMatching( prePersist, container.getPrePersist(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
postPersist = collectIfMatching( postPersist, container.getPostPersist(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
preRemove = collectIfMatching( preRemove, container.getPreRemove(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
postRemove = collectIfMatching( postRemove, container.getPostRemove(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
preUpdate = collectIfMatching( preUpdate, container.getPreUpdate(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
postUpdate = collectIfMatching( postUpdate, container.getPostUpdate(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
postLoad = collectIfMatching( postLoad, container.getPostLoad(), LIFECYCLE_CALLBACK_NAME );
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> List<T> collectIfMatching(List<T> collected, List<T> candidates,
|
||||||
|
Function<? super T, String> nameGetter) {
|
||||||
|
List<T> result = collected;
|
||||||
|
for ( T candidate : candidates ) {
|
||||||
|
result = collectIfMatching( result, candidate, nameGetter );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> List<T> collectIfMatching(List<T> collected, T candidate, Function<? super T, String> nameGetter) {
|
||||||
|
List<T> result = collected;
|
||||||
|
if ( candidate != null && propertyName.equals( nameGetter.apply( candidate ) ) ) {
|
||||||
|
if ( result == null ) {
|
||||||
|
result = new ArrayList<>();
|
||||||
|
}
|
||||||
|
result.add( candidate );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbId> getId() {
|
||||||
|
return defaultToEmpty( id );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbEmbeddedId> getEmbeddedId() {
|
||||||
|
return defaultToEmpty( embeddedId );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbBasic> getBasic() {
|
||||||
|
return defaultToEmpty( basic );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbVersion> getVersion() {
|
||||||
|
return defaultToEmpty( version );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbManyToOne> getManyToOne() {
|
||||||
|
return defaultToEmpty( manyToOne );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbOneToMany> getOneToMany() {
|
||||||
|
return defaultToEmpty( oneToMany );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbOneToOne> getOneToOne() {
|
||||||
|
return defaultToEmpty( oneToOne );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbManyToMany> getManyToMany() {
|
||||||
|
return defaultToEmpty( manyToMany );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbElementCollection> getElementCollection() {
|
||||||
|
return defaultToEmpty( elementCollection );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbEmbedded> getEmbedded() {
|
||||||
|
return defaultToEmpty( embedded );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbTransient> getTransient() {
|
||||||
|
return defaultToEmpty( _transient );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPrePersist> getPrePersist() {
|
||||||
|
return defaultToEmpty( prePersist );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPostPersist> getPostPersist() {
|
||||||
|
return defaultToEmpty( postPersist );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPreRemove> getPreRemove() {
|
||||||
|
return defaultToEmpty( preRemove );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPostRemove> getPostRemove() {
|
||||||
|
return defaultToEmpty( postRemove );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPreUpdate> getPreUpdate() {
|
||||||
|
return defaultToEmpty( preUpdate );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPostUpdate> getPostUpdate() {
|
||||||
|
return defaultToEmpty( postUpdate );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbPostLoad> getPostLoad() {
|
||||||
|
return defaultToEmpty( postLoad );
|
||||||
|
}
|
||||||
|
}
|
@ -16,89 +16,81 @@
|
|||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.boot.AttributeConverterInfo;
|
import org.hibernate.boot.AttributeConverterInfo;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbConverter;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListener;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityListeners;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclass;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaults;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadata;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.ManagedType;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
import org.hibernate.boot.spi.ClassLoaderAccess;
|
import org.hibernate.boot.spi.ClassLoaderAccess;
|
||||||
import org.hibernate.cfg.AttributeConverterDefinition;
|
import org.hibernate.cfg.AttributeConverterDefinition;
|
||||||
import org.hibernate.cfg.NotYetImplementedException;
|
|
||||||
import org.hibernate.cfg.annotations.reflection.AttributeConverterDefinitionCollector;
|
import org.hibernate.cfg.annotations.reflection.AttributeConverterDefinitionCollector;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
|
||||||
import org.dom4j.Element;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A helper for consuming orm.xml mappings.
|
* A helper for consuming orm.xml mappings.
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
// FIXME HHH-14529 Change this class to use JaxbEntityMappings instead of Document.
|
|
||||||
// I'm delaying this change in order to keep the commits simpler and easier to review.
|
|
||||||
public class XMLContext implements Serializable {
|
public class XMLContext implements Serializable {
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( XMLContext.class );
|
||||||
|
|
||||||
private final ClassLoaderAccess classLoaderAccess;
|
private final ClassLoaderAccess classLoaderAccess;
|
||||||
|
|
||||||
private Default globalDefaults;
|
private Default globalDefaults;
|
||||||
private Map<String, Element> classOverriding = new HashMap<>();
|
private final Map<String, ManagedType> managedTypeOverride = new HashMap<>();
|
||||||
private Map<String, Default> defaultsOverriding = new HashMap<>();
|
private final Map<String, JaxbEntityListener> entityListenerOverride = new HashMap<>();
|
||||||
private List<Element> defaultElements = new ArrayList<>();
|
private final Map<String, Default> defaultsOverride = new HashMap<>();
|
||||||
private List<String> defaultEntityListeners = new ArrayList<>();
|
private final List<JaxbEntityMappings> defaultElements = new ArrayList<>();
|
||||||
|
private final List<String> defaultEntityListeners = new ArrayList<>();
|
||||||
private boolean hasContext = false;
|
private boolean hasContext = false;
|
||||||
|
|
||||||
XMLContext(ClassLoaderAccess classLoaderAccess) {
|
/**
|
||||||
|
* @deprecated Use {@link org.hibernate.cfg.annotations.reflection.XMLContext#XMLContext(BootstrapContext)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public XMLContext(ClassLoaderAccess classLoaderAccess) {
|
||||||
this.classLoaderAccess = classLoaderAccess;
|
this.classLoaderAccess = classLoaderAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For tests only
|
|
||||||
public XMLContext(BootstrapContext bootstrapContext) {
|
public XMLContext(BootstrapContext bootstrapContext) {
|
||||||
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
|
this.classLoaderAccess = bootstrapContext.getClassLoaderAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param entityMappings The xml entity mappings to add
|
* @param entityMappings The xml document to add
|
||||||
* @return Add an xml document to this context and return the list of added class names.
|
|
||||||
*/
|
|
||||||
public List<String> addDocument(JaxbEntityMappings entityMappings) {
|
|
||||||
throw new NotYetImplementedException("HHH-14529 Implementation in progress");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param doc The xml document to add
|
|
||||||
* @return Add an xml document to this context and return the list of added class names.
|
* @return Add an xml document to this context and return the list of added class names.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public List<String> addDocument(Document doc) {
|
public List<String> addDocument(JaxbEntityMappings entityMappings) {
|
||||||
hasContext = true;
|
hasContext = true;
|
||||||
List<String> addedClasses = new ArrayList<>();
|
List<String> addedClasses = new ArrayList<>();
|
||||||
Element root = doc.getRootElement();
|
|
||||||
//global defaults
|
//global defaults
|
||||||
Element metadata = root.element( "persistence-unit-metadata" );
|
JaxbPersistenceUnitMetadata metadata = entityMappings.getPersistenceUnitMetadata();
|
||||||
if ( metadata != null ) {
|
if ( metadata != null ) {
|
||||||
if ( globalDefaults == null ) {
|
if ( globalDefaults == null ) {
|
||||||
globalDefaults = new Default();
|
globalDefaults = new Default();
|
||||||
globalDefaults.setMetadataComplete(
|
globalDefaults.setMetadataComplete(
|
||||||
metadata.element( "xml-mapping-metadata-complete" ) != null ?
|
metadata.getXmlMappingMetadataComplete() != null ?
|
||||||
Boolean.TRUE :
|
Boolean.TRUE :
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
Element defaultElement = metadata.element( "persistence-unit-defaults" );
|
JaxbPersistenceUnitDefaults defaultElement = metadata.getPersistenceUnitDefaults();
|
||||||
if ( defaultElement != null ) {
|
if ( defaultElement != null ) {
|
||||||
Element unitElement = defaultElement.element( "schema" );
|
globalDefaults.setSchema( defaultElement.getSchema() );
|
||||||
globalDefaults.setSchema( unitElement != null ? unitElement.getTextTrim() : null );
|
globalDefaults.setCatalog( defaultElement.getCatalog() );
|
||||||
unitElement = defaultElement.element( "catalog" );
|
globalDefaults.setAccess( defaultElement.getAccess() );
|
||||||
globalDefaults.setCatalog( unitElement != null ? unitElement.getTextTrim() : null );
|
globalDefaults.setCascadePersist( defaultElement.getCascadePersist() != null ? Boolean.TRUE : null );
|
||||||
unitElement = defaultElement.element( "access" );
|
globalDefaults.setDelimitedIdentifiers( defaultElement.getDelimitedIdentifiers() != null ? Boolean.TRUE : null );
|
||||||
setAccess( unitElement, globalDefaults );
|
defaultEntityListeners.addAll( addEntityListenerClasses( defaultElement.getEntityListeners(), null, addedClasses ) );
|
||||||
unitElement = defaultElement.element( "cascade-persist" );
|
|
||||||
globalDefaults.setCascadePersist( unitElement != null ? Boolean.TRUE : null );
|
|
||||||
unitElement = defaultElement.element( "delimited-identifiers" );
|
|
||||||
globalDefaults.setDelimitedIdentifiers( unitElement != null ? Boolean.TRUE : null );
|
|
||||||
defaultEntityListeners.addAll( addEntityListenerClasses( defaultElement, null, addedClasses ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -108,92 +100,61 @@ public List<String> addDocument(Document doc) {
|
|||||||
|
|
||||||
//entity mapping default
|
//entity mapping default
|
||||||
Default entityMappingDefault = new Default();
|
Default entityMappingDefault = new Default();
|
||||||
Element unitElement = root.element( "package" );
|
String packageName = entityMappings.getPackage();
|
||||||
String packageName = unitElement != null ? unitElement.getTextTrim() : null;
|
|
||||||
entityMappingDefault.setPackageName( packageName );
|
entityMappingDefault.setPackageName( packageName );
|
||||||
unitElement = root.element( "schema" );
|
entityMappingDefault.setSchema( entityMappings.getSchema() );
|
||||||
entityMappingDefault.setSchema( unitElement != null ? unitElement.getTextTrim() : null );
|
entityMappingDefault.setCatalog( entityMappings.getCatalog() );
|
||||||
unitElement = root.element( "catalog" );
|
entityMappingDefault.setAccess( entityMappings.getAccess() );
|
||||||
entityMappingDefault.setCatalog( unitElement != null ? unitElement.getTextTrim() : null );
|
defaultElements.add( entityMappings );
|
||||||
unitElement = root.element( "access" );
|
|
||||||
setAccess( unitElement, entityMappingDefault );
|
|
||||||
defaultElements.add( root );
|
|
||||||
|
|
||||||
setLocalAttributeConverterDefinitions( root.elements( "converter" ) );
|
setLocalAttributeConverterDefinitions( entityMappings.getConverter() );
|
||||||
|
|
||||||
List<Element> entities = root.elements( "entity" );
|
addClass( entityMappings.getEntity(), packageName, entityMappingDefault, addedClasses );
|
||||||
addClass( entities, packageName, entityMappingDefault, addedClasses );
|
|
||||||
|
|
||||||
entities = root.elements( "mapped-superclass" );
|
addClass( entityMappings.getMappedSuperclass(), packageName, entityMappingDefault, addedClasses );
|
||||||
addClass( entities, packageName, entityMappingDefault, addedClasses );
|
|
||||||
|
addClass( entityMappings.getEmbeddable(), packageName, entityMappingDefault, addedClasses );
|
||||||
|
|
||||||
entities = root.elements( "embeddable" );
|
|
||||||
addClass( entities, packageName, entityMappingDefault, addedClasses );
|
|
||||||
return addedClasses;
|
return addedClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAccess(Element unitElement, Default defaultType) {
|
private void addClass(List<? extends ManagedType> managedTypes, String packageName, Default defaults, List<String> addedClasses) {
|
||||||
if ( unitElement != null ) {
|
for (ManagedType element : managedTypes) {
|
||||||
String access = unitElement.getTextTrim();
|
String className = buildSafeClassName( element.getClazz(), packageName );
|
||||||
setAccess( access, defaultType );
|
if ( managedTypeOverride.containsKey( className ) ) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setAccess( String access, Default defaultType) {
|
|
||||||
AccessType type;
|
|
||||||
if ( access != null ) {
|
|
||||||
try {
|
|
||||||
type = AccessType.valueOf( access );
|
|
||||||
}
|
|
||||||
catch ( IllegalArgumentException e ) {
|
|
||||||
throw new AnnotationException( "Invalid access type " + access + " (check your xml configuration)" );
|
|
||||||
}
|
|
||||||
defaultType.setAccess( type );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addClass(List<Element> entities, String packageName, Default defaults, List<String> addedClasses) {
|
|
||||||
for (Element element : entities) {
|
|
||||||
String className = buildSafeClassName( element.attributeValue( "class" ), packageName );
|
|
||||||
if ( classOverriding.containsKey( className ) ) {
|
|
||||||
//maybe switch it to warn?
|
//maybe switch it to warn?
|
||||||
throw new IllegalStateException( "Duplicate XML entry for " + className );
|
throw new IllegalStateException( "Duplicate XML entry for " + className );
|
||||||
}
|
}
|
||||||
addedClasses.add( className );
|
addedClasses.add( className );
|
||||||
classOverriding.put( className, element );
|
managedTypeOverride.put( className, element );
|
||||||
Default localDefault = new Default();
|
Default localDefault = new Default();
|
||||||
localDefault.override( defaults );
|
localDefault.override( defaults );
|
||||||
String metadataCompleteString = element.attributeValue( "metadata-complete" );
|
localDefault.setMetadataComplete( element.isMetadataComplete() );
|
||||||
if ( metadataCompleteString != null ) {
|
localDefault.setAccess( element.getAccess() );
|
||||||
localDefault.setMetadataComplete( Boolean.parseBoolean( metadataCompleteString ) );
|
defaultsOverride.put( className, localDefault );
|
||||||
}
|
|
||||||
String access = element.attributeValue( "access" );
|
|
||||||
setAccess( access, localDefault );
|
|
||||||
defaultsOverriding.put( className, localDefault );
|
|
||||||
|
|
||||||
LOG.debugf( "Adding XML overriding information for %s", className );
|
LOG.debugf( "Adding XML overriding information for %s", className );
|
||||||
addEntityListenerClasses( element, packageName, addedClasses );
|
if ( element instanceof JaxbEntity ) {
|
||||||
|
addEntityListenerClasses( ( (JaxbEntity) element ).getEntityListeners(), packageName, addedClasses );
|
||||||
|
}
|
||||||
|
else if ( element instanceof JaxbMappedSuperclass ) {
|
||||||
|
addEntityListenerClasses( ( (JaxbMappedSuperclass) element ).getEntityListeners(), packageName, addedClasses );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> addEntityListenerClasses(Element element, String packageName, List<String> addedClasses) {
|
private List<String> addEntityListenerClasses(JaxbEntityListeners listeners, String packageName, List<String> addedClasses) {
|
||||||
List<String> localAddedClasses = new ArrayList<>();
|
List<String> localAddedClasses = new ArrayList<>();
|
||||||
Element listeners = element.element( "entity-listeners" );
|
|
||||||
if ( listeners != null ) {
|
if ( listeners != null ) {
|
||||||
@SuppressWarnings( "unchecked" )
|
List<JaxbEntityListener> elements = listeners.getEntityListener();
|
||||||
List<Element> elements = listeners.elements( "entity-listener" );
|
for (JaxbEntityListener listener : elements) {
|
||||||
for (Element listener : elements) {
|
String listenerClassName = buildSafeClassName( listener.getClazz(), packageName );
|
||||||
String listenerClassName = buildSafeClassName( listener.attributeValue( "class" ), packageName );
|
if ( entityListenerOverride.containsKey( listenerClassName ) ) {
|
||||||
if ( classOverriding.containsKey( listenerClassName ) ) {
|
|
||||||
//maybe switch it to warn?
|
|
||||||
if ( "entity-listener".equals( classOverriding.get( listenerClassName ).getName() ) ) {
|
|
||||||
LOG.duplicateListener( listenerClassName );
|
LOG.duplicateListener( listenerClassName );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Duplicate XML entry for " + listenerClassName);
|
|
||||||
}
|
|
||||||
localAddedClasses.add( listenerClassName );
|
localAddedClasses.add( listenerClassName );
|
||||||
classOverriding.put( listenerClassName, listener );
|
entityListenerOverride.put( listenerClassName, listener );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG.debugf( "Adding XML overriding information for listeners: %s", localAddedClasses );
|
LOG.debugf( "Adding XML overriding information for listeners: %s", localAddedClasses );
|
||||||
@ -202,11 +163,10 @@ private List<String> addEntityListenerClasses(Element element, String packageNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void setLocalAttributeConverterDefinitions(List<Element> converterElements) {
|
private void setLocalAttributeConverterDefinitions(List<JaxbConverter> converterElements) {
|
||||||
for ( Element converterElement : converterElements ) {
|
for ( JaxbConverter converterElement : converterElements ) {
|
||||||
final String className = converterElement.attributeValue( "class" );
|
final String className = converterElement.getClazz();
|
||||||
final String autoApplyAttribute = converterElement.attributeValue( "auto-apply" );
|
final boolean autoApply = Boolean.TRUE.equals( converterElement.isAutoApply() );
|
||||||
final boolean autoApply = autoApplyAttribute != null && Boolean.parseBoolean( autoApplyAttribute );
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName(
|
final Class<? extends AttributeConverter> attributeConverterClass = classLoaderAccess.classForName(
|
||||||
@ -232,7 +192,7 @@ public static String buildSafeClassName(String className, String defaultPackageN
|
|||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String buildSafeClassName(String className, XMLContext.Default defaults) {
|
public static String buildSafeClassName(String className, Default defaults) {
|
||||||
return buildSafeClassName( className, defaults.getPackageName() );
|
return buildSafeClassName( className, defaults.getPackageName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,17 +200,21 @@ public Default getDefault(String className) {
|
|||||||
Default xmlDefault = new Default();
|
Default xmlDefault = new Default();
|
||||||
xmlDefault.override( globalDefaults );
|
xmlDefault.override( globalDefaults );
|
||||||
if ( className != null ) {
|
if ( className != null ) {
|
||||||
Default entityMappingOverriding = defaultsOverriding.get( className );
|
Default entityMappingOverriding = defaultsOverride.get( className );
|
||||||
xmlDefault.override( entityMappingOverriding );
|
xmlDefault.override( entityMappingOverriding );
|
||||||
}
|
}
|
||||||
return xmlDefault;
|
return xmlDefault;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element getXMLTree(String className ) {
|
public ManagedType getManagedTypeOverride(String className) {
|
||||||
return classOverriding.get( className );
|
return managedTypeOverride.get( className );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Element> getAllDocuments() {
|
public JaxbEntityListener getEntityListenerOverride(String className) {
|
||||||
|
return entityListenerOverride.get( className );
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<JaxbEntityMappings> getAllDocuments() {
|
||||||
return defaultElements;
|
return defaultElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +72,9 @@
|
|||||||
</bindings>
|
</bindings>
|
||||||
|
|
||||||
<bindings node="//xsd:simpleType[@name='constraint-mode']">
|
<bindings node="//xsd:simpleType[@name='constraint-mode']">
|
||||||
<javaType name="javax.persistence.ContraintMode"
|
<javaType name="javax.persistence.ConstraintMode"
|
||||||
parseMethod="org.hibernate.boot.jaxb.mapping.internal.ContraintModeMarshalling.fromXml"
|
parseMethod="org.hibernate.boot.jaxb.mapping.internal.ConstraintModeMarshalling.fromXml"
|
||||||
printMethod="org.hibernate.boot.jaxb.mapping.internal.ContraintModeMarshalling.toXml" />
|
printMethod="org.hibernate.boot.jaxb.mapping.internal.ConstraintModeMarshalling.toXml" />
|
||||||
</bindings>
|
</bindings>
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.internal.util.xml;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
|
import org.hibernate.boot.jaxb.SourceType;
|
||||||
|
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.boot.ClassLoaderServiceTestingImpl;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A small helper class for parsing XML mappings, to be used in unit tests.
|
||||||
|
*/
|
||||||
|
public final class XMLMappingHelper {
|
||||||
|
private final MappingBinder binder;
|
||||||
|
|
||||||
|
public XMLMappingHelper(XmlMappingOptions xmlMappingOptions) {
|
||||||
|
binder = new MappingBinder( ClassLoaderServiceTestingImpl.INSTANCE, true, xmlMappingOptions );
|
||||||
|
}
|
||||||
|
|
||||||
|
public JaxbEntityMappings readOrmXmlMappings(String name) throws IOException {
|
||||||
|
try (InputStream is = ClassLoaderServiceTestingImpl.INSTANCE.locateResourceStream( name )) {
|
||||||
|
return readOrmXmlMappings( is, name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JaxbEntityMappings readOrmXmlMappings(InputStream is, String name) {
|
||||||
|
try {
|
||||||
|
Assert.assertNotNull( "Resource not found: " + name, is );
|
||||||
|
Binding<?> binding = binder.bind( is, new Origin( SourceType.JAR, name ) );
|
||||||
|
return (JaxbEntityMappings) binding.getRoot();
|
||||||
|
}
|
||||||
|
catch (RuntimeException e) {
|
||||||
|
throw new IllegalStateException( "Could not parse orm.xml mapping '" + name + "': " + e.getMessage(), e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,12 +9,15 @@
|
|||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
||||||
import org.dom4j.io.SAXReader;
|
import org.dom4j.io.SAXReader;
|
||||||
import org.hibernate.annotations.Columns;
|
import org.hibernate.annotations.Columns;
|
||||||
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
|
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
||||||
import org.hibernate.cfg.EJB3DTDEntityResolver;
|
import org.hibernate.cfg.EJB3DTDEntityResolver;
|
||||||
import org.hibernate.cfg.annotations.reflection.JPAOverriddenAnnotationReader;
|
import org.hibernate.cfg.annotations.reflection.JPAOverriddenAnnotationReader;
|
||||||
import org.hibernate.cfg.annotations.reflection.internal.JPAXMLOverriddenAnnotationReader;
|
import org.hibernate.cfg.annotations.reflection.internal.JPAXMLOverriddenAnnotationReader;
|
||||||
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
||||||
import org.hibernate.internal.util.xml.ErrorLogger;
|
import org.hibernate.internal.util.xml.ErrorLogger;
|
||||||
import org.hibernate.internal.util.xml.XMLHelper;
|
import org.hibernate.internal.util.xml.XMLHelper;
|
||||||
|
import org.hibernate.internal.util.xml.XMLMappingHelper;
|
||||||
|
|
||||||
import org.hibernate.testing.boot.BootstrapContextImpl;
|
import org.hibernate.testing.boot.BootstrapContextImpl;
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
@ -401,32 +404,16 @@ public void testEntityListeners() throws Exception {
|
|||||||
assertEquals( OtherLogListener.class.getName(), context.getDefaultEntityListeners().get( 0 ) );
|
assertEquals( OtherLogListener.class.getName(), context.getDefaultEntityListeners().get( 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private XMLContext buildContext(String ormfile) throws SAXException, DocumentException, IOException {
|
private XMLContext buildContext(String ormfile) throws IOException {
|
||||||
XMLHelper xmlHelper = new XMLHelper();
|
XMLMappingHelper xmlHelper = new XMLMappingHelper( new XmlMappingOptions() {
|
||||||
InputStream is = ClassLoaderServiceTestingImpl.INSTANCE.locateResourceStream( ormfile );
|
@Override
|
||||||
assertNotNull( "ORM.xml not found: " + ormfile, is );
|
public boolean isPreferJaxb() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
JaxbEntityMappings mappings = xmlHelper.readOrmXmlMappings( ormfile );
|
||||||
XMLContext context = new XMLContext( BootstrapContextImpl.INSTANCE );
|
XMLContext context = new XMLContext( BootstrapContextImpl.INSTANCE );
|
||||||
ErrorLogger errorLogger = new ErrorLogger();
|
context.addDocument( mappings );
|
||||||
SAXReader saxReader = xmlHelper.createSAXReader( errorLogger, EJB3DTDEntityResolver.INSTANCE );
|
|
||||||
//saxReader.setValidation( false );
|
|
||||||
try {
|
|
||||||
saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
|
|
||||||
}
|
|
||||||
catch ( SAXNotSupportedException e ) {
|
|
||||||
saxReader.setValidation( false );
|
|
||||||
}
|
|
||||||
org.dom4j.Document doc;
|
|
||||||
try {
|
|
||||||
doc = saxReader.read( new InputSource( new BufferedInputStream( is ) ) );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
if ( errorLogger.hasErrors() ) {
|
|
||||||
System.out.println( errorLogger.getErrors().get( 0 ) );
|
|
||||||
}
|
|
||||||
assertFalse( errorLogger.hasErrors() );
|
|
||||||
context.addDocument( doc );
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.test.annotations.reflection;
|
package org.hibernate.test.annotations.reflection;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
import java.io.IOException;
|
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.dom4j.io.SAXReader;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.SAXNotSupportedException;
|
|
||||||
|
|
||||||
import org.hibernate.cfg.EJB3DTDEntityResolver;
|
|
||||||
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
||||||
import org.hibernate.internal.util.xml.ErrorLogger;
|
import org.hibernate.internal.util.xml.XMLMappingHelper;
|
||||||
import org.hibernate.internal.util.xml.XMLHelper;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.boot.BootstrapContextImpl;
|
import org.hibernate.testing.boot.BootstrapContextImpl;
|
||||||
import org.hibernate.testing.boot.ClassLoaderServiceTestingImpl;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the new {@link XMLContext},
|
* Tests the new {@link XMLContext},
|
||||||
@ -38,36 +28,15 @@
|
|||||||
public class XMLContextTest {
|
public class XMLContextTest {
|
||||||
@Test
|
@Test
|
||||||
public void testAll() throws Exception {
|
public void testAll() throws Exception {
|
||||||
final XMLHelper xmlHelper = new XMLHelper();
|
XMLMappingHelper xmlHelper = new XMLMappingHelper( new XmlMappingOptions() {
|
||||||
|
@Override
|
||||||
|
public boolean isPreferJaxb() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} );
|
||||||
final XMLContext context = new XMLContext( BootstrapContextImpl.INSTANCE );
|
final XMLContext context = new XMLContext( BootstrapContextImpl.INSTANCE );
|
||||||
|
|
||||||
InputStream is = ClassLoaderServiceTestingImpl.INSTANCE.locateResourceStream(
|
JaxbEntityMappings mappings = xmlHelper.readOrmXmlMappings( "org/hibernate/test/annotations/reflection/orm.xml" );
|
||||||
"org/hibernate/test/annotations/reflection/orm.xml"
|
context.addDocument( mappings );
|
||||||
);
|
|
||||||
Assert.assertNotNull( "ORM.xml not found", is );
|
|
||||||
|
|
||||||
final ErrorLogger errorLogger = new ErrorLogger();
|
|
||||||
final SAXReader saxReader = xmlHelper.createSAXReader( errorLogger, EJB3DTDEntityResolver.INSTANCE );
|
|
||||||
|
|
||||||
try {
|
|
||||||
saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
|
|
||||||
}
|
|
||||||
catch ( SAXNotSupportedException e ) {
|
|
||||||
saxReader.setValidation( false );
|
|
||||||
}
|
|
||||||
org.dom4j.Document doc;
|
|
||||||
try {
|
|
||||||
doc = saxReader.read( new InputSource( new BufferedInputStream( is ) ) );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
catch ( IOException ioe ) {
|
|
||||||
//log.warn( "Could not close input stream", ioe );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert.assertFalse( errorLogger.hasErrors() );
|
|
||||||
context.addDocument( doc );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappings;
|
||||||
import org.dom4j.io.SAXReader;
|
import org.hibernate.boot.jaxb.spi.XmlMappingOptions;
|
||||||
|
|
||||||
import org.hibernate.cfg.annotations.reflection.internal.JPAXMLOverriddenAnnotationReader;
|
import org.hibernate.cfg.annotations.reflection.internal.JPAXMLOverriddenAnnotationReader;
|
||||||
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
import org.hibernate.cfg.annotations.reflection.internal.XMLContext;
|
||||||
|
import org.hibernate.internal.util.xml.XMLMappingHelper;
|
||||||
|
|
||||||
import org.hibernate.testing.boot.BootstrapContextImpl;
|
import org.hibernate.testing.boot.BootstrapContextImpl;
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
@ -29,8 +29,12 @@
|
|||||||
* database is used. Thus, no schema generation or cleanup will be performed.
|
* database is used. Thus, no schema generation or cleanup will be performed.
|
||||||
*/
|
*/
|
||||||
public abstract class Ejb3XmlTestCase extends BaseUnitTestCase {
|
public abstract class Ejb3XmlTestCase extends BaseUnitTestCase {
|
||||||
|
|
||||||
protected JPAXMLOverriddenAnnotationReader reader;
|
protected JPAXMLOverriddenAnnotationReader reader;
|
||||||
|
|
||||||
|
protected Ejb3XmlTestCase() {
|
||||||
|
}
|
||||||
|
|
||||||
protected void assertAnnotationPresent(Class<? extends Annotation> annotationType) {
|
protected void assertAnnotationPresent(Class<? extends Annotation> annotationType) {
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"Expected annotation " + annotationType.getSimpleName() + " was not present",
|
"Expected annotation " + annotationType.getSimpleName() + " was not present",
|
||||||
@ -59,17 +63,19 @@ protected AnnotatedElement getAnnotatedElement(Class<?> entityClass, String fiel
|
|||||||
protected XMLContext getContext(String resourceName) throws Exception {
|
protected XMLContext getContext(String resourceName) throws Exception {
|
||||||
InputStream is = getClass().getResourceAsStream( resourceName );
|
InputStream is = getClass().getResourceAsStream( resourceName );
|
||||||
assertNotNull( "Could not load resource " + resourceName, is );
|
assertNotNull( "Could not load resource " + resourceName, is );
|
||||||
return getContext( is );
|
return getContext( is, resourceName );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected XMLContext getContext(InputStream is) throws Exception {
|
protected XMLContext getContext(InputStream is, String resourceName) throws Exception {
|
||||||
XMLContext xmlContext = new XMLContext( BootstrapContextImpl.INSTANCE );
|
XMLMappingHelper xmlHelper = new XMLMappingHelper( new XmlMappingOptions() {
|
||||||
SAXReader reader = new SAXReader();
|
@Override
|
||||||
reader.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false );
|
public boolean isPreferJaxb() {
|
||||||
reader.setFeature( "http://xml.org/sax/features/external-general-entities", false );
|
return true;
|
||||||
reader.setFeature( "http://xml.org/sax/features/external-parameter-entities", false );
|
}
|
||||||
Document doc = reader.read( is );
|
} );
|
||||||
xmlContext.addDocument( doc );
|
JaxbEntityMappings mappings = xmlHelper.readOrmXmlMappings( is, resourceName );
|
||||||
return xmlContext;
|
XMLContext context = new XMLContext( BootstrapContextImpl.INSTANCE );
|
||||||
|
context.addDocument( mappings );
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user