HHH-8893 delay binding of xml resources until building Metadata,

introduce ClassLoaderAccess into transformer, removed old XmlBinder
This commit is contained in:
Brett Meyer 2014-05-21 17:12:24 -04:00
parent 95d66ed252
commit 047d308601
14 changed files with 131 additions and 640 deletions

View File

@ -61,9 +61,9 @@ import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.metamodel.source.internal.jaxb.JaxbMappedSuperclass;
import org.hibernate.metamodel.source.internal.jaxb.JaxbPersistenceUnitDefaults;
import org.hibernate.metamodel.source.internal.jaxb.JaxbPersistenceUnitMetadata;
import org.hibernate.metamodel.source.spi.InvalidMappingException;
import org.hibernate.metamodel.source.spi.MappingException;
import org.hibernate.metamodel.source.spi.MappingNotFoundException;
import org.hibernate.metamodel.spi.ClassLoaderAccess;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.SerializationException;
import org.hibernate.xml.internal.jaxb.UnifiedMappingBinder;
@ -86,7 +86,6 @@ public class MetadataSources {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( MetadataSources.class );
private final ServiceRegistry serviceRegistry;
private final UnifiedMappingBinder jaxbProcessor;
private List<BindResult> bindResultList = new ArrayList<BindResult>();
private LinkedHashSet<Class<?>> annotatedClasses = new LinkedHashSet<Class<?>>();
private LinkedHashSet<String> annotatedClassNames = new LinkedHashSet<String>();
@ -94,8 +93,6 @@ public class MetadataSources {
private List<Class<? extends AttributeConverter>> converterClasses;
private boolean hasOrmXmlJaxbRoots;
public MetadataSources() {
this( new BootstrapServiceRegistryBuilder().build() );
}
@ -115,13 +112,19 @@ public class MetadataSources {
);
}
this.serviceRegistry = serviceRegistry;
this.jaxbProcessor = new UnifiedMappingBinder();
}
protected static boolean isExpectedServiceRegistryType(ServiceRegistry serviceRegistry) {
return BootstrapServiceRegistry.class.isInstance( serviceRegistry )
|| StandardServiceRegistry.class.isInstance( serviceRegistry );
}
public void buildBindResults(ClassLoaderAccess classLoaderAccess) {
final UnifiedMappingBinder jaxbProcessor = new UnifiedMappingBinder( classLoaderAccess );
for ( BindResult bindResult : bindResultList ) {
bindResult.bind( jaxbProcessor );
}
}
public List<BindResult> getBindResultList() {
return bindResultList;
@ -243,24 +246,9 @@ public class MetadataSources {
}
private BindResult add(InputStream inputStream, Origin origin, boolean close) {
try {
BindResult bindResult = new BindResult( jaxbProcessor.bind( inputStream, origin ), origin );
addJaxbRoot( bindResult );
return bindResult;
}
catch ( Exception e ) {
throw new InvalidMappingException( origin, e );
}
finally {
if ( close ) {
try {
inputStream.close();
}
catch ( IOException ignore ) {
LOG.trace( "Was unable to close input stream" );
}
}
}
BindResult bindResult = new BindResult( inputStream, origin, close );
bindResultList.add( bindResult );
return bindResult;
}
/**
@ -419,7 +407,7 @@ public class MetadataSources {
}
LOG.readingCachedMappings( cachedFile );
addJaxbRoot( (BindResult) SerializationHelper.deserialize( new FileInputStream( cachedFile ) ) );
bindResultList.add( (BindResult) SerializationHelper.deserialize( new FileInputStream( cachedFile ) ) );
return this;
}
@ -470,16 +458,10 @@ public class MetadataSources {
@Deprecated
public MetadataSources addDocument(Document document) {
final Origin origin = new Origin( SourceType.DOM, Origin.UNKNOWN_FILE_PATH );
BindResult bindResult = new BindResult( jaxbProcessor.bind( new DOMSource( document ), origin ), origin );
addJaxbRoot( bindResult );
bindResultList.add( new BindResult( new DOMSource( document ), origin ) );
return this;
}
private void addJaxbRoot(BindResult bindResult) {
hasOrmXmlJaxbRoots = hasOrmXmlJaxbRoots || JaxbEntityMappings.class.isInstance( bindResult.getRoot() );
bindResultList.add( bindResult );
}
/**
* Read all mappings from a jar file.
* <p/>

View File

@ -25,11 +25,10 @@ package org.hibernate.metamodel.internal;
import java.net.URL;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.metamodel.spi.ClassLoaderAccess;
import org.hibernate.service.ServiceRegistry;
import org.jboss.logging.Logger;
/**
@ -48,7 +47,7 @@ public class ClassLoaderAccessImpl implements ClassLoaderAccess {
this.classLoaderService = classLoaderService;
}
public ClassLoaderAccessImpl(ClassLoader tempClassLoader, StandardServiceRegistry serviceRegistry) {
public ClassLoaderAccessImpl(ClassLoader tempClassLoader, ServiceRegistry serviceRegistry) {
this( tempClassLoader, serviceRegistry.getService( ClassLoaderService.class ) );
}

View File

@ -148,9 +148,13 @@ public class MetadataBuildingProcess {
options.getTempClassLoader(),
options.getServiceRegistry()
);
// It's necessary to delay the binding of XML resources until now. ClassLoaderAccess is needed for
// reflection, etc.
sources.buildBindResults( classLoaderAccess );
final JandexInitManager jandexInitializer = buildJandexInitializer( options, classLoaderAccess );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// scanning - Jandex initialization and source discovery
if ( options.getScanEnvironment() != null ) {

View File

@ -39,8 +39,6 @@ import org.hibernate.metamodel.source.internal.jaxb.JaxbPersistenceUnitDefaults;
import org.hibernate.metamodel.source.internal.jaxb.JaxbPersistenceUnitMetadata;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.xml.spi.BindResult;
import org.hibernate.xml.spi.Origin;
import org.hibernate.xml.spi.SourceType;
import org.jboss.jandex.Index;
import org.jboss.jandex.IndexView;
@ -68,30 +66,6 @@ public class EntityMappingsMocker {
this.globalAnnotations = new GlobalAnnotations();
}
public EntityMappingsMocker(
List<JaxbEntityMappings> xmlEntityMappingsList,
Index index,
ServiceRegistry serviceRegistry) {
this(
grabJaxbEntityMappings( xmlEntityMappingsList ),
index,
serviceRegistry
);
}
private static List<BindResult<JaxbEntityMappings>> grabJaxbEntityMappings(List<JaxbEntityMappings> xmlEntityMappingsList) {
final List<BindResult<JaxbEntityMappings>> result = new ArrayList<BindResult<JaxbEntityMappings>>();
for ( JaxbEntityMappings binding : xmlEntityMappingsList ) {
result.add(
new BindResult<JaxbEntityMappings>(
binding,
new Origin( SourceType.OTHER, Origin.UNKNOWN_FILE_PATH )
)
);
}
return result;
}
/**
* Create new {@link Index} with mocking JPA annotations from {@link org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings}
* and merge them with existing {@link Index}

View File

@ -30,7 +30,6 @@ import javax.xml.bind.JAXBElement;
import org.hibernate.FlushMode;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.internal.jandex.MockHelper;
import org.hibernate.metamodel.source.internal.jaxb.JaxbAny;
import org.hibernate.metamodel.source.internal.jaxb.JaxbAttributes;
import org.hibernate.metamodel.source.internal.jaxb.JaxbBasic;
@ -62,7 +61,6 @@ import org.hibernate.metamodel.source.internal.jaxb.JaxbHbmTypeDef;
import org.hibernate.metamodel.source.internal.jaxb.JaxbId;
import org.hibernate.metamodel.source.internal.jaxb.JaxbIdClass;
import org.hibernate.metamodel.source.internal.jaxb.JaxbJoinColumn;
import org.hibernate.metamodel.source.internal.jaxb.JaxbJoinTable;
import org.hibernate.metamodel.source.internal.jaxb.JaxbManyToOne;
import org.hibernate.metamodel.source.internal.jaxb.JaxbNamedNativeQuery;
import org.hibernate.metamodel.source.internal.jaxb.JaxbNamedQuery;
@ -72,6 +70,7 @@ import org.hibernate.metamodel.source.internal.jaxb.JaxbPersistenceUnitMetadata;
import org.hibernate.metamodel.source.internal.jaxb.JaxbQueryParamType;
import org.hibernate.metamodel.source.internal.jaxb.JaxbSynchronizeType;
import org.hibernate.metamodel.source.internal.jaxb.JaxbTable;
import org.hibernate.metamodel.spi.ClassLoaderAccess;
import org.hibernate.xml.spi.Origin;
import org.jboss.logging.Logger;
@ -91,9 +90,12 @@ public class HbmXmlTransformer {
private Origin origin;
private JaxbEntityMappings ormRoot;
private ClassLoaderAccess classLoaderAccess;
public JaxbEntityMappings transform(JaxbHibernateMapping hbmXmlMapping, Origin origin) {
public JaxbEntityMappings transform(JaxbHibernateMapping hbmXmlMapping, Origin origin,
ClassLoaderAccess classLoaderAccess) {
this.origin = origin;
this.classLoaderAccess = classLoaderAccess;
ormRoot = new JaxbEntityMappings();
ormRoot.setDescription(

View File

@ -1,195 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2013, 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.xml.internal.jaxb;
import java.io.InputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.validation.Schema;
import org.hibernate.metamodel.source.spi.MappingException;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.xml.internal.stax.BufferedXMLEventReader;
import org.hibernate.xml.internal.stax.LocalXmlResourceResolver;
import org.hibernate.xml.spi.BindResult;
import org.hibernate.xml.spi.Origin;
import org.hibernate.xml.spi.XmlBinder;
import org.jboss.logging.Logger;
/**
* Base implementation (template) of the XmlBinder contract.
* <p/>
* Generally implementors should just have to implement:<ol>
* <li>{@link #getJaxbContext}</li>
* <li>{@link #getSchema}</li>
* <li>(optionally) {@link #wrapReader}</li>
* </ol>
*
* @author Steve Ebersole
* @author Strong Liu <stliu@hibernate.org>
*
* @deprecated See {@link AbstractUnifiedBinder}
*/
@Deprecated
abstract class AbstractXmlBinder implements XmlBinder {
protected static final Logger log = Logger.getLogger( AbstractXmlBinder.class );
protected final ServiceRegistry serviceRegistry;
protected final boolean validateXml;
public AbstractXmlBinder(ServiceRegistry serviceRegistry) {
this( serviceRegistry, true );
}
public AbstractXmlBinder(ServiceRegistry serviceRegistry, boolean validateXml) {
this.serviceRegistry = serviceRegistry;
this.validateXml = validateXml;
}
@Override
public BindResult bind(InputStream stream, Origin origin) {
try {
BufferedXMLEventReader staxReader = new BufferedXMLEventReader(staxFactory().createXMLEventReader( stream ), 100);
try {
return unmarshal( staxReader, origin );
}
finally {
try {
staxReader.close();
}
catch ( Exception ignore ) {
}
}
}
catch ( XMLStreamException e ) {
throw new MappingException( "Unable to create stax reader", e, origin );
}
}
private XMLInputFactory staxFactory;
private XMLInputFactory staxFactory() {
if ( staxFactory == null ) {
staxFactory = buildStaxFactory();
}
return staxFactory;
}
@SuppressWarnings( { "UnnecessaryLocalVariable" })
private XMLInputFactory buildStaxFactory() {
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
staxFactory.setXMLResolver( LocalXmlResourceResolver.INSTANCE );
return staxFactory;
}
@SuppressWarnings( { "unchecked" })
private BindResult unmarshal(XMLEventReader staxEventReader, final Origin origin) {
XMLEvent rootElementStartEvent;
try {
rootElementStartEvent = staxEventReader.peek();
while ( rootElementStartEvent != null && !rootElementStartEvent.isStartElement() ) {
staxEventReader.nextEvent();
rootElementStartEvent = staxEventReader.peek();
}
}
catch ( Exception e ) {
throw new MappingException( "Error accessing stax stream", e, origin );
}
if ( rootElementStartEvent == null ) {
throw new MappingException( "Could not locate root element", origin );
}
final ContextProvidingValidationEventHandler handler = new ContextProvidingValidationEventHandler();
try {
final Schema schema = getSchema( rootElementStartEvent, origin );
staxEventReader = wrapReader( staxEventReader, rootElementStartEvent );
final JAXBContext jaxbContext = getJaxbContext( rootElementStartEvent );
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema( schema );
unmarshaller.setEventHandler( handler );
final Object target = unmarshaller.unmarshal( staxEventReader );
return new BindResult( target, origin );
}
catch ( JAXBException e ) {
throw new MappingException(
"Unable to perform unmarshalling at line number " + handler.getLineNumber()
+ " and column " + handler.getColumnNumber()
+ ". Message: " + handler.getMessage(),
e,
origin
);
}
}
/**
* Identify the Schema to use to validate the document being processed.
*
* @param rootElementStartEvent The peeked event that represents the start of the root element of the document
* @param origin
*
* @return
*
* @throws JAXBException
*/
protected abstract Schema getSchema(XMLEvent rootElementStartEvent, Origin origin) throws JAXBException;
/**
* Wrap the given StAX event reader in another if needed.
*
* @param xmlEventReader The "real" reader.
* @param rootElementStartEvent The peeked event that represents the start of the root element of the document
*
* @return The wrapped reader. Simply return the given reader if no wrapping is needed.
*/
protected XMLEventReader wrapReader(XMLEventReader xmlEventReader, XMLEvent rootElementStartEvent) {
return xmlEventReader;
}
/**
* Get the JAXB context representing the Java model to bind to.
*
* @param event
*
* @return
*
* @throws JAXBException
*/
protected abstract JAXBContext getJaxbContext(XMLEvent event) throws JAXBException;
protected static boolean isNamespaced(StartElement startElement) {
return ! "".equals( startElement.getName().getNamespaceURI() );
}
}

View File

@ -1,85 +0,0 @@
/*
* 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.xml.internal.jaxb;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.validation.Schema;
import org.jboss.logging.Logger;
import org.hibernate.xml.internal.stax.LocalSchemaLocator;
import org.hibernate.xml.spi.Origin;
import org.hibernate.jaxb.spi.cfg.JaxbHibernateConfiguration;
import org.hibernate.service.ServiceRegistry;
/**
* @author Steve Ebersole
*/
public class ConfigurationXmlBinder extends AbstractXmlBinder {
private static final Logger log = Logger.getLogger( ConfigurationXmlBinder.class );
public static final String HIBERNATE_CONFIGURATION_URI = "http://www.hibernate.org/xsd/hibernate-configuration";
public ConfigurationXmlBinder(ServiceRegistry serviceRegistry) {
this( serviceRegistry, true );
}
public ConfigurationXmlBinder(ServiceRegistry serviceRegistry, boolean validateXml) {
super(serviceRegistry, validateXml);
}
@Override
protected XMLEventReader wrapReader(XMLEventReader xmlEventReader, XMLEvent event) {
if ( !isNamespaced( event.asStartElement() ) ) {
// if the elements are not namespaced, wrap the reader in a reader which will namespace them as pulled.
log.debug( "cfg.xml document did not define namespaces; wrapping in custom event reader to introduce namespace information" );
return new NamespaceAddingEventReader( xmlEventReader, HIBERNATE_CONFIGURATION_URI );
}
return super.wrapReader( xmlEventReader, event );
}
@Override
protected JAXBContext getJaxbContext(XMLEvent event) throws JAXBException{
return JAXBContext.newInstance( JaxbHibernateConfiguration.class );
}
@Override
protected Schema getSchema(XMLEvent event, Origin origin) throws JAXBException {
if ( schema == null ) {
schema = LocalSchemaLocator.resolveLocalSchema( "org/hibernate/hibernate-configuration-4.0.xsd" );
}
return schema;
}
private Schema schema;
}

View File

@ -1,156 +0,0 @@
/*
* 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.xml.internal.jaxb;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.metamodel.source.internal.jaxb.hbm.JaxbHibernateMapping;
import org.hibernate.metamodel.source.spi.MappingException;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.xml.internal.stax.LocalSchema;
import org.hibernate.xml.internal.stax.SupportedOrmXsdVersion;
import org.hibernate.xml.spi.BindResult;
import org.hibernate.xml.spi.Origin;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Loads {@code hbm.xml} and {@code orm.xml} files and processes them using StAX and JAXB.
*
* @author Steve Ebersole
* @author Hardy Ferentschik
*
* @deprecated see {@link org.hibernate.xml.internal.jaxb.UnifiedMappingBinder}
*/
@Deprecated
public class MappingXmlBinder extends AbstractXmlBinder {
public MappingXmlBinder(ServiceRegistry serviceRegistry) {
this( serviceRegistry, true );
}
public MappingXmlBinder(ServiceRegistry serviceRegistry, boolean validateXml) {
super(serviceRegistry, validateXml);
}
@Override
protected JAXBContext getJaxbContext(XMLEvent event) throws JAXBException {
final String elementName = event.asStartElement().getName().getLocalPart();
final Class jaxbTarget;
if ( "entity-mappings".equals( elementName ) ) {
jaxbTarget = JaxbEntityMappings.class;
}
else {
jaxbTarget = JaxbHibernateMapping.class;
}
return JAXBContext.newInstance( jaxbTarget );
}
@Override
protected Schema getSchema(XMLEvent event, Origin origin) throws JAXBException {
final String elementName = event.asStartElement().getName().getLocalPart();
final Schema validationSchema;
if ( "entity-mappings".equals( elementName ) ) {
return LocalSchema.MAPPING.getSchema();
}
else {
validationSchema = validateXml ? SupportedOrmXsdVersion.HBM_4_0.getSchema() : null;
}
return validationSchema;
}
@Override
protected XMLEventReader wrapReader(XMLEventReader staxEventReader, XMLEvent event) {
final String elementName = event.asStartElement().getName().getLocalPart();
if ( "entity-mappings".equals( elementName ) ) {
return new UnifiedMappingEventReader( staxEventReader );
}
else {
return new HbmEventReader( staxEventReader );
}
}
@SuppressWarnings( { "unchecked" })
public BindResult bind(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.getNodeName() ) ) {
final String explicitVersion = rootElement.getAttribute( "version" );
validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion, origin ) : null;
jaxbTarget = JaxbEntityMappings.class;
}
else {
validationSchema = validateXml ? SupportedOrmXsdVersion.HBM_4_0.getSchema() : null;
jaxbTarget = JaxbHibernateMapping.class;
}
final Object target;
try {
JAXBContext jaxbContext = JAXBContext.newInstance( jaxbTarget );
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema( validationSchema );
target = unmarshaller.unmarshal( new DOMSource( document ) );
}
catch ( JAXBException e ) {
throw new MappingException( "Unable to perform unmarshalling", e, origin );
}
return new BindResult( target, origin );
}
private Schema resolveSupportedOrmXsd(String explicitVersion, Origin origin) {
if ( StringHelper.isEmpty( explicitVersion ) ) {
return SupportedOrmXsdVersion.ORM_2_1.getSchema();
}
// Here we always use JPA 2.1 schema to do the validation, since the {@link LegacyJPAEventReader} already
// transforms the legacy orm.xml to JPA 2.1 namespace and version.
//
// This may cause some problems, like a jpa 1.0 orm.xml having some element which is only available in the later
// version. It is "invalid" but due to the fact we're using the latest schema to do the validation, then
// it is "valid". Don't know if this will cause any problems, but let's do it for now.
//
// However, still check for the validity of the version by calling #parse. If someone explicitly uses a value
// that doesn't exist, we still need to throw the exception.
SupportedOrmXsdVersion.parse( explicitVersion, origin );
return SupportedOrmXsdVersion.ORM_2_1.getSchema();
}
}

View File

@ -29,6 +29,7 @@ import javax.xml.stream.events.StartElement;
import org.hibernate.metamodel.source.internal.jaxb.hbm.JaxbHibernateMapping;
import org.hibernate.metamodel.source.internal.jaxb.hbm.HbmXmlTransformer;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.metamodel.spi.ClassLoaderAccess;
import org.hibernate.xml.internal.stax.LocalSchema;
import org.hibernate.xml.spi.Origin;
@ -41,13 +42,17 @@ import org.jboss.logging.Logger;
*/
public class UnifiedMappingBinder extends AbstractUnifiedBinder<JaxbEntityMappings> {
private static final Logger log = Logger.getLogger( UnifiedMappingBinder.class );
private final ClassLoaderAccess classLoaderAccess;
public UnifiedMappingBinder() {
public UnifiedMappingBinder(ClassLoaderAccess classLoaderAccess) {
super();
this.classLoaderAccess = classLoaderAccess;
}
public UnifiedMappingBinder(boolean validateXml) {
public UnifiedMappingBinder(boolean validateXml, ClassLoaderAccess classLoaderAccess) {
super( validateXml );
this.classLoaderAccess = classLoaderAccess;
}
@Override
@ -65,7 +70,7 @@ public class UnifiedMappingBinder extends AbstractUnifiedBinder<JaxbEntityMappin
XMLEventReader hbmReader = new HbmEventReader( staxEventReader );
JaxbHibernateMapping hbmBindings = jaxb( hbmReader, LocalSchema.HBM.getSchema(), JaxbHibernateMapping.class, origin );
return HbmXmlTransformer.INSTANCE.transform( hbmBindings, origin );
return HbmXmlTransformer.INSTANCE.transform( hbmBindings, origin, classLoaderAccess );
}
else {
final XMLEventReader reader = new UnifiedMappingEventReader( staxEventReader );

View File

@ -23,8 +23,17 @@
*/
package org.hibernate.xml.spi;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import javax.xml.transform.Source;
import org.hibernate.internal.CoreLogging;
import org.hibernate.metamodel.source.spi.InvalidMappingException;
import org.hibernate.xml.internal.jaxb.AbstractUnifiedBinder;
import org.jboss.logging.Logger;
/**
* Return object for the result of performing JAXB binding.
*
@ -32,12 +41,30 @@ import java.io.Serializable;
* @author Steve Ebersole
*/
public class BindResult<T> implements Serializable {
private final T root;
private static final Logger LOG = CoreLogging.logger( BindResult.class );
private final DelayedBinder<T> binder;
private final Origin origin;
private final boolean close;
private T root;
public BindResult(T root, Origin origin) {
this.root = root;
public BindResult(Source source, Origin origin) {
binder = new DelayedSourceBinder<T>( source );
this.origin = origin;
close = false;
}
public BindResult(InputStream inputStream, Origin origin, boolean close) {
binder = new DelayedInputStreamBinder<T>( inputStream );
this.origin = origin;
this.close = close;
}
public void bind(AbstractUnifiedBinder<T> jaxbProcessor) {
root = binder.bind( jaxbProcessor );
}
/**
@ -57,4 +84,47 @@ public class BindResult<T> implements Serializable {
public Origin getOrigin() {
return origin;
}
private interface DelayedBinder<T> {
public T bind(AbstractUnifiedBinder<T> jaxbProcessor);
}
private class DelayedSourceBinder<T> implements DelayedBinder<T> {
private final Source source;
public DelayedSourceBinder(Source source) {
this.source = source;
}
public T bind(AbstractUnifiedBinder<T> jaxbProcessor) {
return jaxbProcessor.bind( source, origin );
}
}
private class DelayedInputStreamBinder<T> implements DelayedBinder<T> {
private final InputStream inputStream;
public DelayedInputStreamBinder(InputStream inputStream) {
this.inputStream = inputStream;
}
public T bind(AbstractUnifiedBinder<T> jaxbProcessor) {
try {
return jaxbProcessor.bind( inputStream, origin );
}
catch ( Exception e ) {
throw new InvalidMappingException( origin, e );
}
finally {
if ( close ) {
try {
inputStream.close();
}
catch ( IOException ignore ) {
LOG.trace( "Was unable to close input stream" );
}
}
}
}
}
}

View File

@ -1,33 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2014, 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.xml.spi;
import java.io.InputStream;
/**
* @author Steve Ebersole
*/
public interface XmlBinder {
public BindResult bind(InputStream stream, Origin origin);
}

View File

@ -23,6 +23,9 @@
*/
package org.hibernate.metamodel.internal.source.annotations.xml.mocker;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -30,17 +33,16 @@ import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.metamodel.internal.ClassLoaderAccessImpl;
import org.hibernate.metamodel.source.internal.jandex.EntityMappingsMocker;
import org.hibernate.metamodel.source.internal.jandex.IndexBuilder;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.xml.internal.jaxb.MappingXmlBinder;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.hibernate.xml.internal.jaxb.UnifiedMappingBinder;
import org.hibernate.xml.spi.BindResult;
import org.hibernate.xml.spi.Origin;
import org.hibernate.xml.spi.SourceType;
import org.hibernate.testing.ServiceRegistryBuilder;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
@ -48,9 +50,6 @@ import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.jandex.Indexer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
/**
* @author Strong Liu
*/
@ -72,18 +71,20 @@ public abstract class AbstractMockerTest {
}
protected EntityMappingsMocker getEntityMappingsMocker(String... mappingFiles) {
MappingXmlBinder processor = new MappingXmlBinder( getServiceRegistry() );
UnifiedMappingBinder processor = new UnifiedMappingBinder(
new ClassLoaderAccessImpl(null, getServiceRegistry() ) );
ClassLoaderService classLoaderService = getServiceRegistry().getService( ClassLoaderService.class );
List<JaxbEntityMappings> xmlEntityMappingsList = new ArrayList<JaxbEntityMappings>();
List<BindResult<JaxbEntityMappings>> xmlBindings = new ArrayList<BindResult<JaxbEntityMappings>>();
for ( String fileName : mappingFiles ) {
BindResult bindResult = processor.bind(
BindResult bindResult = new BindResult(
classLoaderService.locateResourceStream( packagePrefix + fileName ),
new Origin( SourceType.FILE, packagePrefix + fileName )
new Origin( SourceType.FILE, packagePrefix + fileName ),
true
);
JaxbEntityMappings entityMappings = (JaxbEntityMappings) bindResult.getRoot();
xmlEntityMappingsList.add( entityMappings );
bindResult.bind( processor );
xmlBindings.add( bindResult );
}
return new EntityMappingsMocker( xmlEntityMappingsList, getIndex(), getServiceRegistry() );
return new EntityMappingsMocker( xmlBindings, getIndex(), getServiceRegistry() );
}
protected Index getIndex() {

View File

@ -1,79 +0,0 @@
/*
* 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.internal.source.annotations.xml.mocker;
import java.io.InputStream;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.jboss.logging.Logger;
import org.xml.sax.SAXException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.xml.spi.BindResult;
import org.hibernate.xml.spi.Origin;
/**
* @author Hardy Ferentschik
*/
public class XmlHelper {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, XmlHelper.class.getName() );
private XmlHelper() {
}
public static <T> BindResult<T> unmarshallXml(String fileName, String schemaName, Class<T> clazz, ClassLoaderService classLoaderService)
throws JAXBException {
Schema schema = getMappingSchema( schemaName, classLoaderService );
InputStream in = classLoaderService.locateResourceStream( fileName );
JAXBContext jc = JAXBContext.newInstance( clazz );
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setSchema( schema );
StreamSource stream = new StreamSource( in );
JAXBElement<T> elem = unmarshaller.unmarshal( stream, clazz );
Origin origin = new Origin( null, fileName );
return new BindResult<T>( elem.getValue(), origin );
}
private static Schema getMappingSchema(String schemaVersion, ClassLoaderService classLoaderService) {
URL schemaUrl = classLoaderService.locateResource( schemaVersion );
SchemaFactory sf = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI );
Schema schema = null;
try {
schema = sf.newSchema( schemaUrl );
}
catch ( SAXException e ) {
LOG.debugf( "Unable to create schema for %s: %s", schemaVersion, e.getMessage() );
}
return schema;
}
}

View File

@ -23,28 +23,30 @@
*/
package org.hibernate.test.metamodel.unified.jaxb;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl;
import org.hibernate.metamodel.internal.ClassLoaderAccessImpl;
import org.hibernate.metamodel.source.internal.jaxb.JaxbAttributes;
import org.hibernate.metamodel.source.internal.jaxb.JaxbBasic;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntity;
import org.hibernate.metamodel.source.internal.jaxb.JaxbEntityMappings;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.xml.internal.jaxb.UnifiedMappingBinder;
import org.hibernate.xml.spi.Origin;
import org.hibernate.xml.spi.SourceType;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Steve Ebersole
*/
public class SimpleBindingTest extends BaseUnitTestCase {
private UnifiedMappingBinder binder = new UnifiedMappingBinder( true );
private UnifiedMappingBinder binder = new UnifiedMappingBinder( true,
new ClassLoaderAccessImpl( null, new BootstrapServiceRegistryImpl() ) );
@Test
public void simpleSpecCompliantMappingTest() throws Exception {