diff --git a/.github/workflows/atlas.yml b/.github/workflows/atlas.yml index 0e019fa228..64dc670d6d 100644 --- a/.github/workflows/atlas.yml +++ b/.github/workflows/atlas.yml @@ -31,7 +31,7 @@ jobs: build: permissions: contents: read - name: Hibernate ORM + name: ORM # runs-on: ubuntu-latest runs-on: [self-hosted, Linux, X64, OCI] strategy: diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index edaa5acb82..e5508c82d6 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -119,6 +119,11 @@ xjc { xjcBindingFile = file( 'src/main/xjb/hbm-mapping-bindings.xjb' ) xjcExtensions += ['inheritance', 'simplify'] } + configuration { + xsdFile = file( 'src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd' ) + xjcBindingFile = file( 'src/main/xjb/configuration-bindings.xjb' ) + xjcExtensions += ['inheritance', 'simplify'] + } mapping { xsdFile = file( 'src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd' ) xjcBindingFile = file( 'src/main/xjb/mapping-bindings.xjb' ) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/ResourceStreamLocator.java b/hibernate-core/src/main/java/org/hibernate/boot/ResourceStreamLocator.java index cca6bf079c..222987977e 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/ResourceStreamLocator.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/ResourceStreamLocator.java @@ -8,6 +8,8 @@ package org.hibernate.boot; import java.io.InputStream; +import org.checkerframework.checker.nullness.qual.Nullable; + /** * Abstraction for locating class-path resources * @@ -25,5 +27,5 @@ public interface ResourceStreamLocator { * * @return The located resource's InputStream, or {@code null} if no match found */ - InputStream locateResourceStream(String resourceName); + @Nullable InputStream locateResourceStream(String resourceName); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/ConfigurationBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/ConfigurationBinder.java new file mode 100644 index 0000000000..5784b68640 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/ConfigurationBinder.java @@ -0,0 +1,69 @@ +/* + * 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.internal; + +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.events.StartElement; + +import org.hibernate.Internal; +import org.hibernate.boot.ResourceStreamLocator; +import org.hibernate.boot.jaxb.Origin; +import org.hibernate.boot.jaxb.configuration.spi.JaxbPersistenceImpl; +import org.hibernate.boot.jaxb.internal.stax.ConfigurationEventReader; +import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.boot.xsd.ConfigXsdSupport; +import org.hibernate.internal.util.config.ConfigurationException; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; + +/** + * @author Steve Ebersole + */ +public class ConfigurationBinder extends AbstractBinder { + private final XMLEventFactory xmlEventFactory = XMLEventFactory.newInstance(); + private JAXBContext jaxbContext; + + public ConfigurationBinder(ResourceStreamLocator resourceStreamLocator) { + super( resourceStreamLocator ); + } + + @Override + public boolean isValidationEnabled() { + return false; + } + + @Override + protected Binding doBind( + XMLEventReader staxEventReader, + StartElement rootElementStartEvent, + Origin origin) { + final XMLEventReader reader = new ConfigurationEventReader( staxEventReader, xmlEventFactory ); + final JaxbPersistenceImpl bindingRoot = jaxb( + reader, + ConfigXsdSupport.configurationXsd().getSchema(), + jaxbContext(), + origin + ); + //noinspection unchecked + return new Binding<>( (X) bindingRoot, origin ); + } + + @Internal + public JAXBContext jaxbContext() { + if ( jaxbContext == null ) { + try { + jaxbContext = JAXBContext.newInstance( JaxbPersistenceImpl.class ); + } + catch (JAXBException e) { + throw new ConfigurationException( "Unable to build configuration.xml JAXBContext", e ); + } + } + return jaxbContext; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/MappingBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/MappingBinder.java index df1c81b2f3..dec32c4ed3 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/MappingBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/MappingBinder.java @@ -39,6 +39,7 @@ import org.jboss.logging.Logger; import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; +import org.checkerframework.checker.nullness.qual.Nullable; import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN; @@ -113,7 +114,7 @@ public class MappingBinder extends AbstractBinder public MappingBinder( ResourceStreamLocator resourceStreamLocator, - Function settingsAccess) { + @Nullable Function settingsAccess) { super( resourceStreamLocator == null ? MappingBinder.class.getClassLoader()::getResourceAsStream : resourceStreamLocator ); if ( settingsAccess == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/AbstractEventReader.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/AbstractEventReader.java new file mode 100644 index 0000000000..a8ddd4fab7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/AbstractEventReader.java @@ -0,0 +1,184 @@ +/* + * 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.internal.stax; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.Attribute; +import javax.xml.stream.events.EndElement; +import javax.xml.stream.events.Namespace; +import javax.xml.stream.events.StartElement; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.util.EventReaderDelegate; + +import org.hibernate.boot.xsd.XsdDescriptor; +import org.hibernate.boot.xsd.XsdHelper; + +/** + * @author Steve Ebersole + */ +public abstract class AbstractEventReader extends EventReaderDelegate { + private static final String VERSION_ATTRIBUTE_NAME = "version"; + + private final String rootElementName; + private final XsdDescriptor xsdDescriptor; + private final XMLEventFactory xmlEventFactory; + + public AbstractEventReader( + String rootElementName, + XsdDescriptor xsdDescriptor, + XMLEventReader reader, + XMLEventFactory xmlEventFactory) { + super( reader ); + this.rootElementName = rootElementName; + this.xsdDescriptor = xsdDescriptor; + this.xmlEventFactory = xmlEventFactory; + } + + @Override + public XMLEvent peek() throws XMLStreamException { + return wrap( super.peek() ); + } + + @Override + public XMLEvent nextEvent() throws XMLStreamException { + return wrap( super.nextEvent() ); + } + + private XMLEvent wrap(XMLEvent event) { + if ( event != null ) { + if ( event.isStartElement() ) { + return wrap( event.asStartElement() ); + } + else if ( event.isEndElement() ) { + return wrap( event.asEndElement() ); + } + } + return event; + } + + private StartElement wrap(StartElement startElement) { + final List newElementAttributeList = mapAttributes( startElement ); + final List newNamespaceList = mapNamespaces( startElement ); + + // Transfer the location info from the incoming event to the event factory + // so that the event we ask it to generate for us has the same location info + xmlEventFactory.setLocation( startElement.getLocation() ); + return xmlEventFactory.createStartElement( + new QName( xsdDescriptor.getNamespaceUri(), startElement.getName().getLocalPart() ), + newElementAttributeList.iterator(), + newNamespaceList.iterator() + ); + } + + private Iterator existingXmlAttributesIterator(StartElement startElement) { + return startElement.getAttributes(); + } + + private List mapAttributes(StartElement startElement) { + final List mappedAttributes = new ArrayList<>(); + + final Iterator existingAttributesIterator = existingXmlAttributesIterator( startElement ); + while ( existingAttributesIterator.hasNext() ) { + final Attribute originalAttribute = existingAttributesIterator.next(); + final Attribute attributeToUse = mapAttribute( startElement, originalAttribute ); + mappedAttributes.add( attributeToUse ); + } + + return mappedAttributes; + } + + private Attribute mapAttribute(StartElement startElement, Attribute originalAttribute) { + // Here we look to see if this attribute is the JPA version attribute, and if so do the following: + // 1) validate its version attribute is valid per our "latest XSD" + // 2) update its version attribute to the latest version if not already + // + // NOTE : atm this is a very simple check using just the attribute's local name + // rather than checking its qualified name. It is possibly (though unlikely) + // that this could match on "other" version attributes in the same element + + if ( rootElementName.equals( startElement.getName().getLocalPart() ) ) { + if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) { + final String specifiedVersion = originalAttribute.getValue(); + + if ( !XsdHelper.isValidJpaVersion( specifiedVersion ) ) { + throw new BadVersionException( specifiedVersion ); + } + + return xmlEventFactory.createAttribute( VERSION_ATTRIBUTE_NAME, xsdDescriptor.getVersion() ); + } + } + + return originalAttribute; + } + + private List mapNamespaces(StartElement startElement) { + return mapNamespaces( existingXmlNamespacesIterator( startElement ) ); + } + + private List mapNamespaces(Iterator originalNamespaceIterator ) { + final List mappedNamespaces = new ArrayList<>(); + + while ( originalNamespaceIterator.hasNext() ) { + final Namespace originalNamespace = originalNamespaceIterator.next(); + final Namespace mappedNamespace = mapNamespace( originalNamespace ); + mappedNamespaces.add( mappedNamespace ); + } + + if ( mappedNamespaces.isEmpty() ) { + mappedNamespaces.add( xmlEventFactory.createNamespace( xsdDescriptor.getNamespaceUri() ) ); + } + + return mappedNamespaces; + } + + private Iterator existingXmlNamespacesIterator(StartElement startElement) { + return startElement.getNamespaces(); + } + + private Namespace mapNamespace(Namespace originalNamespace) { + if ( XsdHelper.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) { + // this is a namespace "to map" so map it + return xmlEventFactory.createNamespace( originalNamespace.getPrefix(), xsdDescriptor.getNamespaceUri() ); + } + + return originalNamespace; + } + + private XMLEvent wrap(EndElement endElement) { + final List targetNamespaces = mapNamespaces( existingXmlNamespacesIterator( endElement ) ); + + // Transfer the location info from the incoming event to the event factory + // so that the event we ask it to generate for us has the same location info + xmlEventFactory.setLocation( endElement.getLocation() ); + return xmlEventFactory.createEndElement( + new QName( xsdDescriptor.getNamespaceUri(), endElement.getName().getLocalPart() ), + targetNamespaces.iterator() + ); + } + + private Iterator existingXmlNamespacesIterator(EndElement endElement) { + return endElement.getNamespaces(); + } + + public static class BadVersionException extends RuntimeException { + private final String requestedVersion; + + public BadVersionException(String requestedVersion) { + this.requestedVersion = requestedVersion; + } + + public String getRequestedVersion() { + return requestedVersion; + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java new file mode 100644 index 0000000000..12a746e8f7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/ConfigurationEventReader.java @@ -0,0 +1,28 @@ +/* + * 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.internal.stax; + +import javax.xml.stream.XMLEventFactory; +import javax.xml.stream.XMLEventReader; + +import org.hibernate.boot.xsd.ConfigXsdSupport; + +/** + * @author Steve Ebersole + */ +public class ConfigurationEventReader extends AbstractEventReader { + private static final String ROOT_ELEMENT_NAME = "persistence"; + + public ConfigurationEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) { + super( + ROOT_ELEMENT_NAME, + ConfigXsdSupport.configurationXsd(), + reader, + xmlEventFactory + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/JpaOrmXmlEventReader.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/JpaOrmXmlEventReader.java index 4784f6f596..0259230e19 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/JpaOrmXmlEventReader.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/JpaOrmXmlEventReader.java @@ -21,6 +21,7 @@ import javax.xml.stream.events.XMLEvent; import javax.xml.stream.util.EventReaderDelegate; import org.hibernate.boot.xsd.MappingXsdSupport; +import org.hibernate.boot.xsd.XsdHelper; /** * StAX EVentReader which handles a few oddities specific to JPA {@code orm.xml} @@ -119,7 +120,7 @@ public class JpaOrmXmlEventReader extends EventReaderDelegate { if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) { final String specifiedVersion = originalAttribute.getValue(); - if ( ! MappingXsdSupport.isValidJpaVersion( specifiedVersion ) ) { + if ( ! XsdHelper.isValidJpaVersion( specifiedVersion ) ) { throw new BadVersionException( specifiedVersion ); } @@ -156,7 +157,7 @@ public class JpaOrmXmlEventReader extends EventReaderDelegate { } private Namespace mapNamespace(Namespace originalNamespace) { - if ( MappingXsdSupport.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) { + if ( XsdHelper.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) { // this is a namespace "to map" so map it return xmlEventFactory.createNamespace( originalNamespace.getPrefix(), diff --git a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/MappingEventReader.java b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/MappingEventReader.java index ece40ccb92..98d9c03ccc 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/MappingEventReader.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/stax/MappingEventReader.java @@ -6,19 +6,8 @@ */ package org.hibernate.boot.jaxb.internal.stax; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import javax.xml.namespace.QName; import javax.xml.stream.XMLEventFactory; import javax.xml.stream.XMLEventReader; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.events.Attribute; -import javax.xml.stream.events.EndElement; -import javax.xml.stream.events.Namespace; -import javax.xml.stream.events.StartElement; -import javax.xml.stream.events.XMLEvent; -import javax.xml.stream.util.EventReaderDelegate; import org.hibernate.boot.xsd.MappingXsdSupport; @@ -28,156 +17,11 @@ import org.hibernate.boot.xsd.MappingXsdSupport; * @author Steve Ebersole * @author Hardy Ferentschik */ -public class MappingEventReader extends EventReaderDelegate { +public class MappingEventReader extends AbstractEventReader { private static final String ROOT_ELEMENT_NAME = "entity-mappings"; - private static final String VERSION_ATTRIBUTE_NAME = "version"; - - private final XMLEventFactory xmlEventFactory; public MappingEventReader(XMLEventReader reader, XMLEventFactory xmlEventFactory) { - super( reader ); - this.xmlEventFactory = xmlEventFactory; + super( ROOT_ELEMENT_NAME, MappingXsdSupport.latestDescriptor(), reader, xmlEventFactory ); } - @Override - public XMLEvent peek() throws XMLStreamException { - return wrap( super.peek() ); - } - - @Override - public XMLEvent nextEvent() throws XMLStreamException { - return wrap( super.nextEvent() ); - } - - private XMLEvent wrap(XMLEvent event) { - if ( event != null ) { - if ( event.isStartElement() ) { - return wrap( event.asStartElement() ); - } - else if ( event.isEndElement() ) { - return wrap( event.asEndElement() ); - } - } - return event; - } - - private StartElement wrap(StartElement startElement) { - final List newElementAttributeList = mapAttributes( startElement ); - final List newNamespaceList = mapNamespaces( startElement ); - - // Transfer the location info from the incoming event to the event factory - // so that the event we ask it to generate for us has the same location info - xmlEventFactory.setLocation( startElement.getLocation() ); - return xmlEventFactory.createStartElement( - new QName( MappingXsdSupport.latestDescriptor().getNamespaceUri(), startElement.getName().getLocalPart() ), - newElementAttributeList.iterator(), - newNamespaceList.iterator() - ); - } - - private List mapAttributes(StartElement startElement) { - final List mappedAttributes = new ArrayList<>(); - - final Iterator existingAttributesIterator = existingXmlAttributesIterator( startElement ); - while ( existingAttributesIterator.hasNext() ) { - final Attribute originalAttribute = existingAttributesIterator.next(); - final Attribute attributeToUse = mapAttribute( startElement, originalAttribute ); - mappedAttributes.add( attributeToUse ); - } - - return mappedAttributes; - } - - private Iterator existingXmlAttributesIterator(StartElement startElement) { - return startElement.getAttributes(); - } - - private Attribute mapAttribute(StartElement startElement, Attribute originalAttribute) { - // Here we look to see if this attribute is the JPA version attribute, and if so do the following: - // 1) validate its version attribute is valid per our "latest XSD" - // 2) update its version attribute to the latest version if not already - // - // NOTE : atm this is a very simple check using just the attribute's local name - // rather than checking its qualified name. It is possibly (though unlikely) - // that this could match on "other" version attributes in the same element - - if ( ROOT_ELEMENT_NAME.equals( startElement.getName().getLocalPart() ) ) { - if ( VERSION_ATTRIBUTE_NAME.equals( originalAttribute.getName().getLocalPart() ) ) { - final String specifiedVersion = originalAttribute.getValue(); - - if ( ! MappingXsdSupport.isValidJpaVersion( specifiedVersion ) ) { - throw new BadVersionException( specifiedVersion ); - } - - return xmlEventFactory.createAttribute( VERSION_ATTRIBUTE_NAME, MappingXsdSupport.latestDescriptor().getVersion() ); - } - } - - return originalAttribute; - } - - private List mapNamespaces(StartElement startElement) { - return mapNamespaces( existingXmlNamespacesIterator( startElement ) ); - } - - private List mapNamespaces(Iterator originalNamespaceIterator ) { - final List mappedNamespaces = new ArrayList<>(); - - while ( originalNamespaceIterator.hasNext() ) { - final Namespace originalNamespace = originalNamespaceIterator.next(); - final Namespace mappedNamespace = mapNamespace( originalNamespace ); - mappedNamespaces.add( mappedNamespace ); - } - - if ( mappedNamespaces.isEmpty() ) { - mappedNamespaces.add( xmlEventFactory.createNamespace( MappingXsdSupport.latestDescriptor().getNamespaceUri() ) ); - } - - return mappedNamespaces; - } - - @SuppressWarnings("unchecked") - private Iterator existingXmlNamespacesIterator(StartElement startElement) { - return startElement.getNamespaces(); - } - - private Namespace mapNamespace(Namespace originalNamespace) { - if ( MappingXsdSupport.shouldBeMappedToLatestJpaDescriptor( originalNamespace.getNamespaceURI() ) ) { - // this is a namespace "to map" so map it - return xmlEventFactory.createNamespace( - originalNamespace.getPrefix(), - MappingXsdSupport.latestDescriptor().getNamespaceUri() - ); - } - - return originalNamespace; - } - - private XMLEvent wrap(EndElement endElement) { - final List targetNamespaces = mapNamespaces( existingXmlNamespacesIterator( endElement ) ); - - // Transfer the location info from the incoming event to the event factory - // so that the event we ask it to generate for us has the same location info - xmlEventFactory.setLocation( endElement.getLocation() ); - return xmlEventFactory.createEndElement( - new QName( MappingXsdSupport.latestDescriptor().getNamespaceUri(), endElement.getName().getLocalPart() ), - targetNamespaces.iterator() - ); - } - - private Iterator existingXmlNamespacesIterator(EndElement endElement) { - return endElement.getNamespaces(); - } - - public static class BadVersionException extends RuntimeException { - private final String requestedVersion; - - public BadVersionException(String requestedVersion) { - this.requestedVersion = requestedVersion; - } - - public String getRequestedVersion() { - return requestedVersion; - } - } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java b/hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java index a5fb3294d7..f06df19810 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/xsd/ConfigXsdSupport.java @@ -26,14 +26,15 @@ public class ConfigXsdSupport { * Needs synchronization on any access. * Custom keys: * 0: cfgXml - * 1: JPA 1.0 - * 2: JPA 2.0 - * 3: JPA 2.1 - * 4: JPA 2.2 (default) - * 5: Jakarta Persistence 3.0 - * 6: Jakarta Persistence 3.1 + * 1: configurationXML + * 2: JPA 1.0 + * 3: JPA 2.0 + * 4: JPA 2.1 + * 5: JPA 2.2 (default) + * 6: Jakarta Persistence 3.0 + * 7: Jakarta Persistence 3.1 */ - private static final XsdDescriptor[] xsdCache = new XsdDescriptor[7]; + private static final XsdDescriptor[] xsdCache = new XsdDescriptor[8]; public XsdDescriptor latestJpaDescriptor() { return getJPA31(); @@ -64,6 +65,9 @@ public class ConfigXsdSupport { case "3.1": { return getJPA31(); } + case "3.2": { + return getJPA32(); + } default: { throw new IllegalArgumentException( "Unrecognized JPA persistence.xml XSD version : `" + version + "`" ); } @@ -86,8 +90,24 @@ public class ConfigXsdSupport { } } - public static XsdDescriptor getJPA10() { + public static XsdDescriptor configurationXsd() { final int index = 1; + synchronized ( xsdCache ) { + XsdDescriptor cfgXml = xsdCache[index]; + if ( cfgXml == null ) { + cfgXml = LocalXsdResolver.buildXsdDescriptor( + "org/hibernate/xsd/cfg/configuration-3.2.0.xsd", + "3.2.0" , + "http://www.hibernate.org/xsd/orm/configuration" + ); + xsdCache[index] = cfgXml; + } + return cfgXml; + } + } + + public static XsdDescriptor getJPA10() { + final int index = 2; synchronized ( xsdCache ) { XsdDescriptor jpa10 = xsdCache[index]; if ( jpa10 == null ) { @@ -119,7 +139,7 @@ public class ConfigXsdSupport { } public static XsdDescriptor getJPA21() { - final int index = 3; + final int index = 4; synchronized ( xsdCache ) { XsdDescriptor jpa21 = xsdCache[index]; if ( jpa21 == null ) { @@ -135,7 +155,7 @@ public class ConfigXsdSupport { } public static XsdDescriptor getJPA22() { - final int index = 4; + final int index = 5; synchronized ( xsdCache ) { XsdDescriptor jpa22 = xsdCache[index]; if ( jpa22 == null ) { @@ -151,7 +171,7 @@ public class ConfigXsdSupport { } public static XsdDescriptor getJPA30() { - final int index = 5; + final int index = 6; synchronized ( xsdCache ) { XsdDescriptor jpa30 = xsdCache[index]; if ( jpa30 == null ) { @@ -167,7 +187,7 @@ public class ConfigXsdSupport { } public static XsdDescriptor getJPA31() { - final int index = 6; + final int index = 7; synchronized ( xsdCache ) { XsdDescriptor jpa31 = xsdCache[index]; if ( jpa31 == null ) { @@ -181,5 +201,21 @@ public class ConfigXsdSupport { return jpa31; } } + + public static XsdDescriptor getJPA32() { + final int index = 8; + synchronized ( xsdCache ) { + XsdDescriptor jpa32 = xsdCache[index]; + if ( jpa32 == null ) { + jpa32 = LocalXsdResolver.buildXsdDescriptor( + "org/hibernate/jpa/persistence_3_2.xsd", + "3.2", + "https://jakarta.ee/xml/ns/persistence" + ); + xsdCache[index] = jpa32; + } + return jpa32; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java b/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java index 241cc26c7a..7ebf52fd31 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/xsd/MappingXsdSupport.java @@ -101,26 +101,6 @@ public class MappingXsdSupport { return jpa32; } - public static boolean shouldBeMappedToLatestJpaDescriptor(String uri) { - // JPA 1.0 and 2.0 share the same namespace URI - return jpa10.getNamespaceUri().equals( uri ); - } - - public static boolean isValidJpaVersion(String version) { - switch ( version ) { - case "1.0": - case "2.0": - case "2.1": - case "2.2": - case "3.0": - case "3.1": - case "3.2": - return true; - default: - return false; - } - } - public XsdDescriptor jpaXsd(String version) { switch ( version ) { case "1.0": { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/xsd/XsdHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/xsd/XsdHelper.java new file mode 100644 index 0000000000..71e013cb4a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/xsd/XsdHelper.java @@ -0,0 +1,24 @@ +/* + * 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.xsd; + +/** + * @author Steve Ebersole + */ +public class XsdHelper { + public static boolean isValidJpaVersion(String version) { + return switch ( version ) { + case "1.0", "2.0", "2.1", "2.2", "3.0", "3.1", "3.2" -> true; + default -> false; + }; + } + + public static boolean shouldBeMappedToLatestJpaDescriptor(String uri) { + // JPA 1.0 and 2.0 share the same namespace URI + return MappingXsdSupport.jpa10.getNamespaceUri().equals( uri ); + } +} diff --git a/tooling/metamodel-generator/src/main/xsd/persistence_3_0.xsd b/hibernate-core/src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd similarity index 87% rename from tooling/metamodel-generator/src/main/xsd/persistence_3_0.xsd rename to hibernate-core/src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd index e2a2943937..d79c90c675 100644 --- a/tooling/metamodel-generator/src/main/xsd/persistence_3_0.xsd +++ b/hibernate-core/src/main/resources/org/hibernate/xsd/cfg/configuration-3.2.0.xsd @@ -1,47 +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. + --> - + - ... - + + ... + ]]> @@ -186,7 +170,7 @@ @@ -283,7 +267,7 @@ + fixed="3.1" use="required"/> diff --git a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd index 76cb6f52e7..a5505b82dc 100644 --- a/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd +++ b/hibernate-core/src/main/resources/org/hibernate/xsd/mapping/mapping-3.2.0.xsd @@ -1,4 +1,5 @@ + - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/RuntimeModelSmokeTests.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/RuntimeModelSmokeTests.java index 91ba520540..3845898c9f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/RuntimeModelSmokeTests.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/RuntimeModelSmokeTests.java @@ -6,29 +6,23 @@ */ package org.hibernate.orm.test.envers; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; - -import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.envers.Audited; -import org.hibernate.envers.DefaultRevisionEntity; -import org.hibernate.mapping.PersistentClass; import org.hibernate.metamodel.RuntimeMetamodels; -import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.orm.junit.DomainModel; -import org.hibernate.testing.orm.junit.DomainModelScope; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.Setting; import org.junit.jupiter.api.Test; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; /** @@ -54,9 +48,6 @@ public class RuntimeModelSmokeTests { final EntityPersister mappingType = runtimeMetamodels.getMappingMetamodel().findEntityDescriptor( FULL_NAME ); assertThat( mappingType, notNullValue() ); - - final EntityDomainType jpaType = runtimeMetamodels.getJpaMetamodel().entity( SIMPLE_NAME ); - assertThat( jpaType, notNullValue() ); } @Entity( name = "SimpleEntity" ) diff --git a/settings.gradle b/settings.gradle index 9ff60115d3..8dbf193fa1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -30,16 +30,15 @@ dependencyResolutionManagement { url( rootProject.property( "mavenMirror" ) ) } mavenCentral() - if (System.getProperty('JPA_PREVIEW') != null) { - // Needed for the RC versions of Jakarta Persistence - maven { - url "https://jakarta.oss.sonatype.org/content/repositories/releases/" - } - // Needed for the SNAPSHOT versions of Jakarta Persistence - maven { - url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/" - } - } + if (System.getProperty('JPA_PREVIEW') != null) { // Needed for the RC versions of Jakarta Persistence + maven { + url "https://jakarta.oss.sonatype.org/content/repositories/releases/" + } + // Needed for the SNAPSHOT versions of Jakarta Persistence + maven { + url "https://jakarta.oss.sonatype.org/content/repositories/snapshots/" + } + } //Allow loading additional dependencies from a local path; //useful to load JDBC drivers which can not be distributed in public. diff --git a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle index 84780c9374..6af12021b4 100644 --- a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle +++ b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle @@ -4,20 +4,28 @@ * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or . */ -plugins { - id 'org.hibernate.build.xjc-jakarta' -} - description = 'Hibernate compile-time tooling' apply from: rootProject.file( 'gradle/published-java-module.gradle' ) apply plugin: 'version-injection' -ext { - xjcTargetDir = file( "${buildDir}/generated/sources/xjc/main" ) - xsdDir = file( "${projectDir}/src/main/xsd" ) +java { + sourceCompatibility = jdks.versions.getBaseline( ) + targetCompatibility = 17 } +//configurations { +// modelImplementation { +// extendsFrom implementation +// } +// modelAnnotationProcessor { +// extendsFrom annotationProcessor +// } +// testImplementation { +// extendsFrom modelImplementation +// } +//} + sourceSets { quarkusOrmPanache { java { @@ -64,10 +72,6 @@ dependencies { api libs.byteBuddy api libs.logging - xjc jakartaLibs.xjc - xjc jakartaLibs.jaxb - xjc rootProject.fileTree(dir: 'patched-libs/jaxb2-basics', include: '*.jar') - quarkusOrmPanacheImplementation "io.quarkus:quarkus-hibernate-orm-panache:3.6.2" quarkusHrPanacheImplementation "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2" jakartaDataImplementation "jakarta.data:jakarta.data-api:1.0.0" @@ -121,14 +125,14 @@ test.dependsOn quarkusHrPanacheTestTask test.dependsOn quarkusOrmPanacheTestTask sourceSets.main { - java.srcDir xjcTargetDir + java.srcDir xjcTargetDir resources.srcDir xsdDir } compileTestJava { - options.compilerArgs += [ - "-proc:none", - "-AsuppressJakartaDataMetamodel=true" + options.compilerArgs += [ + "-proc:none", + "-AsuppressJakartaDataMetamodel=true" ] } @@ -193,29 +197,29 @@ else { task jaxb { - // configure Gradle up-to-date checking - inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE ) - outputs.dir( xjcTargetDir ) - outputs.cacheIf { true } + // configure Gradle up-to-date checking + inputs.dir( xsdDir ).withPropertyName("xsdDir" ).withPathSensitivity( PathSensitivity.RELATIVE ) + outputs.dir( xjcTargetDir ) + outputs.cacheIf { true } - // perform actions - doLast { - xjcTargetDir.mkdirs() + // perform actions + doLast { + xjcTargetDir.mkdirs() - ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.xjc.asPath) + ant.taskdef(name: 'xjc', classname: 'org.jvnet.jaxb2_commons.xjc.XJC2Task', classpath: configurations.xjc.asPath) - ant.xjc( - destdir: ( xjcTargetDir as File ).absolutePath, - package: 'org.hibernate.processor.xml.jaxb', - extension: 'true' - ) { - project.ant.arg line: '-no-header' - project.ant.arg line: '-npa' - schema( dir: xsdDir.path, includes: "*.xsd" ) - } - } + ant.xjc( + destdir: ( xjcTargetDir as File ).absolutePath, + package: 'org.hibernate.processor.xml.jaxb', + extension: 'true' + ) { + project.ant.arg line: '-no-header' + project.ant.arg line: '-npa' + schema( dir: xsdDir.path, includes: "*.xsd" ) + } + } } -tasks.sourcesJar.dependsOn jaxb + tasks.sourcesJar.dependsOn ':hibernate-core:generateHqlParser' tasks.sourcesJar.dependsOn ':hibernate-core:generateSqlScriptParser' tasks.compileJava.dependsOn jaxb diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java index 95a65d14cb..7b03e7f27a 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java @@ -27,10 +27,13 @@ import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; +import org.hibernate.jpamodelgen.model.Metamodel; +import org.hibernate.jpamodelgen.util.AccessTypeInformation; import org.hibernate.processor.model.Metamodel; import org.hibernate.processor.util.AccessType; import org.hibernate.processor.util.AccessTypeInformation; +import jakarta.persistence.AccessType; import org.checkerframework.checker.nullness.qual.Nullable; import static java.lang.Boolean.parseBoolean; @@ -412,7 +415,7 @@ public final class Context { public void setUsesQuarkusOrm(boolean b) { usesQuarkusOrm = b; } - + public boolean usesQuarkusOrm() { return usesQuarkusOrm; } @@ -420,7 +423,7 @@ public final class Context { public void setUsesQuarkusReactive(boolean b) { usesQuarkusReactive = b; } - + public boolean usesQuarkusReactive() { return usesQuarkusReactive; } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java index 82cd48a73d..55d115e521 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java @@ -54,6 +54,26 @@ import javax.lang.model.type.WildcardType; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.hibernate.jpamodelgen.Context; +import org.hibernate.jpamodelgen.ImportContextImpl; +import org.hibernate.jpamodelgen.ProcessLaterException; +import org.hibernate.jpamodelgen.model.ImportContext; +import org.hibernate.jpamodelgen.model.MetaAttribute; +import org.hibernate.jpamodelgen.model.Metamodel; +import org.hibernate.jpamodelgen.util.AccessTypeInformation; +import org.hibernate.jpamodelgen.util.Constants; +import org.hibernate.jpamodelgen.validation.ProcessorSessionFactory; +import org.hibernate.jpamodelgen.validation.Validation; +import org.hibernate.metamodel.model.domain.EntityDomainType; +import org.hibernate.query.criteria.JpaEntityJoin; +import org.hibernate.query.criteria.JpaRoot; +import org.hibernate.query.criteria.JpaSelection; +import org.hibernate.query.sqm.SqmExpressible; +import org.hibernate.query.sqm.tree.SqmStatement; +import org.hibernate.query.sqm.tree.expression.SqmParameter; +import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -63,6 +83,8 @@ import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Pattern; +import jakarta.persistence.AccessType; + import static java.beans.Introspector.decapitalize; import static java.lang.Boolean.FALSE; import static java.util.Collections.emptyList; @@ -154,7 +176,7 @@ public class AnnotationMetaEntity extends AnnotationMeta { * The field or method call to obtain the session */ private String sessionGetter = "entityManager"; - + private final Map memberTypes = new HashMap<>(); /** @@ -580,7 +602,7 @@ public class AnnotationMetaEntity extends AnnotationMeta { } return null; } - + private void setupSession() { if ( element.getTypeParameters().isEmpty() ) { jakartaDataRepository = hasAnnotation( element, JD_REPOSITORY ); @@ -2537,7 +2559,6 @@ public class AnnotationMetaEntity extends AnnotationMeta { return returnTypeName.equals( UNI_VOID ) || returnTypeName.equals( UNI_BOOLEAN ) || returnTypeName.equals( UNI_INTEGER ); - } else { // non-reactive diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessType.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessType.java index 314d8c2df0..20588f5b53 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessType.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessType.java @@ -10,6 +10,27 @@ package org.hibernate.processor.util; * @author Hardy Ferentschik */ public enum AccessType { - PROPERTY, - FIELD + PROPERTY( jakarta.persistence.AccessType.PROPERTY ), + FIELD( jakarta.persistence.AccessType.FIELD ); + + private final jakarta.persistence.AccessType jpaAccessType; + + AccessType(jakarta.persistence.AccessType jpaAccessType) { + this.jpaAccessType = jpaAccessType; + } + + public jakarta.persistence.AccessType getJpaAccessType() { + return jpaAccessType; + } + + public static AccessType fromJpaAccessType(jakarta.persistence.AccessType jpaAccessType) { + if ( jpaAccessType == jakarta.persistence.AccessType.FIELD ) { + return FIELD; + } + if ( jpaAccessType == jakarta.persistence.AccessType.PROPERTY ) { + return PROPERTY; + } + + throw new IllegalArgumentException( "Unknown JPA AccessType - " + jpaAccessType.name() ); + } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessTypeInformation.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessTypeInformation.java index e0817314df..3dde49f425 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessTypeInformation.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/AccessTypeInformation.java @@ -6,6 +6,7 @@ */ package org.hibernate.processor.util; +import jakarta.persistence.AccessType; import org.checkerframework.checker.nullness.qual.Nullable; /** diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java index 724dd3c866..17a1315e5a 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java @@ -31,6 +31,10 @@ import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleTypeVisitor8; import javax.tools.Diagnostic; + +import jakarta.persistence.AccessType; +import org.hibernate.jpamodelgen.Context; +import org.hibernate.jpamodelgen.MetaModelGenerationException; import java.util.HashMap; import java.util.HashSet; import java.util.List; diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/xml/XmlParserHelper.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/xml/XmlParserHelper.java index e13929c39a..4c0f872682 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/xml/XmlParserHelper.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/xml/XmlParserHelper.java @@ -23,6 +23,10 @@ import javax.xml.stream.XMLStreamException; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; +import org.hibernate.boot.jaxb.cfg.spi.ObjectFactory; + +import org.hibernate.jpamodelgen.Context; +import org.hibernate.jpamodelgen.util.NullnessUtil; import org.hibernate.processor.Context; import org.hibernate.processor.util.NullnessUtil; import org.hibernate.processor.xml.jaxb.ObjectFactory; diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/JpaDescriptorParser.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/JpaDescriptorParser.java index 8182fbd061..13d2c94934 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/JpaDescriptorParser.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/JpaDescriptorParser.java @@ -19,11 +19,31 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.function.Function; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.tools.Diagnostic; -import javax.xml.validation.Schema; +import org.hibernate.MappingException; +import org.hibernate.boot.jaxb.Origin; +import org.hibernate.boot.jaxb.SourceType; +import org.hibernate.boot.jaxb.configuration.spi.JaxbPersistenceImpl; +import org.hibernate.boot.jaxb.internal.ConfigurationBinder; +import org.hibernate.boot.jaxb.internal.MappingBinder; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitDefaultsImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbPersistenceUnitMetadataImpl; +import org.hibernate.boot.jaxb.spi.Binding; +import org.hibernate.boot.jaxb.spi.JaxbBindableMappingDescriptor; +import org.hibernate.jpamodelgen.Context; +import org.hibernate.jpamodelgen.util.AccessTypeInformation; +import org.hibernate.jpamodelgen.util.FileTimeStampChecker; +import org.hibernate.jpamodelgen.util.StringUtil; +import org.hibernate.jpamodelgen.util.TypeUtils; +import org.hibernate.jpamodelgen.util.xml.XmlParserHelper; import org.hibernate.processor.Context; import org.hibernate.processor.util.AccessType; import org.hibernate.processor.util.AccessTypeInformation; @@ -38,6 +58,7 @@ import org.hibernate.processor.xml.jaxb.Persistence; import org.hibernate.processor.xml.jaxb.PersistenceUnitDefaults; import org.hibernate.processor.xml.jaxb.PersistenceUnitMetadata; +import jakarta.persistence.AccessType; import org.checkerframework.checker.nullness.qual.Nullable; /** @@ -49,20 +70,26 @@ public class JpaDescriptorParser { private static final String DEFAULT_ORM_XML_LOCATION = "/META-INF/orm.xml"; private static final String SERIALIZATION_FILE_NAME = "Hibernate-Static-Metamodel-Generator.tmp"; - private static final String PERSISTENCE_SCHEMA = "persistence_3_0.xsd"; - private static final String ORM_SCHEMA = "orm_3_1.xsd"; + private static final String PERSISTENCE_SCHEMA = "org/hibernate/xsd/cfg/persistence_3_0.xsd"; + private final Context context; - private final List entityMappings; + private final List entityMappings; private final XmlParserHelper xmlParserHelper; + private final ConfigurationBinder configurationBinder; + private final MappingBinder mappingBinder; public JpaDescriptorParser(Context context) { this.context = context; this.entityMappings = new ArrayList<>(); this.xmlParserHelper = new XmlParserHelper( context ); + + final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( context ); + this.configurationBinder = new ConfigurationBinder( resourceStreamLocator ); + this.mappingBinder = new MappingBinder( resourceStreamLocator, (Function) null ); } - public void parseXml() { + public void parseMappingXml() { Collection mappingFileNames = determineMappingFileNames(); if ( context.doLazyXmlParsing() && mappingFilesUnchanged( mappingFileNames ) ) { @@ -78,22 +105,22 @@ public class JpaDescriptorParser { determineAnnotationAccessTypes(); } - for ( EntityMappings mappings : entityMappings ) { + for ( JaxbEntityMappingsImpl mappings : entityMappings ) { String defaultPackageName = mappings.getPackage(); - parseEntities( mappings.getEntity(), defaultPackageName ); - parseEmbeddable( mappings.getEmbeddable(), defaultPackageName ); - parseMappedSuperClass( mappings.getMappedSuperclass(), defaultPackageName ); + parseEntities( mappings.getEntities(), defaultPackageName ); + parseEmbeddable( mappings.getEmbeddables(), defaultPackageName ); + parseMappedSuperClass( mappings.getMappedSuperclasses(), defaultPackageName ); } } private Collection determineMappingFileNames() { Collection mappingFileNames = new ArrayList<>(); - Persistence persistence = getPersistence(); + JaxbPersistenceImpl persistence = getPersistence(); if ( persistence != null ) { // get mapping file names from persistence.xml - List persistenceUnits = persistence.getPersistenceUnit(); - for ( Persistence.PersistenceUnit unit : persistenceUnits ) { + List persistenceUnits = persistence.getPersistenceUnit(); + for ( JaxbPersistenceImpl.JaxbPersistenceUnitImpl unit : persistenceUnits ) { mappingFileNames.addAll( unit.getMappingFile() ); } } @@ -107,19 +134,26 @@ public class JpaDescriptorParser { return mappingFileNames; } - private @Nullable Persistence getPersistence() { - Persistence persistence = null; - String persistenceXmlLocation = context.getPersistenceXmlLocation(); + private @Nullable JaxbPersistenceImpl getPersistence() { + JaxbPersistenceImpl persistence = null; + + final String persistenceXmlLocation = context.getPersistenceXmlLocation(); final InputStream stream = xmlParserHelper.getInputStreamForResource( persistenceXmlLocation ); if ( stream == null ) { return null; } try { - Schema schema = xmlParserHelper.getSchema( PERSISTENCE_SCHEMA ); - persistence = xmlParserHelper.getJaxbRoot( stream, Persistence.class, schema ); + final Binding binding = configurationBinder.bind( + stream, + new Origin( SourceType.RESOURCE, persistenceXmlLocation ) + ); + persistence = binding.getRoot(); } - catch (XmlParsingException e) { + catch (MappingException e) { + throw e; + } + catch (Exception e) { context.logMessage( Diagnostic.Kind.WARNING, "Unable to parse persistence.xml: " + e.getMessage() ); @@ -137,26 +171,31 @@ public class JpaDescriptorParser { } private void loadEntityMappings(Collection mappingFileNames) { + final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( context ); + for ( String mappingFile : mappingFileNames ) { - final InputStream stream = xmlParserHelper.getInputStreamForResource( mappingFile ); - if ( stream == null ) { + final InputStream inputStream = resourceStreamLocator.locateResourceStream( mappingFile ); + if ( inputStream == null ) { + // todo (jpa32) : log continue; } try { - final Schema schema = xmlParserHelper.getSchema( ORM_SCHEMA ); - final EntityMappings mapping = xmlParserHelper.getJaxbRoot( stream, EntityMappings.class, schema ); - if ( mapping != null ) { - entityMappings.add( mapping ); + final Binding binding = mappingBinder.bind( + inputStream, + new Origin( SourceType.RESOURCE, mappingFile ) + ); + if ( binding != null ) { + entityMappings.add( (JaxbEntityMappingsImpl) binding.getRoot() ); } } - catch (XmlParsingException e) { + catch (Exception e) { context.logMessage( Diagnostic.Kind.WARNING, "Unable to parse " + mappingFile + ": " + e.getMessage() ); } finally { try { - stream.close(); + inputStream.close(); } catch (IOException e) { // eat it @@ -236,8 +275,8 @@ public class JpaDescriptorParser { return new FileTimeStampChecker(); } - private void parseEntities(Collection entities, String defaultPackageName) { - for ( Entity entity : entities ) { + private void parseEntities(List entities, String defaultPackageName) { + for ( JaxbEntityImpl entity : entities ) { String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, entity.getClazz() ); if ( !xmlMappedTypeExists( fqcn ) ) { @@ -262,9 +301,9 @@ public class JpaDescriptorParser { } private void parseEmbeddable( - Collection embeddables, + List embeddables, String defaultPackageName) { - for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : embeddables ) { + for ( JaxbEmbeddableImpl embeddable : embeddables ) { String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, embeddable.getClazz() ); // we have to extract the package name from the fqcn. Maybe the entity was setting a fqcn directly String pkg = StringUtil.packageNameFromFqcn( fqcn ); @@ -289,9 +328,9 @@ public class JpaDescriptorParser { } private void parseMappedSuperClass( - Collection mappedSuperClasses, + List mappedSuperClasses, String defaultPackageName) { - for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappedSuperClasses ) { + for ( JaxbMappedSuperclassImpl mappedSuperClass : mappedSuperClasses ) { String fqcn = StringUtil.determineFullyQualifiedClassName( defaultPackageName, mappedSuperClass.getClazz() ); @@ -306,8 +345,7 @@ public class JpaDescriptorParser { continue; } - XmlMetaEntity metaEntity = new XmlMetaEntity( - mappedSuperClass, pkg, getXmlMappedType( fqcn ), context + XmlMetaEntity metaEntity = new XmlMetaEntity( mappedSuperClass, pkg, getXmlMappedType( fqcn ), context ); if ( context.containsMetaEntity( fqcn ) ) { @@ -330,71 +368,53 @@ public class JpaDescriptorParser { return utils.getTypeElement( fullyQualifiedClassName ); } - private AccessType determineEntityAccessType(EntityMappings mappings) { - AccessType accessType = context.getPersistenceUnitDefaultAccessType(); - final org.hibernate.processor.xml.jaxb.AccessType mappingsAccess = mappings.getAccess(); + private AccessType determineEntityAccessType(JaxbEntityMappingsImpl mappings) { + final AccessType contextAccessType = context.getPersistenceUnitDefaultAccessType(); + final AccessType mappingsAccess = mappings.getAccess(); if ( mappingsAccess != null ) { - accessType = mapXmlAccessTypeToJpaAccessType( mappingsAccess ); + return mappingsAccess; } - return accessType; + return contextAccessType; } private void determineXmlAccessTypes() { - for ( EntityMappings mappings : entityMappings ) { + for ( JaxbEntityMappingsImpl mappings : entityMappings ) { String fqcn; String packageName = mappings.getPackage(); AccessType defaultAccessType = determineEntityAccessType( mappings ); - for ( Entity entity : mappings.getEntity() ) { - String name = entity.getClazz(); + for ( JaxbEntityImpl entity : mappings.getEntities() ) { + final String name = entity.getClazz(); fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name ); - AccessType explicitAccessType = null; - org.hibernate.processor.xml.jaxb.AccessType type = entity.getAccess(); - if ( type != null ) { - explicitAccessType = mapXmlAccessTypeToJpaAccessType( type ); - } - AccessTypeInformation accessInfo = new AccessTypeInformation( - fqcn, explicitAccessType, defaultAccessType - ); + final AccessType explicitAccessType = entity.getAccess(); + final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType ); context.addAccessTypeInformation( fqcn, accessInfo ); } - for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappings.getMappedSuperclass() ) { - String name = mappedSuperClass.getClazz(); + for ( JaxbMappedSuperclassImpl mappedSuperClass : mappings.getMappedSuperclasses() ) { + final String name = mappedSuperClass.getClazz(); fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name ); - AccessType explicitAccessType = null; - org.hibernate.processor.xml.jaxb.AccessType type = mappedSuperClass.getAccess(); - if ( type != null ) { - explicitAccessType = mapXmlAccessTypeToJpaAccessType( type ); - } - AccessTypeInformation accessInfo = new AccessTypeInformation( - fqcn, explicitAccessType, defaultAccessType - ); + final AccessType explicitAccessType = mappedSuperClass.getAccess(); + final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType ); context.addAccessTypeInformation( fqcn, accessInfo ); } - for ( org.hibernate.processor.xml.jaxb.Embeddable embeddable : mappings.getEmbeddable() ) { - String name = embeddable.getClazz(); + for ( JaxbEmbeddableImpl embeddable : mappings.getEmbeddables() ) { + final String name = embeddable.getClazz(); fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name ); - AccessType explicitAccessType = null; - org.hibernate.processor.xml.jaxb.AccessType type = embeddable.getAccess(); - if ( type != null ) { - explicitAccessType = mapXmlAccessTypeToJpaAccessType( type ); - } - AccessTypeInformation accessInfo = new AccessTypeInformation( - fqcn, explicitAccessType, defaultAccessType - ); + final AccessType explicitAccessType = embeddable.getAccess(); + final AccessTypeInformation accessInfo = new AccessTypeInformation( fqcn, explicitAccessType, defaultAccessType ); context.addAccessTypeInformation( fqcn, accessInfo ); } } } private void determineAnnotationAccessTypes() { - for ( EntityMappings mappings : entityMappings ) { + for ( JaxbEntityMappingsImpl mappings : entityMappings ) { String fqcn; String packageName = mappings.getPackage(); - for ( Entity entity : mappings.getEntity() ) { + for ( JaxbEntityImpl entity : mappings.getEntities() ) { String name = entity.getClazz(); fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name ); TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn ); @@ -403,7 +423,7 @@ public class JpaDescriptorParser { } } - for ( org.hibernate.processor.xml.jaxb.MappedSuperclass mappedSuperClass : mappings.getMappedSuperclass() ) { + for ( JaxbMappedSuperclassImpl mappedSuperClass : mappings.getMappedSuperclasses() ) { String name = mappedSuperClass.getClazz(); fqcn = StringUtil.determineFullyQualifiedClassName( packageName, name ); TypeElement element = context.getTypeElementForFullyQualifiedName( fqcn ); @@ -430,16 +450,16 @@ public class JpaDescriptorParser { * */ private void determineDefaultAccessTypeAndMetaCompleteness() { - for ( EntityMappings mappings : entityMappings ) { - PersistenceUnitMetadata meta = mappings.getPersistenceUnitMetadata(); + for ( JaxbEntityMappingsImpl mappings : entityMappings ) { + JaxbPersistenceUnitMetadataImpl meta = mappings.getPersistenceUnitMetadata(); if ( meta != null ) { context.mappingDocumentFullyXmlConfigured( meta.getXmlMappingMetadataComplete() != null ); - PersistenceUnitDefaults persistenceUnitDefaults = meta.getPersistenceUnitDefaults(); + JaxbPersistenceUnitDefaultsImpl persistenceUnitDefaults = meta.getPersistenceUnitDefaults(); if ( persistenceUnitDefaults != null ) { - org.hibernate.processor.xml.jaxb.AccessType xmlAccessType = persistenceUnitDefaults.getAccess(); - if ( xmlAccessType != null ) { - context.setPersistenceUnitDefaultAccessType( mapXmlAccessTypeToJpaAccessType( xmlAccessType ) ); + final jakarta.persistence.AccessType xmlJpaAccessType = persistenceUnitDefaults.getAccess(); + if ( xmlJpaAccessType != null ) { + context.setPersistenceUnitDefaultAccessType( xmlJpaAccessType ); } } } @@ -448,14 +468,4 @@ public class JpaDescriptorParser { } } } - - private AccessType mapXmlAccessTypeToJpaAccessType(org.hibernate.processor.xml.jaxb.AccessType xmlAccessType) { - switch ( xmlAccessType ) { - case FIELD: - return AccessType.FIELD; - case PROPERTY: - return AccessType.PROPERTY; - } - throw new IllegalArgumentException( "Unknown access type: " + xmlAccessType ); - } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/ResourceStreamLocatorImpl.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/ResourceStreamLocatorImpl.java new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/XmlMetaEntity.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/XmlMetaEntity.java index 452f1f424e..d4f803c892 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/XmlMetaEntity.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/xml/XmlMetaEntity.java @@ -18,6 +18,32 @@ import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeMirror; import javax.tools.Diagnostic; +import org.hibernate.boot.jaxb.mapping.spi.JaxbAttributesContainerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbBasicImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbElementCollectionImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableAttributesContainerImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddableImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMapKeyClassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbMappedSuperclassImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToManyImpl; +import org.hibernate.boot.jaxb.mapping.spi.JaxbOneToOneImpl; +import org.hibernate.jpamodelgen.Context; +import org.hibernate.jpamodelgen.ImportContextImpl; +import org.hibernate.jpamodelgen.MetaModelGenerationException; +import org.hibernate.jpamodelgen.model.ImportContext; +import org.hibernate.jpamodelgen.model.MetaAttribute; +import org.hibernate.jpamodelgen.model.Metamodel; +import org.hibernate.jpamodelgen.util.AccessTypeInformation; +import org.hibernate.jpamodelgen.util.Constants; +import org.hibernate.jpamodelgen.util.NullnessUtil; +import org.hibernate.jpamodelgen.util.StringUtil; +import org.hibernate.jpamodelgen.util.TypeUtils; import org.hibernate.processor.Context; import org.hibernate.processor.ImportContextImpl; import org.hibernate.processor.MetaModelGenerationException; @@ -45,8 +71,12 @@ import org.hibernate.processor.xml.jaxb.MappedSuperclass; import org.hibernate.processor.xml.jaxb.OneToMany; import org.hibernate.processor.xml.jaxb.OneToOne; +import jakarta.persistence.AccessType; import org.checkerframework.checker.nullness.qual.Nullable; +import static jakarta.persistence.AccessType.FIELD; +import static org.hibernate.jpamodelgen.util.StringUtil.determineFullyQualifiedClassName; +import static org.hibernate.jpamodelgen.util.TypeUtils.getElementKindForAccessType; import static java.util.Collections.emptyList; import static org.hibernate.processor.util.StringUtil.determineFullyQualifiedClassName; import static org.hibernate.processor.util.TypeUtils.extractClosestRealTypeAsString; @@ -70,8 +100,8 @@ public class XmlMetaEntity implements Metamodel { private final Context context; private final boolean isMetaComplete; - private @Nullable Attributes attributes; - private @Nullable EmbeddableAttributes embeddableAttributes; + private @Nullable JaxbAttributesContainerImpl attributes; + private @Nullable JaxbEmbeddableAttributesContainerImpl embeddableAttributes; private AccessTypeInformation accessTypeInfo; /** @@ -87,20 +117,20 @@ public class XmlMetaEntity implements Metamodel { */ private boolean initialized; - XmlMetaEntity(Entity ormEntity, String defaultPackageName, TypeElement element, Context context) { + XmlMetaEntity(JaxbEntityImpl ormEntity, String defaultPackageName, TypeElement element, Context context) { this( ormEntity.getClazz(), defaultPackageName, element, context, ormEntity.isMetadataComplete() ); this.attributes = ormEntity.getAttributes(); this.embeddableAttributes = null; } - static XmlMetaEntity create(Entity ormEntity, String defaultPackageName, TypeElement element, Context context) { + static XmlMetaEntity create(JaxbEntityImpl ormEntity, String defaultPackageName, TypeElement element, Context context) { XmlMetaEntity entity = new XmlMetaEntity( ormEntity, defaultPackageName, element, context ); // entities can be directly initialised entity.init(); return entity; } - XmlMetaEntity(MappedSuperclass mappedSuperclass, String defaultPackageName, TypeElement element, Context context) { + XmlMetaEntity(JaxbMappedSuperclassImpl mappedSuperclass, String defaultPackageName, TypeElement element, Context context) { this( mappedSuperclass.getClazz(), defaultPackageName, @@ -112,7 +142,7 @@ public class XmlMetaEntity implements Metamodel { this.embeddableAttributes = null; } - XmlMetaEntity(Embeddable embeddable, String defaultPackageName, TypeElement element, Context context) { + XmlMetaEntity(JaxbEmbeddableImpl embeddable, String defaultPackageName, TypeElement element, Context context) { this( embeddable.getClazz(), defaultPackageName, element, context, embeddable.isMetadataComplete() ); this.attributes = null; this.embeddableAttributes = embeddable.getAttributes(); @@ -365,98 +395,98 @@ public class XmlMetaEntity implements Metamodel { return null; } - private void parseAttributes(Attributes attributes) { + private void parseAttributes(JaxbAttributesContainerImpl attributes) { XmlMetaSingleAttribute attribute; - for ( Id id : attributes.getId() ) { - ElementKind elementKind = getElementKind( id.getAccess() ); - String type = getType( id.getName(), null, elementKind ); + for ( JaxbIdImpl id : attributes.getIdAttributes() ) { + final ElementKind elementKind = getElementKind( id.getAccess() ); + final String type = getType( id.getName(), null, elementKind ); if ( type != null ) { attribute = new XmlMetaSingleAttribute( this, id.getName(), type ); members.add( attribute ); } } - if ( attributes.getEmbeddedId() != null ) { - EmbeddedId embeddedId = attributes.getEmbeddedId(); - ElementKind elementKind = getElementKind( embeddedId.getAccess() ); - String type = getType( embeddedId.getName(), null, elementKind ); + if ( attributes.getEmbeddedIdAttribute() != null ) { + final JaxbEmbeddedIdImpl embeddedId = attributes.getEmbeddedIdAttribute(); + final ElementKind elementKind = getElementKind( embeddedId.getAccess() ); + final String type = getType( embeddedId.getName(), null, elementKind ); if ( type != null ) { attribute = new XmlMetaSingleAttribute( this, embeddedId.getName(), type ); members.add( attribute ); } } - for ( Basic basic : attributes.getBasic() ) { + for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) { parseBasic( basic ); } - for ( ManyToOne manyToOne : attributes.getManyToOne() ) { + for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) { parseManyToOne( manyToOne ); } - for ( OneToOne oneToOne : attributes.getOneToOne() ) { + for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) { parseOneToOne( oneToOne ); } - for ( ManyToMany manyToMany : attributes.getManyToMany() ) { + for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) { if ( parseManyToMany( manyToMany ) ) { break; } } - for ( OneToMany oneToMany : attributes.getOneToMany() ) { + for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) { if ( parseOneToMany( oneToMany ) ) { break; } } - for ( ElementCollection collection : attributes.getElementCollection() ) { + for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) { if ( parseElementCollection( collection ) ) { break; } } - for ( Embedded embedded : attributes.getEmbedded() ) { + for ( JaxbEmbeddedImpl embedded : attributes.getEmbeddedAttributes() ) { parseEmbedded( embedded ); } } - private void parseEmbeddableAttributes(@Nullable EmbeddableAttributes attributes) { + private void parseEmbeddableAttributes(@Nullable JaxbEmbeddableAttributesContainerImpl attributes) { if ( attributes == null ) { return; } - for ( Basic basic : attributes.getBasic() ) { + for ( JaxbBasicImpl basic : attributes.getBasicAttributes() ) { parseBasic( basic ); } - for ( ManyToOne manyToOne : attributes.getManyToOne() ) { + for ( JaxbManyToOneImpl manyToOne : attributes.getManyToOneAttributes() ) { parseManyToOne( manyToOne ); } - for ( OneToOne oneToOne : attributes.getOneToOne() ) { + for ( JaxbOneToOneImpl oneToOne : attributes.getOneToOneAttributes() ) { parseOneToOne( oneToOne ); } - for ( ManyToMany manyToMany : attributes.getManyToMany() ) { + for ( JaxbManyToManyImpl manyToMany : attributes.getManyToManyAttributes() ) { if ( parseManyToMany( manyToMany ) ) { break; } } - for ( OneToMany oneToMany : attributes.getOneToMany() ) { + for ( JaxbOneToManyImpl oneToMany : attributes.getOneToManyAttributes() ) { if ( parseOneToMany( oneToMany ) ) { break; } } - for ( ElementCollection collection : attributes.getElementCollection() ) { + for ( JaxbElementCollectionImpl collection : attributes.getElementCollectionAttributes() ) { if ( parseElementCollection( collection ) ) { break; } } } - private boolean parseElementCollection(ElementCollection collection) { + private boolean parseElementCollection(JaxbElementCollectionImpl collection) { @Nullable String @Nullable[] types; XmlMetaCollection metaCollection; ElementKind elementKind = getElementKind( collection.getAccess() ); @@ -486,7 +516,7 @@ public class XmlMetaEntity implements Metamodel { return false; } - private void parseEmbedded(Embedded embedded) { + private void parseEmbedded(JaxbEmbeddedImpl embedded) { XmlMetaSingleAttribute attribute; ElementKind elementKind = getElementKind( embedded.getAccess() ); String type = getType( embedded.getName(), null, elementKind ); @@ -504,7 +534,7 @@ public class XmlMetaEntity implements Metamodel { return explicitTargetClass; } - private @Nullable String determineExplicitMapKeyClass(MapKeyClass mapKeyClass) { + private @Nullable String determineExplicitMapKeyClass(JaxbMapKeyClassImpl mapKeyClass) { String explicitMapKey = null; if ( mapKeyClass != null ) { explicitMapKey = determineFullyQualifiedClassName( defaultPackageName, mapKeyClass.getClazz() ); @@ -512,7 +542,7 @@ public class XmlMetaEntity implements Metamodel { return explicitMapKey; } - private boolean parseOneToMany(OneToMany oneToMany) { + private boolean parseOneToMany(JaxbOneToManyImpl oneToMany) { @Nullable String @Nullable [] types; XmlMetaCollection metaCollection; ElementKind elementKind = getElementKind( oneToMany.getAccess() ); @@ -540,7 +570,7 @@ public class XmlMetaEntity implements Metamodel { return false; } - private boolean parseManyToMany(ManyToMany manyToMany) { + private boolean parseManyToMany(JaxbManyToManyImpl manyToMany) { @Nullable String @Nullable [] types; XmlMetaCollection metaCollection; ElementKind elementKind = getElementKind( manyToMany.getAccess() ); @@ -570,7 +600,7 @@ public class XmlMetaEntity implements Metamodel { return false; } - private void parseOneToOne(OneToOne oneToOne) { + private void parseOneToOne(JaxbOneToOneImpl oneToOne) { XmlMetaSingleAttribute attribute; ElementKind elementKind = getElementKind( oneToOne.getAccess() ); String type = getType( oneToOne.getName(), oneToOne.getTargetEntity(), elementKind ); @@ -580,7 +610,7 @@ public class XmlMetaEntity implements Metamodel { } } - private void parseManyToOne(ManyToOne manyToOne) { + private void parseManyToOne(JaxbManyToOneImpl manyToOne) { XmlMetaSingleAttribute attribute; ElementKind elementKind = getElementKind( manyToOne.getAccess() ); String type = getType( manyToOne.getName(), manyToOne.getTargetEntity(), elementKind ); @@ -590,7 +620,7 @@ public class XmlMetaEntity implements Metamodel { } } - private void parseBasic(Basic basic) { + private void parseBasic(JaxbBasicImpl basic) { XmlMetaSingleAttribute attribute; ElementKind elementKind = getElementKind( basic.getAccess() ); String type = getType( basic.getName(), null, elementKind ); @@ -614,7 +644,7 @@ public class XmlMetaEntity implements Metamodel { ); } - private ElementKind getElementKind(org.hibernate.processor.xml.jaxb.AccessType accessType) { + private ElementKind getElementKind(AccessType accessType) { // if no explicit access type was specified in xml we use the entity access type if ( accessType == null ) { return getElementKindForAccessType( accessTypeInfo.getAccessType() ); diff --git a/tooling/metamodel-generator/src/main/xsd/orm_3_1.xsd b/tooling/metamodel-generator/src/main/xsd/orm_3_1.xsd deleted file mode 100644 index f233261efa..0000000000 --- a/tooling/metamodel-generator/src/main/xsd/orm_3_1.xsd +++ /dev/null @@ -1,2325 +0,0 @@ - - - - - - - - - ... - - - - ]]> - - - - - - - - - - - - - - - - - - The entity-mappings element is the root element of a mapping - file. It contains the following four types of elements: - - 1. The persistence-unit-metadata element contains metadata - for the entire persistence unit. It is undefined if this element - occurs in multiple mapping files within the same persistence unit. - - 2. The package, schema, catalog and access elements apply to all of - the entity, mapped-superclass and embeddable elements defined in - the same file in which they occur. - - 3. The sequence-generator, table-generator, converter, named-query, - named-native-query, named-stored-procedure-query, and - sql-result-set-mapping elements are global to the persistence - unit. It is undefined to have more than one sequence-generator - or table-generator of the same name in the same or different - mapping files in a persistence unit. It is undefined to have - more than one named-query, named-native-query, sql-result-set-mapping, - or named-stored-procedure-query of the same name in the same - or different mapping files in a persistence unit. It is also - undefined to have more than one converter for the same target - type in the same or different mapping files in a persistence unit. - - 4. The entity, mapped-superclass and embeddable elements each define - the mapping information for a managed persistent class. The mapping - information contained in these elements may be complete or it may - be partial. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Metadata that applies to the persistence unit and not just to - the mapping file in which it is contained. - - If the xml-mapping-metadata-complete element is specified, - the complete set of mapping metadata for the persistence unit - is contained in the XML mapping files for the persistence unit. - - - - - - - - - - - - - - - - - These defaults are applied to the persistence unit as a whole - unless they are overridden by local annotation or XML - element settings. - - schema - Used as the schema for all tables, secondary tables, join - tables, collection tables, sequence generators, and table - generators that apply to the persistence unit - catalog - Used as the catalog for all tables, secondary tables, join - tables, collection tables, sequence generators, and table - generators that apply to the persistence unit - delimited-identifiers - Used to treat database identifiers as - delimited identifiers. - access - Used as the access type for all managed classes in - the persistence unit - cascade-persist - Adds cascade-persist to the set of cascade options - in all entity relationships of the persistence unit - entity-listeners - List of default entity listeners to be invoked - on each entity in the persistence unit. - - - - - - - - - - - - - - - - - - - - Defines the settings and mappings for an entity. Is allowed to be - sparsely populated and used in conjunction with the annotations. - Alternatively, the metadata-complete attribute can be used to - indicate that no annotations on the entity class (and its fields - or properties) are to be processed. If this is the case then - the defaulting rules for the entity and its subelements will - be recursively applied. - - @Target(TYPE) @Retention(RUNTIME) - public @interface Entity { - String name() default ""; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This element determines how the persistence provider accesses the - state of an entity or embedded object. - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface AssociationOverride { - String name(); - JoinColumn[] joinColumns() default{}; - JoinTable joinTable() default @JoinTable; - } - - - - - - - - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface AttributeOverride { - String name(); - Column column(); - } - - - - - - - - - - - - - - - - - This element contains the entity field or property mappings. - It may be sparsely populated to include only a subset of the - fields or properties. If metadata-complete for the entity is true - then the remainder of the attributes will be defaulted according - to the default rules. - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Basic { - FetchType fetch() default EAGER; - boolean optional() default true; - } - - - - - - - - - - - - - - - - - - - - - - - - - public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH}; - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface CollectionTable { - String name() default ""; - String catalog() default ""; - String schema() default ""; - JoinColumn[] joinColumns() default {}; - UniqueConstraint[] uniqueConstraints() default {}; - Index[] indexes() default {}; - } - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Column { - String name() default ""; - boolean unique() default false; - boolean nullable() default true; - boolean insertable() default true; - boolean updatable() default true; - String columnDefinition() default ""; - String table() default ""; - int length() default 255; - int precision() default 0; // decimal precision - int scale() default 0; // decimal scale - } - - - - - - - - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface ColumnResult { - String name(); - Class type() default void.class; - } - - - - - - - - - - - - - - public enum ConstraintMode {CONSTRAINT, NO_CONSTRAINT, PROVIDER_DEFAULT}; - - - - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface ConstructorResult { - Class targetClass(); - ColumnResult[] columns(); - } - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface Convert { - Class converter() default void.class; - String attributeName() default ""; - boolean disableConversion() default false; - } - - - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface Converter { - boolean autoApply() default false; - } - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface DiscriminatorColumn { - String name() default "DTYPE"; - DiscriminatorType discriminatorType() default STRING; - String columnDefinition() default ""; - int length() default 31; - } - - - - - - - - - - - - - - - - public enum DiscriminatorType { STRING, CHAR, INTEGER }; - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface DiscriminatorValue { - String value(); - } - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface ElementCollection { - Class targetClass() default void.class; - FetchType fetch() default LAZY; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Defines the settings and mappings for embeddable objects. Is - allowed to be sparsely populated and used in conjunction with - the annotations. Alternatively, the metadata-complete attribute - can be used to indicate that no annotations are to be processed - in the class. If this is the case then the defaulting rules will - be recursively applied. - - @Target({TYPE}) @Retention(RUNTIME) - public @interface Embeddable {} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Embedded {} - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface EmbeddedId {} - - - - - - - - - - - - - - - - - Defines an entity listener to be invoked at lifecycle events - for the entities that list this listener. - - - - - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface EntityListeners { - Class[] value(); - } - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface EntityResult { - Class entityClass(); - FieldResult[] fields() default {}; - String discriminatorColumn() default ""; - } - - - - - - - - - - - - - - - - - public enum EnumType { - ORDINAL, - STRING - } - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Enumerated { - EnumType value() default ORDINAL; - } - - - - - - - - - - - - - public enum FetchType { LAZY, EAGER }; - - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface FieldResult { - String name(); - String column(); - } - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface ForeignKey { - String name() default ""; - ConstraintMode value() default CONSTRAINT; - String foreign-key-definition() default ""; - - Note that the elements that embed the use of the annotation - default this use as @ForeignKey(PROVIDER_DEFAULT). - - } - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface GeneratedValue { - GenerationType strategy() default AUTO; - String generator() default ""; - } - - - - - - - - - - - - - - public enum GenerationType { TABLE, SEQUENCE, IDENTITY, UUID, AUTO }; - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Id {} - - - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface IdClass { - Class value(); - } - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface Index { - String name() default ""; - String columnList(); - boolean unique() default false; - } - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface Inheritance { - InheritanceType strategy() default SINGLE_TABLE; - } - - - - - - - - - - - - - public enum InheritanceType - { SINGLE_TABLE, JOINED, TABLE_PER_CLASS}; - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface JoinColumn { - String name() default ""; - String referencedColumnName() default ""; - boolean unique() default false; - boolean nullable() default true; - boolean insertable() default true; - boolean updatable() default true; - String columnDefinition() default ""; - String table() default ""; - ForeignKey foreignKey() default @ForeignKey(); - } - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface JoinTable { - String name() default ""; - String catalog() default ""; - String schema() default ""; - JoinColumn[] joinColumns() default {}; - JoinColumn[] inverseJoinColumns() default {}; - UniqueConstraint[] uniqueConstraints() default {}; - Index[] indexes() default {}; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Lob {} - - - - - - - - - - - - public enum LockModeType { READ, WRITE, OPTIMISTIC, OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC_READ, PESSIMISTIC_WRITE, PESSIMISTIC_FORCE_INCREMENT, NONE}; - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface ManyToMany { - Class targetEntity() default void.class; - CascadeType[] cascade() default {}; - FetchType fetch() default LAZY; - String mappedBy() default ""; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface ManyToOne { - Class targetEntity() default void.class; - CascadeType[] cascade() default {}; - FetchType fetch() default EAGER; - boolean optional() default true; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface MapKey { - String name() default ""; - } - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface MapKeyClass { - Class value(); - } - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface MapKeyColumn { - String name() default ""; - boolean unique() default false; - boolean nullable() default false; - boolean insertable() default true; - boolean updatable() default true; - String columnDefinition() default ""; - String table() default ""; - int length() default 255; - int precision() default 0; // decimal precision - int scale() default 0; // decimal scale - } - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface MapKeyJoinColumn { - String name() default ""; - String referencedColumnName() default ""; - boolean unique() default false; - boolean nullable() default false; - boolean insertable() default true; - boolean updatable() default true; - String columnDefinition() default ""; - String table() default ""; - } - - - - - - - - - - - - - - - - - - - - - Defines the settings and mappings for a mapped superclass. Is - allowed to be sparsely populated and used in conjunction with - the annotations. Alternatively, the metadata-complete attribute - can be used to indicate that no annotations are to be processed - If this is the case then the defaulting rules will be recursively - applied. - - @Target(TYPE) @Retention(RUNTIME) - public @interface MappedSuperclass{} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface NamedAttributeNode { - String value(); - String subgraph() default ""; - String keySubgraph() default ""; - } - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface NamedEntityGraph { - String name() default ""; - NamedAttributeNode[] attributeNodes() default {}; - boolean includeAllAttributes() default false; - NamedSubgraph[] subgraphs() default {}; - NamedSubGraph[] subclassSubgraphs() default {}; - } - - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface NamedNativeQuery { - String name(); - String query(); - QueryHint[] hints() default {}; - Class resultClass() default void.class; - String resultSetMapping() default ""; //named SqlResultSetMapping - } - - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface NamedQuery { - String name(); - String query(); - LockModeType lockMode() default NONE; - QueryHint[] hints() default {}; - } - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface NamedStoredProcedureQuery { - String name(); - String procedureName(); - StoredProcedureParameter[] parameters() default {}; - Class[] resultClasses() default {}; - String[] resultSetMappings() default{}; - QueryHint[] hints() default {}; - } - - - - - - - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface NamedSubgraph { - String name(); - Class type() default void.class; - NamedAttributeNode[] attributeNodes(); - } - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface OneToMany { - Class targetEntity() default void.class; - CascadeType[] cascade() default {}; - FetchType fetch() default LAZY; - String mappedBy() default ""; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface OneToOne { - Class targetEntity() default void.class; - CascadeType[] cascade() default {}; - FetchType fetch() default EAGER; - boolean optional() default true; - String mappedBy() default ""; - boolean orphanRemoval() default false; - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface OrderBy { - String value() default ""; - } - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface OrderColumn { - String name() default ""; - boolean nullable() default true; - boolean insertable() default true; - boolean updatable() default true; - String columnDefinition() default ""; - } - - - - - - - - - - - - - - - - - public enum ParameterMode { IN, INOUT, OUT, REF_CURSOR}; - - - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PostLoad {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PostPersist {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PostRemove {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PostUpdate {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PrePersist {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PreRemove {} - - - - - - - - - - - - - - - - @Target({METHOD}) @Retention(RUNTIME) - public @interface PreUpdate {} - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface PrimaryKeyJoinColumn { - String name() default ""; - String referencedColumnName() default ""; - String columnDefinition() default ""; - } - - - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface QueryHint { - String name(); - String value(); - } - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface SecondaryTable { - String name(); - String catalog() default ""; - String schema() default ""; - PrimaryKeyJoinColumn[] pkJoinColumns() default {}; - UniqueConstraint[] uniqueConstraints() default {}; - Index[] indexes() default {}; - } - - - - - - - - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface SequenceGenerator { - String name(); - String sequenceName() default ""; - String catalog() default ""; - String schema() default ""; - int initialValue() default 1; - int allocationSize() default 50; - } - - - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface SqlResultSetMapping { - String name(); - EntityResult[] entities() default {}; - ConstructorResult[] classes() default{}; - ColumnResult[] columns() default {}; - } - - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface StoredProcedureParameter { - String name() default ""; - ParameterMode mode() default ParameterMode.IN; - Class type(); - } - - - - - - - - - - - - - - - - - - @Target({TYPE}) @Retention(RUNTIME) - public @interface Table { - String name() default ""; - String catalog() default ""; - String schema() default ""; - UniqueConstraint[] uniqueConstraints() default {}; - Index[] indexes() default {}; - } - - - - - - - - - - - - - - - - - - - @Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME) - public @interface TableGenerator { - String name(); - String table() default ""; - String catalog() default ""; - String schema() default ""; - String pkColumnName() default ""; - String valueColumnName() default ""; - String pkColumnValue() default ""; - int initialValue() default 0; - int allocationSize() default 50; - UniqueConstraint[] uniqueConstraints() default {}; - Indexes[] indexes() default {}; - } - - - - - - - - - - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Temporal { - TemporalType value(); - } - - - - - - - - - - - - - public enum TemporalType { - DATE, // java.sql.Date - TIME, // java.sql.Time - TIMESTAMP // java.sql.Timestamp - } - - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Transient {} - - - - - - - - - - - - - @Target({}) @Retention(RUNTIME) - public @interface UniqueConstraint { - String name() default ""; - String[] columnNames(); - } - - - - - - - - - - - - - - - - @Target({METHOD, FIELD}) @Retention(RUNTIME) - public @interface Version {} - - - - - - - - - - - - diff --git a/tooling/metamodel-generator/src/test/resources/org/hibernate/processor/test/xmlonly/persistence.xml b/tooling/metamodel-generator/src/test/resources/org/hibernate/processor/test/xmlonly/persistence.xml index f022e8fa72..d4b7923ffb 100644 --- a/tooling/metamodel-generator/src/test/resources/org/hibernate/processor/test/xmlonly/persistence.xml +++ b/tooling/metamodel-generator/src/test/resources/org/hibernate/processor/test/xmlonly/persistence.xml @@ -6,9 +6,9 @@ ~ See the lgpl.txt file in the root directory or . --> - + version="3.2"> /org/hibernate/processor/test/xmlonly/xmlonly.xml