Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

merge master

  • Loading branch information...
commit 72c5f8f5e9f5773b6406a526f7f1b23802f309f0 2 parents 5edee45 + e4c1db1
@stliu stliu authored
Showing with 6,768 additions and 3,960 deletions.
  1. +1 −1  hibernate-core/hibernate-core.gradle
  2. +21 −13 hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java
  3. +3 −2 hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
  4. +31 −18 hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
  5. +45 −25 hibernate-core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
  6. +1 −1  hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
  7. +21 −1 hibernate-core/src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverriddenAnnotationReader.java
  8. +15 −0 hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java
  9. +147 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/BaseXMLEventReader.java
  10. +196 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/BufferedXMLEventReader.java
  11. +3 −12 hibernate-core/src/main/java/org/hibernate/internal/util/xml/ErrorLogger.java
  12. +141 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/FilteringXMLEventReader.java
  13. +148 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/LocalXmlResourceResolver.java
  14. +295 −158 hibernate-core/src/main/java/org/hibernate/internal/util/xml/MappingReader.java
  15. +43 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/UnsupportedOrmXsdVersionException.java
  16. +69 −0 hibernate-core/src/main/java/org/hibernate/internal/util/xml/XMLStreamConstantsUtils.java
  17. +2 −0  hibernate-core/src/main/java/org/hibernate/internal/util/xml/XmlDocument.java
  18. +5 −2 hibernate-core/src/main/java/org/hibernate/internal/util/xml/XmlDocumentImpl.java
  19. +8 −22 ...core/src/main/java/org/hibernate/internal/util/xml/{OriginImpl.java → XmlInfrastructureException.java}
  20. +33 −31 hibernate-core/src/main/java/org/hibernate/jaxb/internal/JaxbMappingProcessor.java
  21. +89 −0 hibernate-core/src/main/java/org/hibernate/jaxb/internal/LegacyJPAEventReader.java
  22. +11 −9 hibernate-core/src/main/java/org/hibernate/jaxb/internal/NamespaceAddingEventReader.java
  23. +3 −3 hibernate-core/src/main/java/org/hibernate/mapping/Collection.java
  24. +5 −27 hibernate-core/src/main/java/org/hibernate/mapping/Table.java
  25. +1,540 −1,540 hibernate-core/src/main/resources/org/hibernate/{ejb → jpa}/orm_1_0.xsd
  26. 0  hibernate-core/src/main/resources/org/hibernate/{ejb → jpa}/orm_2_0.xsd
  27. 0  {hibernate-entitymanager → hibernate-core}/src/main/resources/org/hibernate/jpa/orm_2_1.xsd
  28. +1 −1  hibernate-core/src/main/xjb/orm-bindings.xjb
  29. +2 −0  hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/xml/OrmXmlParserTests.java
  30. +15 −19 ...e-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/xml/mocker/AbstractMockerTest.java
  31. +143 −0 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/AbstractJPAIndexTest.java
  32. +89 −6 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/Car.java
  33. +22 −3 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/Dealer.java
  34. +70 −0 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/Importer.java
  35. +5 −128 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/IndexTest.java
  36. +15 −0 hibernate-core/src/test/java/org/hibernate/test/annotations/index/jpa/OrmXmlIndexTest.java
  37. +9 −10 hibernate-core/src/test/java/org/hibernate/test/annotations/xml/ejb3/NonExistentOrmVersionTest.java
  38. +84 −21 hibernate-core/src/test/java/org/hibernate/test/constraint/ConstraintTest.java
  39. +2 −1  hibernate-core/src/test/java/org/hibernate/test/hqlfetchscroll/HQLScrollFetchTest.java
  40. +14 −4 hibernate-core/src/test/java/org/hibernate/test/querycache/StringCompositeKey.java
  41. +67 −0 hibernate-core/src/test/resources/org/hibernate/test/annotations/index/jpa/orm-index.xml
  42. +4 −2 hibernate-entitymanager/src/main/java/org/hibernate/ejb/packaging/NamedInputStream.java
  43. +2 −2 hibernate-entitymanager/src/main/java/org/hibernate/ejb/packaging/Scanner.java
  44. +35 −68 ...g/hibernate/jpa/{packaging/internal/JarVisitorFactory.java → boot/archive/internal/ArchiveHelper.java}
  45. +212 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/internal/ExplodedArchiveDescriptor.java
  46. +193 −0 ...nate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/internal/JarFileBasedArchiveDescriptor.java
  47. +168 −0 ...titymanager/src/main/java/org/hibernate/jpa/boot/archive/internal/JarInputStreamBasedArchiveDescriptor.java
  48. +71 −0 ...rnate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/internal/JarProtocolArchiveDescriptor.java
  49. +105 −0 ...e-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/internal/StandardArchiveDescriptorFactory.java
  50. +92 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/spi/AbstractArchiveDescriptor.java
  51. +37 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/spi/ArchiveContext.java
  52. +9 −15 ...main/java/org/hibernate/jpa/{packaging/internal/Filter.java → boot/archive/spi/ArchiveDescriptor.java}
  53. +39 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/spi/ArchiveDescriptorFactory.java
  54. +19 −13 ...igin.java → hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/spi/ArchiveEntry.java
  55. +33 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/archive/spi/ArchiveEntryHandler.java
  56. +15 −14 .../java/org/hibernate/jpa/{packaging/internal/ClassFilter.java → boot/archive/spi/ArchiveException.java}
  57. +60 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/ByteArrayInputStreamAccess.java
  58. +29 −23 ...c/main/java/org/hibernate/jpa/{packaging/internal/Entry.java → boot/internal/ClassDescriptorImpl.java}
  59. +345 −306 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java
  60. +77 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/FileInputStreamAccess.java
  61. +73 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/MappingFileDescriptorImpl.java
  62. +68 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/PackageDescriptorImpl.java
  63. +3 −3 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/PersistenceXmlParser.java
  64. +62 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/internal/UrlInputStreamAccess.java
  65. +67 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/internal/StandardScanOptions.java
  66. +40 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/internal/StandardScanner.java
  67. +67 −0 ...te-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractJavaArtifactArchiveEntryHandler.java
  68. +302 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/AbstractScannerImpl.java
  69. +125 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ClassFileArchiveEntryHandler.java
  70. +87 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/NonClassFileArchiveEntryHandler.java
  71. +79 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/PackageInfoArchiveEntryHandler.java
  72. +12 −16 ...c/main/java/org/hibernate/jpa/{packaging/internal/PackageFilter.java → boot/scan/spi/ScanOptions.java}
  73. +41 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/scan/spi/ScanResult.java
  74. +18 −18 ...ager/src/main/java/org/hibernate/jpa/{packaging/internal/JarVisitor.java → boot/scan/spi/Scanner.java}
  75. +34 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/spi/ClassDescriptor.java
  76. +52 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/spi/InputStreamAccess.java
  77. +32 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/spi/MappingFileDescriptor.java
  78. +11 −12 hibernate-entitymanager/src/main/java/org/hibernate/jpa/{packaging → boot}/spi/NamedInputStream.java
  79. +34 −0 hibernate-entitymanager/src/main/java/org/hibernate/jpa/boot/spi/PackageDescriptor.java
  80. +0 −262 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/AbstractJarVisitor.java
  81. +0 −138 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/ExplodedJarVisitor.java
  82. +0 −43 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/FileFilter.java
  83. +0 −133 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/FileZippedJarVisitor.java
  84. +0 −121 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/InputStreamZippedJarVisitor.java
  85. +0 −73 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/JarProtocolVisitor.java
  86. +0 −52 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/JavaElementFilter.java
  87. +0 −248 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/internal/NativeScanner.java
  88. +0 −67 hibernate-entitymanager/src/main/java/org/hibernate/jpa/packaging/spi/Scanner.java
  89. +67 −0 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/TestHelper.java
  90. +9 −30 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/packaging/CustomScanner.java
  91. +208 −199 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/packaging/JarVisitorTest.java
  92. +9 −2 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/packaging/PackagingTestCase.java
  93. +43 −35 hibernate-entitymanager/src/test/java/org/hibernate/jpa/test/packaging/ScannerTest.java
  94. +24 −5 hibernate-envers/src/main/java/org/hibernate/envers/event/BaseEnversCollectionEventListener.java
  95. +9 −1 hibernate-envers/src/main/java/org/hibernate/envers/event/EnversPreCollectionRemoveEventListenerImpl.java
  96. +95 −0 ...nate-envers/src/test/java/org/hibernate/envers/test/entities/manytomany/unidirectional/JoinTableEntity.java
  97. +137 −0 ...rs/src/test/java/org/hibernate/envers/test/integration/manytomany/unidirectional/JoinTableDetachedTest.java
  98. +1 −1  libraries.gradle
View
2  hibernate-core/hibernate-core.gradle
@@ -84,7 +84,7 @@ task jaxb {
// input schemas
cfgXsd = file( 'src/main/resources/org/hibernate/hibernate-configuration-4.0.xsd')
hbmXsd = file( 'src/main/resources/org/hibernate/hibernate-mapping-4.0.xsd' )
- ormXsd = file( 'src/main/resources/org/hibernate/ejb/orm_2_0.xsd' )
+ ormXsd = file( 'src/main/resources/org/hibernate/jpa/orm_2_1.xsd' )
// input bindings
cfgXjb = file( 'src/main/xjb/hbm-configuration-bindings.xjb' )
View
34 hibernate-core/src/main/java/org/hibernate/InvalidMappingException.java
@@ -49,24 +49,32 @@ public InvalidMappingException(String customMessage, String type, String path) {
this.path=path;
}
- public InvalidMappingException(String customMessage, XmlDocument xmlDocument, Throwable cause) {
- this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName(), cause );
- }
-
- public InvalidMappingException(String customMessage, XmlDocument xmlDocument) {
- this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName() );
- }
+// public InvalidMappingException(String customMessage, XmlDocument xmlDocument, Throwable cause) {
+// this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName(), cause );
+// }
+//
+// public InvalidMappingException(String customMessage, XmlDocument xmlDocument) {
+// this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName() );
+// }
+//
+// public InvalidMappingException(String customMessage, Origin origin) {
+// this( customMessage, origin.getType().toString(), origin.getName() );
+// }
+//
+// public InvalidMappingException(String type, String path) {
+// this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
+// }
- public InvalidMappingException(String customMessage, Origin origin) {
- this( customMessage, origin.getType().toString(), origin.getName() );
+ public InvalidMappingException(String type, String path, Throwable cause) {
+ this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);
}
- public InvalidMappingException(String type, String path) {
- this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
+ public InvalidMappingException(String message, Origin origin, Exception cause) {
+ this( message, origin.getType().name(), origin.getName(), cause );
}
- public InvalidMappingException(String type, String path, Throwable cause) {
- this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);
+ public InvalidMappingException(String message, Origin origin) {
+ this( message, origin, null );
}
public String getType() {
View
5 hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java
@@ -155,6 +155,7 @@
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.StringHelper;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.DependantValue;
@@ -2090,12 +2091,12 @@ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
if ( naturalIdAnn != null ) {
if ( joinColumns != null ) {
for ( Ejb3Column column : joinColumns ) {
- column.addUniqueKey( "_UniqueKey", inSecondPass );
+ column.addUniqueKey( StringHelper.randomFixedLengthHex("UK_"), inSecondPass );
}
}
else {
for ( Ejb3Column column : columns ) {
- column.addUniqueKey( "_UniqueKey", inSecondPass );
+ column.addUniqueKey( StringHelper.randomFixedLengthHex("UK_"), inSecondPass );
}
}
}
View
49 hibernate-core/src/main/java/org/hibernate/cfg/Configuration.java
@@ -112,11 +112,11 @@
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.internal.util.xml.ErrorLogger;
import org.hibernate.internal.util.xml.MappingReader;
-import org.hibernate.internal.util.xml.Origin;
-import org.hibernate.internal.util.xml.OriginImpl;
import org.hibernate.internal.util.xml.XMLHelper;
import org.hibernate.internal.util.xml.XmlDocument;
import org.hibernate.internal.util.xml.XmlDocumentImpl;
+import org.hibernate.jaxb.spi.Origin;
+import org.hibernate.jaxb.spi.SourceType;
import org.hibernate.mapping.AuxiliaryDatabaseObject;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
@@ -473,12 +473,12 @@ public Configuration addFile(final File xmlFile) throws MappingException {
catch ( FileNotFoundException e ) {
throw new MappingNotFoundException( "file", xmlFile.toString() );
}
- add( inputSource, "file", name );
+ add( inputSource, SourceType.FILE, name );
return this;
}
- private XmlDocument add(InputSource inputSource, String originType, String originName) {
- return add( inputSource, new OriginImpl( originType, originName ) );
+ private XmlDocument add(InputSource inputSource, SourceType originType, String originName) {
+ return add( inputSource, new Origin( originType, originName ) );
}
private XmlDocument add(InputSource inputSource, Origin origin) {
@@ -549,7 +549,7 @@ public Configuration addCacheableFile(File xmlFile) throws MappingException {
}
LOG.readingMappingsFromFile( xmlFile.getPath() );
- XmlDocument metadataXml = add( inputSource, "file", name );
+ XmlDocument metadataXml = add( inputSource, SourceType.FILE, name );
try {
LOG.debugf( "Writing cache file for: %s to: %s", xmlFile, cachedFile );
@@ -592,7 +592,7 @@ public Configuration addCacheableFileStrictly(File xmlFile) throws Serialization
LOG.readingCachedMappings( cachedFile );
Document document = ( Document ) SerializationHelper.deserialize( new FileInputStream( cachedFile ) );
- add( new XmlDocumentImpl( document, "file", xmlFile.getAbsolutePath() ) );
+ add( new XmlDocumentImpl( document, SourceType.FILE, xmlFile.getAbsolutePath() ) );
return this;
}
@@ -622,7 +622,7 @@ public Configuration addCacheableFile(String xmlFile) throws MappingException {
public Configuration addXML(String xml) throws MappingException {
LOG.debugf( "Mapping XML:\n%s", xml );
final InputSource inputSource = new InputSource( new StringReader( xml ) );
- add( inputSource, "string", "XML String" );
+ add( inputSource, SourceType.STRING, "XML String" );
return this;
}
@@ -640,7 +640,7 @@ public Configuration addURL(URL url) throws MappingException {
LOG.debugf( "Reading mapping document from URL : %s", urlExternalForm );
try {
- add( url.openStream(), "URL", urlExternalForm );
+ add( url.openStream(), SourceType.URL, urlExternalForm );
}
catch ( IOException e ) {
throw new InvalidMappingException( "Unable to open url stream [" + urlExternalForm + "]", "URL", urlExternalForm, e );
@@ -648,7 +648,7 @@ public Configuration addURL(URL url) throws MappingException {
return this;
}
- private XmlDocument add(InputStream inputStream, final String type, final String name) {
+ private XmlDocument add(InputStream inputStream, final SourceType type, final String name) {
final InputSource inputSource = new InputSource( inputStream );
try {
return add( inputSource, type, name );
@@ -675,7 +675,7 @@ public Configuration addDocument(org.w3c.dom.Document doc) throws MappingExcepti
LOG.debugf( "Mapping Document:\n%s", doc );
final Document document = xmlHelper.createDOMReader().read( doc );
- add( new XmlDocumentImpl( document, "unknown", null ) );
+ add( new XmlDocumentImpl( document, SourceType.DOM, null ) );
return this;
}
@@ -689,7 +689,7 @@ public Configuration addDocument(org.w3c.dom.Document doc) throws MappingExcepti
* processing the contained mapping document.
*/
public Configuration addInputStream(InputStream xmlInputStream) throws MappingException {
- add( xmlInputStream, "input stream", null );
+ add( xmlInputStream, SourceType.INPUT_STREAM, null );
return this;
}
@@ -708,7 +708,7 @@ public Configuration addResource(String resourceName, ClassLoader classLoader) t
if ( resourceInputStream == null ) {
throw new MappingNotFoundException( "resource", resourceName );
}
- add( resourceInputStream, "resource", resourceName );
+ add( resourceInputStream, SourceType.RESOURCE, resourceName );
return this;
}
@@ -734,7 +734,7 @@ public Configuration addResource(String resourceName) throws MappingException {
if ( resourceInputStream == null ) {
throw new MappingNotFoundException( "resource", resourceName );
}
- add( resourceInputStream, "resource", resourceName );
+ add( resourceInputStream, SourceType.RESOURCE, resourceName );
return this;
}
@@ -1186,6 +1186,21 @@ else if ( ig instanceof IdentifierGeneratorAggregator ) {
table.isQuoted()
);
+ Iterator uniqueIter = table.getUniqueKeyIterator();
+ while ( uniqueIter.hasNext() ) {
+ final UniqueKey uniqueKey = (UniqueKey) uniqueIter.next();
+ // Skip if index already exists
+ if ( tableInfo != null && StringHelper.isNotEmpty( uniqueKey.getName() ) ) {
+ final IndexMetadata meta = tableInfo.getIndexMetadata( uniqueKey.getName() );
+ if ( meta != null ) {
+ continue;
+ }
+ }
+ String constraintString = uniqueKey.sqlCreateString( dialect,
+ mapping, tableCatalog, tableSchema );
+ if (constraintString != null) script.add( constraintString );
+ }
+
if ( dialect.hasAlterTable() ) {
Iterator subIter = table.getForeignKeyIterator();
while ( subIter.hasNext() ) {
@@ -1378,11 +1393,9 @@ protected void secondPassCompile() throws MappingException {
for ( Map.Entry<Table, List<UniqueConstraintHolder>> tableListEntry : uniqueConstraintHoldersByTable.entrySet() ) {
final Table table = tableListEntry.getKey();
final List<UniqueConstraintHolder> uniqueConstraints = tableListEntry.getValue();
- int uniqueIndexPerTable = 0;
for ( UniqueConstraintHolder holder : uniqueConstraints ) {
- uniqueIndexPerTable++;
final String keyName = StringHelper.isEmpty( holder.getName() )
- ? "UK_" + table.getName() + "_" + uniqueIndexPerTable
+ ? StringHelper.randomFixedLengthHex("UK_")
: holder.getName();
buildUniqueKeyFromColumnNames( table, keyName, holder.getColumns() );
}
@@ -3537,7 +3550,7 @@ private void processHbmXml(XmlDocument metadataXml, Set<String> entityNames) {
}
catch ( MappingException me ) {
throw new InvalidMappingException(
- metadataXml.getOrigin().getType(),
+ metadataXml.getOrigin().getType().name(),
metadataXml.getOrigin().getName(),
me
);
View
70 hibernate-core/src/main/java/org/hibernate/cfg/EJB3DTDEntityResolver.java
@@ -56,37 +56,57 @@ public boolean isResolved() {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
LOG.tracev( "Resolving XML entity {0} : {1}", publicId, systemId );
- InputSource is = super.resolveEntity( publicId, systemId );
- if ( is == null ) {
- if ( systemId != null ) {
- if ( systemId.endsWith( "orm_1_0.xsd" ) ) {
- InputStream dtdStream = getStreamFromClasspath( "orm_1_0.xsd" );
- final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
- if (source != null) return source;
+ if ( systemId != null ) {
+ if ( systemId.endsWith( "orm_2_1.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "orm_2_1.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
+ if ( source != null ) {
+ return source;
}
- else if ( systemId.endsWith( "orm_2_0.xsd" ) ) {
- InputStream dtdStream = getStreamFromClasspath( "orm_2_0.xsd" );
- final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
- if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "orm_2_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "orm_2_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
+ if ( source != null ) {
+ return source;
}
- else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
- InputStream dtdStream = getStreamFromClasspath( "persistence_1_0.xsd" );
- final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
- if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "orm_1_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "orm_1_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, false );
+ if ( source != null ) {
+ return source;
}
- else if ( systemId.endsWith( "persistence_2_0.xsd" ) ) {
- InputStream dtdStream = getStreamFromClasspath( "persistence_2_0.xsd" );
- final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
- if (source != null) return source;
+ }
+ else if ( systemId.endsWith( "persistence_2_1.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "persistence_2_1.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
+ if ( source != null ) {
+ return source;
+ }
+ }
+ else if ( systemId.endsWith( "persistence_2_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "persistence_2_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
+ if ( source != null ) {
+ return source;
+ }
+ }
+ else if ( systemId.endsWith( "persistence_1_0.xsd" ) ) {
+ InputStream dtdStream = getStreamFromClasspath( "persistence_1_0.xsd" );
+ final InputSource source = buildInputSource( publicId, systemId, dtdStream, true );
+ if ( source != null ) {
+ return source;
}
}
}
- else {
+
+ // because the old code did this too (in terms of setting resolved)
+ InputSource source = super.resolveEntity( publicId, systemId );
+ if ( source != null ) {
resolved = true;
- return is;
}
- //use the default behavior
- return null;
+ return source;
}
private InputSource buildInputSource(String publicId, String systemId, InputStream dtdStream, boolean resolved) {
@@ -103,8 +123,8 @@ private InputSource buildInputSource(String publicId, String systemId, InputStre
}
private InputStream getStreamFromClasspath(String fileName) {
- LOG.trace( "Recognized JPA ORM namespace; attempting to resolve on classpath under org/hibernate/ejb" );
- String path = "org/hibernate/ejb/" + fileName;
+ LOG.trace( "Recognized JPA ORM namespace; attempting to resolve on classpath under org/hibernate/jpa" );
+ String path = "org/hibernate/jpa/" + fileName;
InputStream dtdStream = resolveInHibernateNamespace( path );
return dtdStream;
}
View
2  hibernate-core/src/main/java/org/hibernate/cfg/HbmBinder.java
@@ -2247,7 +2247,7 @@ else if ( "filter".equals( name ) ) {
}
else if ( "natural-id".equals( name ) ) {
UniqueKey uk = new UniqueKey();
- uk.setName("_UniqueKey");
+ uk.setName(StringHelper.randomFixedLengthHex("UK_"));
uk.setTable(table);
//by default, natural-ids are "immutable" (constant)
boolean mutableId = "true".equals( subnode.attributeValue("mutable") );
View
22 ...src/main/java/org/hibernate/cfg/annotations/reflection/JPAOverriddenAnnotationReader.java
@@ -65,10 +65,12 @@
import javax.persistence.ExcludeSuperclassListeners;
import javax.persistence.FetchType;
import javax.persistence.FieldResult;
+import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
+import javax.persistence.Index;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
@@ -227,6 +229,8 @@ public boolean returnTransient() {
annotationToXml.put( MapKeyJoinColumns.class, "map-key-join-column" );
annotationToXml.put( OrderColumn.class, "order-column" );
annotationToXml.put( Cacheable.class, "cacheable" );
+ annotationToXml.put( Index.class, "index" );
+ annotationToXml.put( ForeignKey.class, "foreign-key" );
}
private XMLContext xmlContext;
@@ -659,6 +663,7 @@ private JoinTable buildJoinTable(Element tree, XMLContext.Default defaults) {
annotation.setValue( "schema", defaults.getSchema() );
}
buildUniqueConstraints( annotation, subelement );
+ buildIndex( annotation, subelement );
annotation.setValue( "joinColumns", getJoinColumns( subelement, false ) );
annotation.setValue( "inverseJoinColumns", getJoinColumns( subelement, true ) );
return AnnotationFactory.create( annotation );
@@ -1069,6 +1074,7 @@ private void getCollectionTable(List<Annotation> annotationList, Element element
annotation.setValue( "joinColumns", joinColumns );
}
buildUniqueConstraints( annotation, subelement );
+ buildIndex( annotation, subelement );
annotationList.add( AnnotationFactory.create( annotation ) );
}
}
@@ -2298,6 +2304,7 @@ else if ( defaults.canUseJavaAnnotations() ) {
annotation.setValue( "schema", defaults.getSchema() );
}
buildUniqueConstraints( annotation, subelement );
+ buildIndex( annotation, subelement );
return AnnotationFactory.create( annotation );
}
}
@@ -2321,6 +2328,7 @@ private SecondaryTables getSecondaryTables(Element tree, XMLContext.Default defa
annotation.setValue( "schema", defaults.getSchema() );
}
buildUniqueConstraints( annotation, element );
+ buildIndex( annotation, element );
annotation.setValue( "pkJoinColumns", buildPrimaryKeyJoinColumns( element ) );
secondaryTables.add( (SecondaryTable) AnnotationFactory.create( annotation ) );
}
@@ -2376,7 +2384,19 @@ private void overridesDefaultInSecondaryTable(
}
}
}
-
+ private static void buildIndex(AnnotationDescriptor annotation, Element element){
+ List indexElementList = element.elements( "index" );
+ Index[] indexes = new Index[indexElementList.size()];
+ for(int i=0;i<indexElementList.size();i++){
+ Element subelement = (Element)indexElementList.get( i );
+ AnnotationDescriptor indexAnn = new AnnotationDescriptor( Index.class );
+ copyStringAttribute( indexAnn, subelement, "name", false );
+ copyStringAttribute( indexAnn, subelement, "column-list", true );
+ copyBooleanAttribute( indexAnn, subelement, "unique" );
+ indexes[i] = AnnotationFactory.create( indexAnn );
+ }
+ annotation.setValue( "indexes", indexes );
+ }
private static void buildUniqueConstraints(AnnotationDescriptor annotation, Element element) {
List uniqueConstraintElementList = element.elements( "unique-constraint" );
UniqueConstraint[] uniqueConstraints = new UniqueConstraint[uniqueConstraintElementList.size()];
View
15 hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java
@@ -29,6 +29,7 @@
import java.util.Arrays;
import java.util.Iterator;
import java.util.StringTokenizer;
+import java.util.UUID;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.collections.ArrayHelper;
@@ -763,4 +764,18 @@ public static String expandBatchIdPlaceholder(
public static String[] toArrayElement(String s) {
return ( s == null || s.length() == 0 ) ? new String[0] : new String[] { s };
}
+
+ // Oracle restricts identifier lengths to 30. Rather than tie this to
+ // Dialect, simply restrict randomly-generated constrain names across
+ // the board.
+ private static final int MAX_NAME_LENGTH = 30;
+ public static String randomFixedLengthHex(String prefix) {
+ int length = MAX_NAME_LENGTH - prefix.length();
+ String s = UUID.randomUUID().toString();
+ s = s.replace( "-", "" );
+ if (s.length() > length) {
+ s = s.substring( 0, length );
+ }
+ return prefix + s;
+ }
}
View
147 hibernate-core/src/main/java/org/hibernate/internal/util/xml/BaseXMLEventReader.java
@@ -0,0 +1,147 @@
+/*
+ * 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.internal.util.xml;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Characters;
+import javax.xml.stream.events.EntityDeclaration;
+import javax.xml.stream.events.EntityReference;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.stream.util.EventReaderDelegate;
+
+/**
+ * Base for XMLEventReader that implements the {@link #getElementText()} and {@link #nextTag()} APIs in a
+ * way that is agnostic from the rest of the XMLEventReader implementation. Both will use the subclasses
+ * {@link #internalNextEvent()} as the exclusive way to read events.
+ *
+ * Note, copied from the uPortal project by permission of author. See
+ * https://github.com/Jasig/uPortal/blob/master/uportal-war/src/main/java/org/jasig/portal/xml/stream/BaseXMLEventReader.java
+ *
+ * @author Eric Dalquist
+ */
+public abstract class BaseXMLEventReader extends EventReaderDelegate {
+ private XMLEvent previousEvent;
+
+ public BaseXMLEventReader(XMLEventReader reader) {
+ super(reader);
+ }
+
+ /**
+ * Subclass's version of {@link #nextEvent()}, called by {@link #next()}
+ */
+ protected abstract XMLEvent internalNextEvent() throws XMLStreamException;
+
+ /**
+ * @return The XMLEvent returned by the last call to {@link #internalNextEvent()}
+ */
+ protected final XMLEvent getPreviousEvent() {
+ return this.previousEvent;
+ }
+
+ @Override
+ public final XMLEvent nextEvent() throws XMLStreamException {
+ this.previousEvent = this.internalNextEvent();
+ return this.previousEvent;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.Iterator#next()
+ */
+ @Override
+ public final Object next() {
+ try {
+ return this.nextEvent();
+ }
+ catch (XMLStreamException e) {
+ return null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.stream.XMLEventReader#getElementText()
+ */
+ @Override
+ public final String getElementText() throws XMLStreamException {
+ XMLEvent event = this.previousEvent;
+ if (event == null) {
+ throw new XMLStreamException("Must be on START_ELEMENT to read next text, element was null");
+ }
+ if (!event.isStartElement()) {
+ throw new XMLStreamException("Must be on START_ELEMENT to read next text", event.getLocation());
+ }
+
+ final StringBuilder text = new StringBuilder();
+ while (!event.isEndDocument()) {
+ switch (event.getEventType()) {
+ case XMLStreamConstants.CHARACTERS:
+ case XMLStreamConstants.SPACE:
+ case XMLStreamConstants.CDATA: {
+ final Characters characters = event.asCharacters();
+ text.append(characters.getData());
+ break;
+ }
+ case XMLStreamConstants.ENTITY_REFERENCE: {
+ final EntityReference entityReference = (EntityReference)event;
+ final EntityDeclaration declaration = entityReference.getDeclaration();
+ text.append(declaration.getReplacementText());
+ break;
+ }
+ case XMLStreamConstants.COMMENT:
+ case XMLStreamConstants.PROCESSING_INSTRUCTION: {
+ //Ignore
+ break;
+ }
+ default: {
+ throw new XMLStreamException("Unexpected event type '" + XMLStreamConstantsUtils.getEventName(event.getEventType()) + "' encountered. Found event: " + event, event.getLocation());
+ }
+ }
+
+ event = this.nextEvent();
+ }
+
+ return text.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.xml.stream.XMLEventReader#nextTag()
+ */
+ @Override
+ public final XMLEvent nextTag() throws XMLStreamException {
+ XMLEvent event = this.nextEvent();
+ while ((event.isCharacters() && event.asCharacters().isWhiteSpace())
+ || event.isProcessingInstruction()
+ || event.getEventType() == XMLStreamConstants.COMMENT) {
+
+ event = this.nextEvent();
+ }
+
+ if (!event.isStartElement() && event.isEndElement()) {
+ throw new XMLStreamException("Unexpected event type '" + XMLStreamConstantsUtils.getEventName(event.getEventType()) + "' encountered. Found event: " + event, event.getLocation());
+ }
+
+ return event;
+ }
+}
View
196 hibernate-core/src/main/java/org/hibernate/internal/util/xml/BufferedXMLEventReader.java
@@ -0,0 +1,196 @@
+/*
+ * 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.internal.util.xml;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Buffers XML events for later re-reading
+ *
+ * Note, copied from the uPortal project by permission of author. See
+ * https://github.com/Jasig/uPortal/blob/master/uportal-war/src/main/java/org/jasig/portal/xml/stream/BufferedXMLEventReader.java
+ *
+ * @author Eric Dalquist
+ */
+public class BufferedXMLEventReader extends BaseXMLEventReader {
+ private final LinkedList<XMLEvent> eventBuffer = new LinkedList<XMLEvent>();
+ private int eventLimit = 0;
+ private ListIterator<XMLEvent> bufferReader = null;
+
+ /**
+ * Create new buffering reader, no buffering is done until {@link #mark(int)} is called.
+ */
+ public BufferedXMLEventReader(XMLEventReader reader) {
+ super(reader);
+ }
+
+ /**
+ * Create new buffering reader. Calls {@link #mark(int)} with the specified event limit
+ * @see #mark(int)
+ */
+ public BufferedXMLEventReader(XMLEventReader reader, int eventLimit) {
+ super(reader);
+ this.eventLimit = eventLimit;
+ }
+
+ /**
+ * @return A copy of the current buffer
+ */
+ public List<XMLEvent> getBuffer() {
+ return new ArrayList<XMLEvent>(this.eventBuffer);
+ }
+
+ /* (non-Javadoc)
+ * @see org.jasig.portal.xml.stream.BaseXMLEventReader#internalNextEvent()
+ */
+ @Override
+ protected XMLEvent internalNextEvent() throws XMLStreamException {
+ //If there is an iterator to read from reset was called, use the iterator
+ //until it runs out of events.
+ if (this.bufferReader != null) {
+ final XMLEvent event = this.bufferReader.next();
+
+ //If nothing left in the iterator, remove the reference and fall through to direct reading
+ if (!this.bufferReader.hasNext()) {
+ this.bufferReader = null;
+ }
+
+ return event;
+ }
+
+ //Get the next event from the underlying reader
+ final XMLEvent event = this.getParent().nextEvent();
+
+ //if buffering add the event
+ if (this.eventLimit != 0) {
+ this.eventBuffer.offer(event);
+
+ //If limited buffer size and buffer is too big trim the buffer.
+ if (this.eventLimit > 0 && this.eventBuffer.size() > this.eventLimit) {
+ this.eventBuffer.poll();
+ }
+ }
+
+ return event;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.bufferReader != null || super.hasNext();
+ }
+
+ @Override
+ public XMLEvent peek() throws XMLStreamException {
+ if (this.bufferReader != null) {
+ final XMLEvent event = this.bufferReader.next();
+ this.bufferReader.previous(); //move the iterator back
+ return event;
+ }
+ return super.peek();
+ }
+
+ /**
+ * Same as calling {@link #mark(int)} with -1.
+ */
+ public void mark() {
+ this.mark(-1);
+ }
+
+ /**
+ * Start buffering events
+ * @param eventLimit the maximum number of events to buffer. -1 will buffer all events, 0 will buffer no events.
+ */
+ public void mark(int eventLimit) {
+ this.eventLimit = eventLimit;
+
+ //Buffering no events now, clear the buffer and buffered reader
+ if (this.eventLimit == 0) {
+ this.eventBuffer.clear();
+ this.bufferReader = null;
+ }
+ //Buffering limited set of events, lets trim the buffer if needed
+ else if (this.eventLimit > 0) {
+ //If there is an iterator check its current position and calculate the new iterator start position
+ int iteratorIndex = 0;
+ if (this.bufferReader != null) {
+ final int nextIndex = this.bufferReader.nextIndex();
+ iteratorIndex = Math.max(0, nextIndex - (this.eventBuffer.size() - this.eventLimit));
+ }
+
+ //Trim the buffer until it is not larger than the limit
+ while (this.eventBuffer.size() > this.eventLimit) {
+ this.eventBuffer.poll();
+ }
+
+ //If there is an iterator re-create it using the newly calculated index
+ if (this.bufferReader != null) {
+ this.bufferReader = this.eventBuffer.listIterator(iteratorIndex);
+ }
+ }
+ }
+
+ /**
+ * Reset the reader to these start of the buffered events.
+ */
+ public void reset() {
+ if (this.eventBuffer.isEmpty()) {
+ this.bufferReader = null;
+ }
+ else {
+ this.bufferReader = this.eventBuffer.listIterator();
+ }
+ }
+
+ @Override
+ public void close() throws XMLStreamException {
+ this.mark(0);
+ super.close();
+ }
+
+ /**
+ * @return The number of events in the buffer.
+ */
+ public int bufferSize() {
+ return this.eventBuffer.size();
+ }
+
+ /**
+ * If reading from the buffer after a {@link #reset()} call an {@link IllegalStateException} will be thrown.
+ */
+ @Override
+ public void remove() {
+ if (this.bufferReader != null && this.bufferReader.hasNext()) {
+ throw new IllegalStateException("Cannot remove a buffered element");
+ }
+
+ super.remove();
+ }
+}
View
15 hibernate-core/src/main/java/org/hibernate/internal/util/xml/ErrorLogger.java
@@ -58,9 +58,7 @@ public ErrorLogger(String file) {
this.file = file;
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void error(SAXParseException error) {
if ( this.errors == null ) {
errors = new ArrayList<SAXParseException>();
@@ -68,23 +66,16 @@ public void error(SAXParseException error) {
errors.add( error );
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void fatalError(SAXParseException error) {
error( error );
}
- /**
- * {@inheritDoc}
- */
+ @Override
public void warning(SAXParseException warn) {
LOG.parsingXmlWarning( warn.getLineNumber(), warn.getMessage() );
}
- /**
- * @return returns a list of encountered xml parsing errors, or the empty list if there was no error
- */
public List<SAXParseException> getErrors() {
return errors;
}
View
141 hibernate-core/src/main/java/org/hibernate/internal/util/xml/FilteringXMLEventReader.java
@@ -0,0 +1,141 @@
+/*
+ * 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.internal.util.xml;
+
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+/**
+ * Base class for {@link XMLEventReader}s that want to modify or remove events from the reader stream.
+ * If a {@link StartElement} event is removed the subclass's {@link #filterEvent(XMLEvent, boolean)} will
+ * not see any events until after the matching {@link EndElement} event.
+ *
+ * Note, copied from the uPortal project by permission of author. See
+ * https://github.com/Jasig/uPortal/blob/master/uportal-war/src/main/java/org/jasig/portal/xml/stream/FilteringXMLEventReader.java
+ *
+ * @author Eric Dalquist
+ */
+public abstract class FilteringXMLEventReader extends BaseXMLEventReader {
+ private final Deque<QName> prunedElements = new LinkedList<QName>();
+ private XMLEvent peekedEvent = null;
+
+ public FilteringXMLEventReader(XMLEventReader reader) {
+ super(reader);
+ }
+
+ @Override
+ protected final XMLEvent internalNextEvent() throws XMLStreamException {
+ return this.internalNext(false);
+ }
+
+ @Override
+ public boolean hasNext() {
+ try {
+ return peekedEvent != null || (super.hasNext() && this.peek() != null);
+ }
+ catch (XMLStreamException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public final XMLEvent peek() throws XMLStreamException {
+ if (peekedEvent != null) {
+ return peekedEvent;
+ }
+
+ peekedEvent = internalNext(true);
+ return peekedEvent;
+ }
+
+ protected final XMLEvent internalNext(boolean peek) throws XMLStreamException {
+ XMLEvent event = null;
+
+ if (peekedEvent != null) {
+ event = peekedEvent;
+ peekedEvent = null;
+ return event;
+ }
+
+ do {
+ event = super.getParent().nextEvent();
+
+ //If there are pruned elements in the queue filtering events is still needed
+ if (!prunedElements.isEmpty()) {
+ //If another start element add it to the queue
+ if (event.isStartElement()) {
+ final StartElement startElement = event.asStartElement();
+ prunedElements.push(startElement.getName());
+ }
+ //If end element pop the newest name of the queue and double check that the start/end elements match up
+ else if (event.isEndElement()) {
+ final QName startElementName = prunedElements.pop();
+
+ final EndElement endElement = event.asEndElement();
+ final QName endElementName = endElement.getName();
+
+ if (!startElementName.equals(endElementName)) {
+ throw new IllegalArgumentException("Malformed XMLEvent stream. Expected end element for " + startElementName + " but found end element for " + endElementName);
+ }
+ }
+
+ event = null;
+ }
+ else {
+ final XMLEvent filteredEvent = this.filterEvent(event, peek);
+
+ //If the event is being removed and it is a start element all elements until the matching
+ //end element need to be removed as well
+ if (filteredEvent == null && event.isStartElement()) {
+ final StartElement startElement = event.asStartElement();
+ final QName name = startElement.getName();
+ prunedElements.push(name);
+ }
+
+ event = filteredEvent;
+ }
+ }
+ while (event == null);
+
+ return event;
+ }
+
+ /**
+ * @param event The current event
+ * @param peek If the event is from a {@link #peek()} call
+ * @return The event to return, if null is returned the event is dropped from the stream and the next event will be used.
+ */
+ protected abstract XMLEvent filterEvent(XMLEvent event, boolean peek);
+}
View
148 hibernate-core/src/main/java/org/hibernate/internal/util/xml/LocalXmlResourceResolver.java
@@ -0,0 +1,148 @@
+/*
+ * 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.internal.util.xml;
+
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.xml.sax.InputSource;
+
+import org.jboss.logging.Logger;
+
+import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.internal.util.ConfigHelper;
+
+/**
+ * @author Steve Ebersole
+ */
+public class LocalXmlResourceResolver implements javax.xml.stream.XMLResolver {
+ private static final CoreMessageLogger log = Logger.getMessageLogger(
+ CoreMessageLogger.class,
+ MappingReader.class.getName()
+ );
+
+ public static final LocalXmlResourceResolver INSTANCE = new LocalXmlResourceResolver();
+
+ /**
+ * Namespace for the orm.xml xsd for jpa 1.0 and 2.0
+ */
+ public static final String INITIAL_JPA_ORM_NS = "http://java.sun.com/xml/ns/persistence/orm";
+
+ /**
+ * Namespace for the orm.xml xsd for jpa 2.1
+ */
+ public static final String SECOND_JPA_ORM_NS = "http://xmlns.jcp.org/xml/ns/persistence/orm";
+
+ public static final String HIBERNATE_MAPPING_DTD_URL_BASE = "http://www.hibernate.org/dtd/";
+ public static final String LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE = "http://hibernate.sourceforge.net/";
+ public static final String CLASSPATH_EXTENSION_URL_BASE = "classpath://";
+
+ @Override
+ public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException {
+ log.tracef( "In resolveEntity(%s, %s, %s, %s)", publicID, systemID, baseURI, namespace );
+
+ if ( namespace != null ) {
+ log.debugf( "Interpreting namespace : %s", namespace );
+ if ( INITIAL_JPA_ORM_NS.equals( namespace ) ) {
+ return openUrlStream( MappingReader.SupportedOrmXsdVersion.ORM_2_0.getSchemaUrl() );
+ }
+ else if ( SECOND_JPA_ORM_NS.equals( namespace ) ) {
+ return openUrlStream( MappingReader.SupportedOrmXsdVersion.ORM_2_1.getSchemaUrl() );
+ }
+ }
+
+ if ( systemID != null ) {
+ log.debugf( "Interpreting systemID : %s", namespace );
+ InputStream stream = null;
+ if ( systemID.startsWith( HIBERNATE_MAPPING_DTD_URL_BASE ) ) {
+ log.debug( "Recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/" );
+ stream = resolveOnClassPath( systemID, HIBERNATE_MAPPING_DTD_URL_BASE );
+ }
+ else if ( systemID.startsWith( LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE ) ) {
+ log.recognizedObsoleteHibernateNamespace( LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE, HIBERNATE_MAPPING_DTD_URL_BASE );
+ log.debug( "Attempting to resolve on classpath under org/hibernate/" );
+ stream = resolveOnClassPath( systemID, LEGACY_HIBERNATE_MAPPING_DTD_URL_BASE );
+ }
+ else if ( systemID.startsWith( CLASSPATH_EXTENSION_URL_BASE ) ) {
+ log.debug( "Recognized local namespace; attempting to resolve on classpath" );
+ final String path = systemID.substring( CLASSPATH_EXTENSION_URL_BASE.length() );
+ stream = resolveInLocalNamespace( path );
+ if ( stream == null ) {
+ log.debugf( "Unable to resolve [%s] on classpath", systemID );
+ }
+ else {
+ log.debugf( "Resolved [%s] on classpath", systemID );
+ }
+ }
+
+ if ( stream != null ) {
+ return stream;
+ }
+ }
+
+ return null;
+ }
+
+ private InputStream openUrlStream(URL url) {
+ try {
+ return url.openStream();
+ }
+ catch (IOException e) {
+ throw new XmlInfrastructureException( "Could not open url stream : " + url.toExternalForm(), e );
+ }
+ }
+
+ private InputStream resolveOnClassPath(String systemID, String namespace) {
+ final String relativeResourceName = systemID.substring( namespace.length() );
+ final String path = "org/hibernate/" + relativeResourceName;
+ InputStream dtdStream = resolveInHibernateNamespace( path );
+ if ( dtdStream == null ) {
+ log.debugf( "Unable to locate [%s] on classpath", systemID );
+ if ( relativeResourceName.contains( "2.0" ) ) {
+ log.usingOldDtd();
+ }
+ return null;
+ }
+ else {
+ log.debugf( "Located [%s] in classpath", systemID );
+ return dtdStream;
+ }
+ }
+
+ private InputStream resolveInHibernateNamespace(String path) {
+ return this.getClass().getClassLoader().getResourceAsStream( path );
+ }
+
+ private InputStream resolveInLocalNamespace(String path) {
+ try {
+ return ConfigHelper.getUserResourceAsStream( path );
+ }
+ catch ( Throwable t ) {
+ return null;
+ }
+ }
+}
View
453 hibernate-core/src/main/java/org/hibernate/internal/util/xml/MappingReader.java
@@ -23,17 +23,36 @@
*/
package org.hibernate.internal.util.xml;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.StringReader;
+import java.net.URL;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
-import org.jboss.logging.Logger;
+import org.dom4j.io.STAXEventReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.jboss.logging.Logger;
+
import org.hibernate.InvalidMappingException;
import org.hibernate.internal.CoreMessageLogger;
+import org.hibernate.jaxb.spi.Origin;
/**
* Handles reading mapping documents, both {@code hbm} and {@code orm} varieties.
@@ -41,7 +60,6 @@
* @author Steve Ebersole
*/
public class MappingReader {
-
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
CoreMessageLogger.class,
MappingReader.class.getName()
@@ -59,10 +77,241 @@
private MappingReader() {
}
+ public XmlDocument readMappingDocument(InputSource source, Origin origin) {
+ XMLEventReader staxReader = buildStaxEventReader( source, origin );
+ try {
+ return read( staxReader, origin );
+ }
+ finally {
+ try {
+ staxReader.close();
+ }
+ catch ( Exception ignore ) {
+ }
+ }
+ }
+
+ private XMLEventReader buildStaxEventReader(InputSource source, Origin origin) {
+ XMLEventReader reader = null;
+
+ if ( source.getByteStream() != null ) {
+ try {
+ reader = staxFactory().createXMLEventReader( source.getByteStream() );
+ }
+ catch (XMLStreamException e) {
+ throw new XmlInfrastructureException(
+ "Unable to create stax reader, origin = " + toLoggableString( origin ),
+ e
+ );
+ }
+ }
+ else if ( source.getCharacterStream() != null ) {
+ try {
+ reader = staxFactory().createXMLEventReader( source.getCharacterStream() );
+ }
+ catch (XMLStreamException e) {
+ throw new XmlInfrastructureException(
+ "Unable to create stax reader, origin = " + toLoggableString( origin ),
+ e
+ );
+ }
+ }
+ // todo : try to interpret the InputSource SystemId or Origin path?
+
+ if ( reader == null ) {
+ throw new XmlInfrastructureException( "Unable to convert SAX InputStream into StAX XMLEventReader" );
+ }
+
+ // For performance we wrap the reader in a buffered reader
+ return new BufferedXMLEventReader( reader );
+ }
+
+ 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;
+ }
+
+ private String toLoggableString(Origin origin) {
+ return "[type=" + origin.getType() + ", name=" + origin.getName() + "]";
+ }
+
+ private static final QName ORM_VERSION_ATTRIBUTE_QNAME = new QName( "version" );
+
+ private XmlDocument read(XMLEventReader staxEventReader, Origin origin) {
+ XMLEvent event;
+ try {
+ event = staxEventReader.peek();
+ while ( event != null && !event.isStartElement() ) {
+ staxEventReader.nextEvent();
+ event = staxEventReader.peek();
+ }
+ }
+ catch ( Exception e ) {
+ throw new InvalidMappingException( "Error accessing stax stream", origin, e );
+ }
+
+ if ( event == null ) {
+ throw new InvalidMappingException( "Could not locate root element", origin );
+ }
+
+ final String rootElementName = event.asStartElement().getName().getLocalPart();
+
+ if ( "entity-mappings".equals( rootElementName ) ) {
+ final Attribute attribute = event.asStartElement().getAttributeByName( ORM_VERSION_ATTRIBUTE_QNAME );
+ final String explicitVersion = attribute == null ? null : attribute.getValue();
+ validateMapping(
+ SupportedOrmXsdVersion.parse( explicitVersion, origin ),
+ staxEventReader,
+ origin
+ );
+ }
+
+ return new XmlDocumentImpl( toDom4jDocument( staxEventReader, origin ), origin );
+ }
+
+ private Document toDom4jDocument(XMLEventReader staxEventReader, Origin origin) {
+ STAXEventReader dom4jStaxEventReader = new STAXEventReader();
+ try {
+ // the dom4j converter class is touchy about comments (aka, comments make it implode)
+ // so wrap the event stream in a filtering stream to filter out comment events
+ staxEventReader = new FilteringXMLEventReader( staxEventReader ) {
+ @Override
+ protected XMLEvent filterEvent(XMLEvent event, boolean peek) {
+ return event.getEventType() == XMLStreamConstants.COMMENT
+ ? null
+ : event;
+ }
+ };
+
+ return dom4jStaxEventReader.readDocument( staxEventReader );
+ }
+ catch (XMLStreamException e) {
+ throw new InvalidMappingException( "Unable to read StAX source as dom4j Document for processing", origin, e );
+ }
+ }
+
+ public static void validateMapping(SupportedOrmXsdVersion xsdVersion, XMLEventReader staxEventReader, Origin origin) {
+ final Validator validator = xsdVersion.getSchema().newValidator();
+ final StAXSource staxSource;
+ try {
+ staxSource = new StAXSource( staxEventReader );
+ }
+ catch (XMLStreamException e) {
+ throw new InvalidMappingException( "Unable to generate StAXSource from mapping", origin, e );
+ }
+
+ try {
+ validator.validate( staxSource );
+ }
+ catch (SAXException e) {
+ throw new InvalidMappingException( "SAXException performing validation", origin, e );
+ }
+ catch (IOException e) {
+ throw new InvalidMappingException( "IOException performing validation", origin, e );
+ }
+ }
+
+ public static enum SupportedOrmXsdVersion {
+ ORM_1_0( "org/hibernate/jpa/orm_1_0.xsd" ),
+ ORM_2_0( "org/hibernate/jpa/orm_2_0.xsd" ),
+ ORM_2_1( "org/hibernate/jpa/orm_2_1.xsd" ),
+ HBM_4_0( "org/hibernate/hibernate-mapping-4.0.xsd");
+
+ private final String schemaResourceName;
+
+ private SupportedOrmXsdVersion(String schemaResourceName) {
+ this.schemaResourceName = schemaResourceName;
+ }
+
+ public static SupportedOrmXsdVersion parse(String name, Origin origin) {
+ if ( "1.0".equals( name ) ) {
+ return ORM_1_0;
+ }
+ else if ( "2.0".equals( name ) ) {
+ return ORM_2_0;
+ }
+ else if ( "2.1".equals( name ) ) {
+ return ORM_2_1;
+ }
+ throw new UnsupportedOrmXsdVersionException( name, origin );
+ }
+
+ private URL schemaUrl;
+
+ public URL getSchemaUrl() {
+ if ( schemaUrl == null ) {
+ schemaUrl = resolveLocalSchemaUrl( schemaResourceName );
+ }
+ return schemaUrl;
+ }
+
+ private Schema schema;
+
+ public Schema getSchema() {
+ if ( schema == null ) {
+ schema = resolveLocalSchema( getSchemaUrl() );
+ }
+ return schema;
+ }
+ }
+
+ private static URL resolveLocalSchemaUrl(String schemaName) {
+ URL url = MappingReader.class.getClassLoader().getResource( schemaName );
+ if ( url == null ) {
+ throw new XmlInfrastructureException( "Unable to locate schema [" + schemaName + "] via classpath" );
+ }
+ return url;
+ }
+
+ private static Schema resolveLocalSchema(URL schemaUrl) {
+
+ try {
+ InputStream schemaStream = schemaUrl.openStream();
+ try {
+ StreamSource source = new StreamSource(schemaUrl.openStream());
+ SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
+ return schemaFactory.newSchema(source);
+ }
+ catch ( Exception e ) {
+ throw new XmlInfrastructureException( "Unable to load schema [" + schemaUrl.toExternalForm() + "]", e );
+ }
+ finally {
+ try {
+ schemaStream.close();
+ }
+ catch ( IOException e ) {
+ LOG.debugf( "Problem closing schema stream - %s", e.toString() );
+ }
+ }
+ }
+ catch ( IOException e ) {
+ throw new XmlInfrastructureException( "Stream error handling schema url [" + schemaUrl.toExternalForm() + "]" );
+ }
+
+ }
+
+
public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
+ return legacyReadMappingDocument( entityResolver, source, origin );
+// return readMappingDocument( source, origin );
+ }
+
+ private XmlDocument legacyReadMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
// IMPL NOTE : this is the legacy logic as pulled from the old AnnotationConfiguration code
Exception failure;
+
ErrorLogger errorHandler = new ErrorLogger();
SAXReader saxReader = new SAXReader();
@@ -73,193 +322,81 @@ public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSourc
Document document = null;
try {
- // first try with orm 2.0 xsd validation
- setValidationFor( saxReader, "orm_2_0.xsd" );
+ // first try with orm 2.1 xsd validation
+ setValidationFor( saxReader, "orm_2_1.xsd" );
document = saxReader.read( source );
if ( errorHandler.hasErrors() ) {
throw errorHandler.getErrors().get( 0 );
}
- return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
+ return new XmlDocumentImpl( document, origin );
}
- catch ( Exception orm2Problem ) {
+ catch ( Exception e ) {
if ( LOG.isDebugEnabled() ) {
- LOG.debugf( "Problem parsing XML using orm 2 xsd : %s", orm2Problem.getMessage() );
+ LOG.debugf( "Problem parsing XML using orm 2.1 xsd, trying 2.0 xsd : %s", e.getMessage() );
}
- failure = orm2Problem;
+ failure = e;
errorHandler.reset();
if ( document != null ) {
- // next try with orm 1.0 xsd validation
+ // next try with orm 2.0 xsd validation
try {
- setValidationFor( saxReader, "orm_1_0.xsd" );
+ setValidationFor( saxReader, "orm_2_0.xsd" );
document = saxReader.read( new StringReader( document.asXML() ) );
if ( errorHandler.hasErrors() ) {
errorHandler.logErrors();
throw errorHandler.getErrors().get( 0 );
}
- return new XmlDocumentImpl( document, origin.getType(), origin.getName() );
+ return new XmlDocumentImpl( document, origin );
}
- catch ( Exception orm1Problem ) {
+ catch ( Exception e2 ) {
if ( LOG.isDebugEnabled() ) {
- LOG.debugf( "Problem parsing XML using orm 1 xsd : %s", orm1Problem.getMessage() );
+ LOG.debugf( "Problem parsing XML using orm 2.0 xsd, trying 1.0 xsd : %s", e2.getMessage() );
+ }
+ errorHandler.reset();
+
+ if ( document != null ) {
+ // next try with orm 1.0 xsd validation
+ try {
+ setValidationFor( saxReader, "orm_1_0.xsd" );
+ document = saxReader.read( new StringReader( document.asXML() ) );
+ if ( errorHandler.hasErrors() ) {
+ errorHandler.logErrors();
+ throw errorHandler.getErrors().get( 0 );
+ }
+ return new XmlDocumentImpl( document, origin );
+ }
+ catch ( Exception e3 ) {
+ if ( LOG.isDebugEnabled() ) {
+ LOG.debugf( "Problem parsing XML using orm 1.0 xsd : %s", e3.getMessage() );
+ }
+ }
}
}
}
}
- throw new InvalidMappingException( "Unable to read XML", origin.getType(), origin.getName(), failure );
+ throw new InvalidMappingException( "Unable to read XML", origin, failure );
}
private void setValidationFor(SAXReader saxReader, String xsd) {
try {
saxReader.setFeature( "http://apache.org/xml/features/validation/schema", true );
- //saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
- //set the default schema locators
- saxReader.setProperty(
- "http://apache.org/xml/properties/schema/external-schemaLocation",
- "http://java.sun.com/xml/ns/persistence/orm " + xsd
- );
+ // saxReader.setFeature( "http://apache.org/xml/features/validation/dynamic", true );
+ if ( "orm_2_1.xsd".equals( xsd ) ) {
+ saxReader.setProperty(
+ "http://apache.org/xml/properties/schema/external-schemaLocation",
+ LocalXmlResourceResolver.SECOND_JPA_ORM_NS + " " + xsd
+ );
+ }
+ else {
+ saxReader.setProperty(
+ "http://apache.org/xml/properties/schema/external-schemaLocation",
+ LocalXmlResourceResolver.INITIAL_JPA_ORM_NS + " " + xsd
+ );
+ }
}
catch ( SAXException e ) {
saxReader.setValidation( false );
}
}
- // this is the version of the code I'd like to use, but it unfortunately works very differently between
- // JDK 1.5 ad JDK 1.6. On 1.5 the vaildation "passes" even with invalid content.
- //
- // Options:
- // 1) continue using the code above
- // 2) Document the issue on 1.5 and how to fix (specifying alternate SchemaFactory instance)
- // 3) Use a specific JAXP library (Xerces2, Saxon, Jing, MSV) and its SchemaFactory instance directly
-
-// public XmlDocument readMappingDocument(EntityResolver entityResolver, InputSource source, Origin origin) {
-// ErrorLogger errorHandler = new ErrorLogger();
-//
-// SAXReader saxReader = new SAXReader( new DOMDocumentFactory() );
-// saxReader.setEntityResolver( entityResolver );
-// saxReader.setErrorHandler( errorHandler );
-// saxReader.setMergeAdjacentText( true );
-//
-// Document documentTree = null;
-//
-// // IMPL NOTE : here we enable DTD validation in case the mapping is a HBM file. This will validate
-// // the document as it is parsed. This is needed because the DTD defines default values that have to be
-// // applied as the document is parsed, so thats something we need to account for as we (if we) transition
-// // to XSD.
-// saxReader.setValidation( true );
-// try {
-// documentTree = saxReader.read( source );
-// }
-// catch ( DocumentException e ) {
-// // we had issues reading the input, most likely malformed document or validation error against DTD
-// throw new InvalidMappingException( "Unable to read XML", origin.getType(), origin.getName(), e );
-// }
-//
-// Element rootElement = documentTree.getRootElement();
-// if ( rootElement == null ) {
-// throw new InvalidMappingException( "No root element", origin.getType(), origin.getName() );
-// }
-//
-// if ( "entity-mappings".equals( rootElement.getName() ) ) {
-// final String explicitVersion = rootElement.attributeValue( "version" );
-// final String xsdVersionString = explicitVersion == null ? ASSUMED_ORM_XSD_VERSION : explicitVersion;
-// final SupportedOrmXsdVersion xsdVersion = SupportedOrmXsdVersion.parse( xsdVersionString );
-// final Schema schema = xsdVersion == SupportedOrmXsdVersion.ORM_1_0 ? orm1Schema() : orm2Schema();
-// try {
-// schema.newValidator().validate( new DOMSource( (org.w3c.dom.Document) documentTree ) );
-// }
-// catch ( SAXException e ) {
-// throw new InvalidMappingException( "Validation problem", origin.getType(), origin.getName(), e );
-// }
-// catch ( IOException e ) {
-// throw new InvalidMappingException( "Validation problem", origin.getType(), origin.getName(), e );
-// }
-// }
-// else {
-// if ( errorHandler.getError() != null ) {
-// throw new InvalidMappingException(
-// "Error validating hibernate-mapping against DTD",
-// origin.getType(),
-// origin.getName(),
-// errorHandler.getError()
-// );
-// }
-// }
-//
-// return new XmlDocumentImpl( documentTree, origin );
-// }
-//
-// public static enum SupportedOrmXsdVersion {
-// ORM_1_0,
-// ORM_2_0;
-//
-// public static SupportedOrmXsdVersion parse(String name) {
-// if ( "1.0".equals( name ) ) {
-// return ORM_1_0;
-// }
-// else if ( "2.0".equals( name ) ) {
-// return ORM_2_0;
-// }
-// throw new IllegalArgumentException( "Unsupported orm.xml XSD version encountered [" + name + "]" );
-// }
-// }
-//
-//
-// public static final String ORM_1_SCHEMA_NAME = "org/hibernate/ejb/orm_1_0.xsd";
-// public static final String ORM_2_SCHEMA_NAME = "org/hibernate/ejb/orm_2_0.xsd";
-//
-// private static Schema orm1Schema;
-//
-// private static Schema orm1Schema() {
-// if ( orm1Schema == null ) {
-// orm1Schema = resolveLocalSchema( ORM_1_SCHEMA_NAME );
-// }
-// return orm1Schema;
-// }
-//
-// private static Schema orm2Schema;
-//
-// private static Schema orm2Schema() {
-// if ( orm2Schema == null ) {
-// orm2Schema = resolveLocalSchema( ORM_2_SCHEMA_NAME );
-// }
-// return orm2Schema;
-// }
-//
-// private static Schema resolveLocalSchema(String schemaName) {
-// return resolveLocalSchema( schemaName, XMLConstants.W3C_XML_SCHEMA_NS_URI );
-// }
-//
-// private static Schema resolveLocalSchema(String schemaName, String schemaLanguage) {
-// URL url = ConfigHelper.findAsResource( schemaName );
-// if ( url == null ) {
-// throw new MappingException( "Unable to locate schema [" + schemaName + "] via classpath" );
-// }
-// try {
-// InputStream schemaStream = url.openStream();
-// try {
-// StreamSource source = new StreamSource(url.openStream());
-// SchemaFactory schemaFactory = SchemaFactory.newInstance( schemaLanguage );
-// return schemaFactory.newSchema(source);
-// }
-// catch ( SAXException e ) {
-// throw new MappingException( "Unable to load schema [" + schemaName + "]", e );
-// }
-// catch ( IOException e ) {
-// throw new MappingException( "Unable to load schema [" + schemaName + "]", e );
-// }
-// finally {
-// try {
-// schemaStream.close();
-// }
-// catch ( IOException e ) {
-// log.warn( "Problem closing schema stream [{}]", e.toString() );
-// }
-// }
-// }
-// catch ( IOException e ) {
-// throw new MappingException( "Stream error handling schema url [" + url.toExternalForm() + "]" );
-// }
-//
-// }
}
View
43 ...core/src/main/java/org/hibernate/internal/util/xml/UnsupportedOrmXsdVersionException.java
@@ -0,0 +1,43 @@
+/*
+ * 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.internal.util.xml;
+
+import org.hibernate.HibernateException;
+import org.hibernate.jaxb.spi.Origin;
+
+/**
+ * @author Steve Ebersole
+ */
+public class UnsupportedOrmXsdVersionException extends HibernateException {
+ public UnsupportedOrmXsdVersionException(String requestedVersion, Origin origin) {
+ super(
+ String.format(
+ "Encountered unsupported orm.xml xsd version [%s] in mapping document [type=%s, name=%s]",
+ requestedVersion,
+ origin.getType(),
+ origin.getName()
+ )
+ );
+ }
+}
View
69 hibernate-core/src/main/java/org/hibernate/internal/util/xml/XMLStreamConstantsUtils.java
@@ -0,0 +1,69 @@
+/*
+ * 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.internal.util.xml;
+
+import javax.xml.stream.XMLStreamConstants;
+
+/**
+ *
+ *
+ *
+ *
+ * Note, copied from the uPortal project by permission of author. See
+ * https://github.com/Jasig/uPortal/blob/master/uportal-war/src/main/java/org/jasig/portal/xml/stream/XMLStreamConstantsUtils.java
+ *
+ * @author Eric Dalquist
+ */
+public class XMLStreamConstantsUtils {
+ /**
+ * Get the human readable event name for the numeric event id
+ */
+ public static String getEventName(int eventId) {
+ switch (eventId) {
+ case XMLStreamConstants.START_ELEMENT:
+ return "StartElementEvent";
+ case XMLStreamConstants.END_ELEMENT:
+ return "EndElementEvent";
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ return "ProcessingInstructionEvent";
+ case XMLStreamConstants.CHARACTERS:
+ return "CharacterEvent";
+ case XMLStreamConstants.COMMENT:
+ return "CommentEvent";
+ case XMLStreamConstants.START_DOCUMENT:
+ return "StartDocumentEvent";
+ case XMLStreamConstants.END_DOCUMENT:
+ return "EndDocumentEvent";
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ return "EntityReferenceEvent";
+ case XMLStreamConstants.ATTRIBUTE:
+ return "AttributeBase";
+ case XMLStreamConstants.DTD:
+ return "DTDEvent";
+ case XMLStreamConstants.CDATA:
+ return "CDATA";
+ }
+ return "UNKNOWN_EVENT_TYPE";
+ }
+}
View
2  hibernate-core/src/main/java/org/hibernate/internal/util/xml/XmlDocument.java
@@ -27,6 +27,8 @@
import org.dom4j.Document;
+import org.hibernate.jaxb.spi.Origin;
+
/**
* Describes a parsed xml document.
*
View
7 hibernate-core/src/main/java/org/hibernate/internal/util/xml/XmlDocumentImpl.java
@@ -27,6 +27,9 @@
import org.dom4j.Document;
+import org.hibernate.jaxb.spi.Origin;
+import org.hibernate.jaxb.spi.SourceType;
+
/**
* Basic implemementation of {@link XmlDocument}
*
@@ -36,8 +39,8 @@
private final Document documentTree;
private final Origin origin;
- public XmlDocumentImpl(Document documentTree, String originType, String originName) {
- this( documentTree, new OriginImpl( originType, originName ) );
+ public XmlDocumentImpl(Document documentTree, SourceType originType, String originName) {
+ this( documentTree, new Origin( originType, originName ) );
}
public XmlDocumentImpl(Document documentTree, Origin origin) {
View
30 ...bernate/internal/util/xml/OriginImpl.java → .../util/xml/XmlInfrastructureException.java
@@ -1,7 +1,7 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2010, Red Hat Inc. or third-party contributors as
+ * 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.
@@ -23,33 +23,19 @@
*/
package org.hibernate.internal.util.xml;
-import java.io.Serializable;
+import org.hibernate.HibernateException;
/**
- * Basic implementation of {@link Origin}
+ * An error using XML infrastructure (jaxp, stax, etc).
*
* @author Steve Ebersole
*/
-public class OriginImpl implements Origin, Serializable {
- private final String type;
- private final String name;
-
- public OriginImpl(String type, String name) {
- this.type = type;
- this.name = name;
- }
-
- /**
- * {@inheritDoc}
- */
- public String getType() {
- return type;
+public class XmlInfrastructureException extends HibernateException {
+ public XmlInfrastructureException(String message) {
+ super( message );
}
- /**
- * {@inheritDoc}
- */
- public String getName() {
- return name;
+ public XmlInfrastructureException(String message, Throwable root) {
+ super( message, root );
}
}
View
64 hibernate-core/src/main/java/org/hibernate/jaxb/internal/JaxbMappingProcessor.java
@@ -41,16 +41,22 @@
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
import org.jboss.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
+import org.hibernate.InvalidMappingException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
+import org.hibernate.internal.util.StringHelper;
+import org.hibernate.internal.util.xml.LocalXmlResourceResolver;
+import org.hibernate.internal.util.xml.MappingReader;
import org.hibernate.jaxb.spi.JaxbRoot;
import org.hibernate.jaxb.spi.Origin;
import org.hibernate.jaxb.spi.hbm.JaxbHibernateMapping;
@@ -68,7 +74,7 @@
public class JaxbMappingProcessor {
private static final Logger log = Logger.getLogger( JaxbMappingProcessor.class );
- public static final String ASSUMED_ORM_XSD_VERSION = "2.0";
+ public static final String ASSUMED_ORM_XSD_VERSION = "2.1";
public static final String VALIDATE_XML_SETTING = "hibernate.xml.validate";
public static final String HIBERNATE_MAPPING_URI = "http://www.hibernate.org/xsd/hibernate-mapping";
@@ -123,6 +129,7 @@ private XMLInputFactory staxFactory() {
@SuppressWarnings( { "UnnecessaryLocalVariable" })
private XMLInputFactory buildStaxFactory() {
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
+ staxFactory.setXMLResolver( LocalXmlResourceResolver.INSTANCE );
return staxFactory;
}
@@ -154,7 +161,23 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
if ( "entity-mappings".equals( elementName ) ) {
final Attribute attribute = event.asStartElement().getAttributeByName( ORM_VERSION_ATTRIBUTE_QNAME );
final String explicitVersion = attribute == null ? null : attribute.getValue();
- validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion ) : null;
+ if ( !"2.1".equals( explicitVersion ) ) {
+ if ( validateXml ) {
+ MappingReader.validateMapping(
+ MappingReader.SupportedOrmXsdVersion.parse( explicitVersion, origin ),
+ staxEventReader,
+ origin
+ );
+ }
+ staxEventReader = new LegacyJPAEventReader(
+ staxEventReader,
+ LocalXmlResourceResolver.SECOND_JPA_ORM_NS
+ );
+ validationSchema = null; //disable JAXB validation
+ }
+ else {
+ validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion, origin ) : null;
+ }
jaxbTarget = JaxbEntityMappings.class;
}
else {
@@ -163,7 +186,7 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
log.debug( "HBM mapping document did not define namespaces; wrapping in custom event reader to introduce namespace information" );
staxEventReader = new NamespaceAddingEventReader( staxEventReader, HIBERNATE_MAPPING_URI );
}
- validationSchema = validateXml ? hbmSchema() : null;
+ validationSchema = validateXml ? MappingReader.SupportedOrmXsdVersion.HBM_4_0.getSchema() : null;
jaxbTarget = JaxbHibernateMapping.class;
}
@@ -177,6 +200,7 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
target = unmarshaller.unmarshal( staxEventReader );
}
catch ( JAXBException e ) {
+ e.printStackTrace();
StringBuilder builder = new StringBuilder();
builder.append( "Unable to perform unmarshalling at line number " );
builder.append( handler.getLineNumber() );
@@ -190,6 +214,7 @@ private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin)
return new JaxbRoot( target, origin );
}
+
private boolean isNamespaced(StartElement startElement) {
return ! "".equals( startElement.getName().getNamespaceURI() );
}
@@ -206,7 +231,7 @@ public JaxbRoot unmarshal(Document document, Origin origin) {
if ( "entity-mappings".equals( rootElement.getNodeName() ) ) {
final String explicitVersion = rootElement.getAttribute( "version" );
- validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion ) : null;
+ validationSchema = validateXml ? resolveSupportedOrmXsd( explicitVersion, origin ) : null;
jaxbTarget = JaxbEntityMappings.class;
}
else {
@@ -228,20 +253,14 @@ public JaxbRoot unmarshal(Document document, Origin origin) {
return new JaxbRoot( target, origin );
}
- private Schema resolveSupportedOrmXsd(String explicitVersion) {
- final String xsdVersionString = explicitVersion == null ? ASSUMED_ORM_XSD_VERSION : explicitVersion;
- if ( "1.0".equals( xsdVersionString ) ) {
- return orm1Schema();
- }
- else if ( "2.0".equals( xsdVersionString ) ) {
- return orm2Schema();
+ private Schema resolveSupportedOrmXsd(String explicitVersion, Origin origin) {
+ if( StringHelper.isEmpty(explicitVersion)){
+ return MappingReader.SupportedOrmXsdVersion.ORM_2_1.getSchema();
}
- throw new IllegalArgumentException( "Unsupported orm.xml XSD version encountered [" + xsdVersionString + "]" );
+ return MappingReader.SupportedOrmXsdVersion.parse( explicitVersion, origin ).getSchema();
}
public static final String HBM_SCHEMA_NAME = "org/hibernate/hibernate-mapping-4.0.xsd";
- public static final String ORM_1_SCHEMA_NAME = "org/hibernate/ejb/orm_1_0.xsd";
- public static final String ORM_2_SCHEMA_NAME = "org/hibernate/ejb/orm_2_0.xsd";
private Schema hbmSchema;
@@ -252,23 +271,6 @@ private Schema hbmSchema() {
return hbmSchema;
}
- private Schema orm1Schema;
-
- private Schema orm1Schema() {
- if ( orm1Schema == null ) {
- orm1Schema = resolveLocalSchema( ORM_1_SCHEMA_NAME );
- }
- return orm1Schema;
- }
-
- private Schema orm2Schema;
-
- private Schema orm2Schema() {
- if ( orm2Schema == null ) {
- orm2Schema = resolveLocalSchema( ORM_2_SCHEMA_NAME );
- }
- return orm2Schema;
- }
private Schema resolveLocalSchema(String schemaName) {
return resolveLocalSchema( schemaName, XMLConstants.W3C_XML_SCHEMA_NS_URI );
View
89 hibernate-core/src/main/java/org/hibernate/jaxb/internal/LegacyJPAEventReader.java
@@ -0,0 +1,89 @@
+package org.hibernate.jaxb.internal;
+
+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.Namespace;
+import javax.xml.stream.events.StartElement;