Skip to content

Commit 15b9357

Browse files
committed
HHH-18455 - Change Binder.bind(InputStream, Origin) method signature to bind(InputStreamAccess, Origin) to allow repeatable access to the InputStream, needed for strict Jpa XML validation
Signed-off-by: Jan Schatteman <[email protected]>
1 parent ee6fd38 commit 15b9357

File tree

13 files changed

+81
-19
lines changed

13 files changed

+81
-19
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.boot.archive.internal;
6+
7+
8+
import org.hibernate.HibernateException;
9+
import org.hibernate.boot.archive.spi.InputStreamAccess;
10+
11+
import java.io.ByteArrayInputStream;
12+
import java.io.IOException;
13+
import java.io.InputStream;
14+
15+
/**
16+
* @author Jan Schatteman
17+
*/
18+
public class RepeatableInputStreamAccess implements InputStreamAccess {
19+
20+
private final String resourceName;
21+
private byte[] bytes = new byte[0];
22+
23+
public RepeatableInputStreamAccess(String resourceName, InputStream inputStream) {
24+
this.resourceName = resourceName;
25+
try {
26+
bytes = inputStream.readAllBytes();
27+
}
28+
catch (IOException | OutOfMemoryError e) {
29+
throw new HibernateException( "Could not read resource " + resourceName, e );
30+
}
31+
}
32+
33+
@Override
34+
public String getStreamName() {
35+
return resourceName;
36+
}
37+
38+
@Override
39+
public InputStream accessInputStream() {
40+
return new ByteArrayInputStream( bytes );
41+
}
42+
43+
}

hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/AbstractBinder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import org.hibernate.boot.MappingException;
1717
import org.hibernate.boot.ResourceStreamLocator;
18+
import org.hibernate.boot.archive.spi.InputStreamAccess;
1819
import org.hibernate.boot.jaxb.Origin;
1920
import org.hibernate.boot.jaxb.internal.stax.BufferedXMLEventReader;
2021
import org.hibernate.boot.jaxb.internal.stax.LocalXmlResourceResolver;
@@ -43,8 +44,8 @@ protected AbstractBinder(ResourceStreamLocator resourceStreamLocator) {
4344
public abstract boolean isValidationEnabled();
4445

4546
@Override
46-
public <X extends T> Binding<X> bind(InputStream stream, Origin origin) {
47-
final XMLEventReader eventReader = createReader( stream, origin );
47+
public <X extends T> Binding<X> bind(InputStreamAccess stream, Origin origin) {
48+
final XMLEventReader eventReader = createReader( stream.accessInputStream(), origin );
4849
try {
4950
return doBind( eventReader, origin );
5051
}

hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/InputStreamAccessXmlSource.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ public Binding doBind(Binder binder) {
2727
}
2828

2929
public static Binding doBind(Binder binder, InputStreamAccess inputStreamAccess, Origin origin) {
30-
return inputStreamAccess.fromStream(
31-
inputStream -> binder.bind( inputStream, origin )
32-
);
30+
return binder.bind( inputStreamAccess, origin ) ;
3331
}
3432
}

hibernate-core/src/main/java/org/hibernate/boot/jaxb/internal/InputStreamXmlSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.io.InputStream;
99

1010
import org.hibernate.boot.InvalidMappingException;
11+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
1112
import org.hibernate.boot.jaxb.Origin;
1213
import org.hibernate.boot.jaxb.spi.Binder;
1314
import org.hibernate.boot.jaxb.spi.Binding;
@@ -38,7 +39,7 @@ public Binding doBind(Binder binder) {
3839

3940
public static Binding doBind(Binder binder, InputStream inputStream, Origin origin, boolean autoClose) {
4041
try {
41-
return binder.bind( inputStream, origin );
42+
return binder.bind( new RepeatableInputStreamAccess( origin.getName(), inputStream), origin );
4243
}
4344
catch ( Exception e ) {
4445
throw new InvalidMappingException( origin, e );

hibernate-core/src/main/java/org/hibernate/boot/jaxb/spi/Binder.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
*/
55
package org.hibernate.boot.jaxb.spi;
66

7-
import java.io.InputStream;
87
import javax.xml.transform.Source;
98

9+
import org.hibernate.boot.archive.spi.InputStreamAccess;
1010
import org.hibernate.boot.jaxb.Origin;
1111

1212
/**
@@ -31,5 +31,14 @@ public interface Binder<T> {
3131
* @param origin The descriptor of the stream origin
3232
* @return The bound JAXB model
3333
*/
34-
<X extends T> Binding<X> bind(InputStream stream, Origin origin);
34+
// <X extends T> Binding<X> bind(InputStream stream, Origin origin);
35+
36+
/**
37+
* Bind from an InputStreamAccess
38+
*
39+
* @param streamAccess The {@link InputStreamAccess} providing access to the stream containing XML
40+
* @param origin The descriptor of the stream origin
41+
* @return The bound JAXB model
42+
*/
43+
<X extends T> Binding<X> bind(InputStreamAccess streamAccess, Origin origin);
3544
}

hibernate-core/src/main/java/org/hibernate/boot/model/process/spi/MetadataBuildingProcess.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.hibernate.Internal;
2525
import org.hibernate.boot.MetadataSources;
26+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
2627
import org.hibernate.boot.internal.InFlightMetadataCollectorImpl;
2728
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
2829
import org.hibernate.boot.internal.RootMappingDefaults;
@@ -571,7 +572,7 @@ public void contributeManagedClass(ClassDetails classDetails) {
571572
@Override
572573
public void contributeBinding(InputStream xmlStream) {
573574
final Origin origin = new Origin( SourceType.INPUT_STREAM, null );
574-
final Binding<JaxbBindableMappingDescriptor> binding = mappingBinder.bind( xmlStream, origin );
575+
final Binding<JaxbBindableMappingDescriptor> binding = mappingBinder.bind( new RepeatableInputStreamAccess( SourceType.INPUT_STREAM.toString(), xmlStream ), origin );
575576

576577
final JaxbBindableMappingDescriptor bindingRoot = binding.getRoot();
577578
if ( bindingRoot instanceof JaxbHbmHibernateMapping ) {

hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AdditionalManagedResourcesImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111
import java.util.Map;
1212

13+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
1314
import org.hibernate.boot.jaxb.Origin;
1415
import org.hibernate.boot.jaxb.SourceType;
1516
import org.hibernate.boot.jaxb.internal.MappingBinder;
@@ -144,7 +145,7 @@ public Builder addXmlMappings(String resourceName) {
144145

145146
public Builder addXmlMappings(String resourceName, Origin origin) {
146147
return addXmlBinding( mappingBinder.bind(
147-
Builder.class.getClassLoader().getResourceAsStream( resourceName ),
148+
new RepeatableInputStreamAccess( resourceName, Builder.class.getClassLoader().getResourceAsStream( resourceName )),
148149
origin
149150
) );
150151
}

hibernate-core/src/test/java/org/hibernate/orm/test/boot/jaxb/mapping/PartialJaxbTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
package org.hibernate.orm.test.boot.jaxb.mapping;
66

7+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
78
import org.hibernate.boot.jaxb.Origin;
89
import org.hibernate.boot.jaxb.SourceType;
910
import org.hibernate.boot.jaxb.internal.MappingBinder;
@@ -27,10 +28,11 @@ public class PartialJaxbTests {
2728
public void cachingTest(ServiceRegistryScope scope) {
2829
final MappingBinder mappingBinder = new MappingBinder( scope.getRegistry() );
2930
scope.withService( ClassLoaderService.class, (cls) -> {
31+
final String resourceLocation = "xml/jaxb/mapping/partial/caching.xml";
3032
//noinspection unchecked
3133
final Binding<JaxbEntityMappingsImpl> binding = mappingBinder.bind(
32-
cls.locateResourceStream( "xml/jaxb/mapping/partial/caching.xml" ),
33-
new Origin( SourceType.RESOURCE, "xml/jaxb/mapping/partial/caching.xml" )
34+
new RepeatableInputStreamAccess( resourceLocation, cls.locateResourceStream( resourceLocation )),
35+
new Origin( SourceType.RESOURCE, resourceLocation )
3436
);
3537

3638
final JaxbEntityMappingsImpl entityMappings = binding.getRoot();

hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/XmlHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.net.URL;
1010

1111
import org.hibernate.boot.ResourceStreamLocator;
12+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
1213
import org.hibernate.boot.jaxb.Origin;
1314
import org.hibernate.boot.jaxb.SourceType;
1415
import org.hibernate.boot.jaxb.internal.MappingBinder;
@@ -28,7 +29,7 @@ public static JaxbEntityMappingsImpl loadMapping(String resourceName, ClassLoadi
2829
final ResourceStreamLocatorImpl resourceStreamLocator = new ResourceStreamLocatorImpl( classLoadingAccess );
2930
final MappingBinder mappingBinder = new MappingBinder( resourceStreamLocator, NON_VALIDATING );
3031
final Binding<JaxbBindableMappingDescriptor> binding = mappingBinder.bind(
31-
resourceStreamLocator.locateResourceStream( resourceName ),
32+
new RepeatableInputStreamAccess( resourceName, resourceStreamLocator.locateResourceStream( resourceName )),
3233
new Origin( SourceType.RESOURCE, resourceName )
3334
);
3435
return (JaxbEntityMappingsImpl) binding.getRoot();

hibernate-core/src/test/java/org/hibernate/orm/test/internal/util/xml/XMLMappingHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.io.IOException;
88
import java.io.InputStream;
99

10+
import org.hibernate.boot.archive.internal.RepeatableInputStreamAccess;
1011
import org.hibernate.boot.jaxb.Origin;
1112
import org.hibernate.boot.jaxb.SourceType;
1213
import org.hibernate.boot.jaxb.internal.MappingBinder;
@@ -35,7 +36,7 @@ public JaxbEntityMappingsImpl readOrmXmlMappings(String name) throws IOException
3536
public JaxbEntityMappingsImpl readOrmXmlMappings(InputStream is, String name) {
3637
try {
3738
Assert.assertNotNull( "Resource not found: " + name, is );
38-
Binding<?> binding = binder.bind( is, new Origin( SourceType.JAR, name ) );
39+
Binding<?> binding = binder.bind( new RepeatableInputStreamAccess( name, is), new Origin( SourceType.JAR, name ) );
3940
return (JaxbEntityMappingsImpl) binding.getRoot();
4041
}
4142
catch (RuntimeException e) {

0 commit comments

Comments
 (0)