cleanups in descriptor.java package

- delete a duplicate class
- fix some incorrect usage of that class
- continue using more flow typing

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-10-30 11:21:08 +01:00
parent 2924fe8875
commit 16a15ea6ac
16 changed files with 63 additions and 368 deletions

View File

@ -285,10 +285,10 @@ public class ArrayJavaType<T> extends AbstractArrayJavaType<T[], T> {
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -138,10 +138,10 @@ public class BooleanPrimitiveArrayJavaType extends AbstractArrayJavaType<boolean
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -112,18 +112,18 @@ public class ByteArrayJavaType extends AbstractClassJavaType<Byte[]> {
if ( value == null ) {
return null;
}
if (value instanceof Byte[]) {
return (Byte[]) value;
if (value instanceof Byte[] bytes) {
return bytes;
}
if (value instanceof byte[]) {
return wrapBytes( (byte[]) value );
if (value instanceof byte[] bytes) {
return wrapBytes( bytes );
}
if (value instanceof InputStream) {
return wrapBytes( DataHelper.extractBytes( (InputStream) value ) );
if (value instanceof InputStream inputStream) {
return wrapBytes( DataHelper.extractBytes( inputStream ) );
}
if ( value instanceof Blob || DataHelper.isNClob( value.getClass() ) ) {
if ( value instanceof Blob blob ) {
try {
return wrapBytes( DataHelper.extractBytes( ( (Blob) value ).getBinaryStream() ) );
return wrapBytes( DataHelper.extractBytes( blob.getBinaryStream() ) );
}
catch ( SQLException e ) {
throw new HibernateException( "Unable to access lob stream", e );

View File

@ -99,7 +99,7 @@ public class ClobJavaType extends AbstractClassJavaType<Clob> {
}
else {
// otherwise extract the bytes from the stream manually
return (X) LobStreamDataHelper.extractString( value.getCharacterStream() );
return (X) DataHelper.extractString( value.getCharacterStream() );
}
}
else if ( Clob.class.isAssignableFrom( type ) ) {

View File

@ -15,6 +15,7 @@ import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import org.hibernate.HibernateException;
import org.hibernate.Internal;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.internal.CoreMessageLogger;
@ -22,10 +23,11 @@ import org.hibernate.internal.CoreMessageLogger;
import org.jboss.logging.Logger;
/**
* A help for dealing with BLOB and CLOB data
* A helper for dealing with {@code BLOB} and {@code CLOB} data
*
* @author Steve Ebersole
*/
@Internal
public final class DataHelper {
private DataHelper() {
}
@ -35,10 +37,6 @@ public final class DataHelper {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, DataHelper.class.getName() );
public static boolean isNClob(final Class type) {
return java.sql.NClob.class.isAssignableFrom( type );
}
/**
* Extract the contents of the given reader/stream as a string.
* The reader will be closed.
@ -65,7 +63,7 @@ public final class DataHelper {
final int bufferSize = getSuggestedBufferSize( lengthHint );
final StringBuilder stringBuilder = new StringBuilder( bufferSize );
try {
char[] buffer = new char[bufferSize];
final char[] buffer = new char[bufferSize];
while (true) {
int amountRead = reader.read( buffer, 0, bufferSize );
if ( amountRead == -1 ) {
@ -101,17 +99,17 @@ public final class DataHelper {
if ( length == 0 ) {
return "";
}
StringBuilder stringBuilder = new StringBuilder( length );
final StringBuilder stringBuilder = new StringBuilder( length );
try {
long skipped = characterStream.skip( start );
final long skipped = characterStream.skip( start );
if ( skipped != start ) {
throw new HibernateException( "Unable to skip needed bytes" );
}
final int bufferSize = getSuggestedBufferSize( length );
char[] buffer = new char[bufferSize];
final char[] buffer = new char[bufferSize];
int charsRead = 0;
while ( true ) {
int amountRead = characterStream.read( buffer, 0, bufferSize );
final int amountRead = characterStream.read( buffer, 0, bufferSize );
if ( amountRead == -1 ) {
break;
}
@ -153,16 +151,16 @@ public final class DataHelper {
* @return The contents as a {@code byte[]}
*/
public static byte[] extractBytes(InputStream inputStream) {
if ( inputStream instanceof BinaryStream ) {
return ( (BinaryStream ) inputStream ).getBytes();
if ( inputStream instanceof BinaryStream binaryStream ) {
return binaryStream.getBytes();
}
// read the stream contents into a buffer and return the complete byte[]
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
try {
byte[] buffer = new byte[BUFFER_SIZE];
final byte[] buffer = new byte[BUFFER_SIZE];
while (true) {
int amountRead = inputStream.read( buffer );
final int amountRead = inputStream.read( buffer );
if ( amountRead == -1 ) {
break;
}
@ -199,24 +197,25 @@ public final class DataHelper {
* @return The extracted bytes
*/
public static byte[] extractBytes(InputStream inputStream, long start, int length) {
if ( inputStream instanceof BinaryStream && Integer.MAX_VALUE > start ) {
byte[] data = ( (BinaryStream ) inputStream ).getBytes();
int size = Math.min( length, data.length );
byte[] result = new byte[size];
if ( inputStream instanceof BinaryStream binaryStream
&& Integer.MAX_VALUE > start ) {
final byte[] data = binaryStream.getBytes();
final int size = Math.min( length, data.length );
final byte[] result = new byte[size];
System.arraycopy( data, (int) start, result, 0, size );
return result;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( length );
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream( length );
try {
long skipped = inputStream.skip( start );
final long skipped = inputStream.skip( start );
if ( skipped != start ) {
throw new HibernateException( "Unable to skip needed bytes" );
}
byte[] buffer = new byte[BUFFER_SIZE];
final byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = 0;
while ( true ) {
int amountRead = inputStream.read( buffer );
final int amountRead = inputStream.read( buffer );
if ( amountRead == -1 ) {
break;
}

View File

@ -138,10 +138,10 @@ public class DoublePrimitiveArrayJavaType extends AbstractArrayJavaType<double[]
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -138,10 +138,10 @@ public class FloatPrimitiveArrayJavaType extends AbstractArrayJavaType<float[],
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -138,10 +138,10 @@ public class IntegerPrimitiveArrayJavaType extends AbstractArrayJavaType<int[],
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -1,299 +0,0 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.type.descriptor.java;
import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.BinaryStream;
import org.hibernate.engine.jdbc.internal.BinaryStreamImpl;
import org.hibernate.internal.CoreMessageLogger;
import org.jboss.logging.Logger;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.invoke.MethodHandles;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
/**
* A help for dealing with BLOB and CLOB data
*
* @author Steve Ebersole
*/
public final class LobStreamDataHelper {
private LobStreamDataHelper() {
}
/** The size of the buffer we will use to deserialize larger streams */
private static final int BUFFER_SIZE = 1024 * 4;
private static final CoreMessageLogger LOG = Logger.getMessageLogger( MethodHandles.lookup(), CoreMessageLogger.class, LobStreamDataHelper.class.getName() );
public static boolean isNClob(final Class type) {
return java.sql.NClob.class.isAssignableFrom( type );
}
/**
* Extract the contents of the given reader/stream as a string.
* The reader will be closed.
*
* @param reader The reader for the content
*
* @return The content as string
*/
public static String extractString(Reader reader) {
return extractString( reader, BUFFER_SIZE );
}
/**
* Extract the contents of the given reader/stream as a string.
* The reader will be closed.
*
* @param reader The reader for the content
* @param lengthHint if the length is known in advance the implementation can be slightly more efficient
*
* @return The content as string
*/
public static String extractString(Reader reader, int lengthHint) {
// read the Reader contents into a buffer and return the complete string
final int bufferSize = getSuggestedBufferSize( lengthHint );
final StringBuilder stringBuilder = new StringBuilder( bufferSize );
try {
char[] buffer = new char[bufferSize];
while (true) {
int amountRead = reader.read( buffer, 0, bufferSize );
if ( amountRead == -1 ) {
break;
}
stringBuilder.append( buffer, 0, amountRead );
}
}
catch ( IOException ioe ) {
throw new HibernateException( "IOException occurred reading text", ioe );
}
finally {
try {
reader.close();
}
catch (IOException e) {
LOG.unableToCloseStream( e );
}
}
return stringBuilder.toString();
}
/**
* Extracts a portion of the contents of the given reader/stream as a string.
*
* @param characterStream The reader for the content
* @param start The start position/offset (0-based, per general stream/reader contracts).
* @param length The amount to extract
*
* @return The content as string
*/
private static String extractString(Reader characterStream, long start, int length) {
if ( length == 0 ) {
return "";
}
StringBuilder stringBuilder = new StringBuilder( length );
try {
long skipped = characterStream.skip( start );
if ( skipped != start ) {
throw new HibernateException( "Unable to skip needed bytes" );
}
final int bufferSize = getSuggestedBufferSize( length );
char[] buffer = new char[bufferSize];
int charsRead = 0;
while ( true ) {
int amountRead = characterStream.read( buffer, 0, bufferSize );
if ( amountRead == -1 ) {
break;
}
stringBuilder.append( buffer, 0, amountRead );
if ( amountRead < bufferSize ) {
// we have read up to the end of stream
break;
}
charsRead += amountRead;
if ( charsRead >= length ) {
break;
}
}
}
catch ( IOException ioe ) {
throw new HibernateException( "IOException occurred reading a binary value", ioe );
}
return stringBuilder.toString();
}
/**
* Extract a portion of a reader, wrapping the portion in a new reader.
*
* @param characterStream The reader for the content
* @param start The start position/offset (0-based, per general stream/reader contracts).
* @param length The amount to extract
*
* @return The content portion as a reader
*/
public static Object subStream(Reader characterStream, long start, int length) {
return new StringReader( extractString( characterStream, start, length ) );
}
/**
* Extract by bytes from the given stream.
*
* @param inputStream The stream of bytes.
*
* @return The contents as a {@code byte[]}
*/
public static byte[] extractBytes(InputStream inputStream) {
if ( inputStream instanceof BinaryStream ) {
return ( (BinaryStream) inputStream ).getBytes();
}
// read the stream contents into a buffer and return the complete byte[]
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
try {
byte[] buffer = new byte[BUFFER_SIZE];
while (true) {
int amountRead = inputStream.read( buffer );
if ( amountRead == -1 ) {
break;
}
outputStream.write( buffer, 0, amountRead );
}
}
catch ( IOException ioe ) {
throw new HibernateException( "IOException occurred reading a binary value", ioe );
}
finally {
try {
inputStream.close();
}
catch ( IOException e ) {
LOG.unableToCloseInputStream( e );
}
try {
outputStream.close();
}
catch ( IOException e ) {
LOG.unableToCloseOutputStream( e );
}
}
return outputStream.toByteArray();
}
/**
* Extract a portion of the bytes from the given stream.
*
* @param inputStream The stream of bytes.
* @param start The start position/offset (0-based, per general stream/reader contracts).
* @param length The amount to extract
*
* @return The extracted bytes
*/
public static byte[] extractBytes(InputStream inputStream, long start, int length) {
if ( inputStream instanceof BinaryStream && Integer.MAX_VALUE > start ) {
byte[] data = ( (BinaryStream) inputStream ).getBytes();
int size = Math.min( length, data.length );
byte[] result = new byte[size];
System.arraycopy( data, (int) start, result, 0, size );
return result;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( length );
try {
long skipped = inputStream.skip( start );
if ( skipped != start ) {
throw new HibernateException( "Unable to skip needed bytes" );
}
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = 0;
while ( true ) {
int amountRead = inputStream.read( buffer );
if ( amountRead == -1 ) {
break;
}
outputStream.write( buffer, 0, amountRead );
if ( amountRead < buffer.length ) {
// we have read up to the end of stream
break;
}
bytesRead += amountRead;
if ( bytesRead >= length ) {
break;
}
}
}
catch ( IOException ioe ) {
throw new HibernateException( "IOException occurred reading a binary value", ioe );
}
return outputStream.toByteArray();
}
/**
* Extract a portion of the bytes from the given stream., wrapping them in a new stream.
*
* @param inputStream The stream of bytes.
* @param start The start position/offset (0-based, per general stream/reader contracts).
* @param length The amount to extract
*
* @return The extracted bytes as a stream
*/
public static InputStream subStream(InputStream inputStream, long start, int length) {
return new BinaryStreamImpl( extractBytes( inputStream, start, length ) );
}
/**
* Extract the contents of the given Clob as a string.
*
* @param value The clob to to be extracted from
*
* @return The content as string
*/
public static String extractString(final Clob value) {
try {
final Reader characterStream = value.getCharacterStream();
final long length = determineLengthForBufferSizing( value );
return length > Integer.MAX_VALUE
? extractString( characterStream, Integer.MAX_VALUE )
: extractString( characterStream, (int) length );
}
catch ( SQLException e ) {
throw new HibernateException( "Unable to access lob stream", e );
}
}
/**
* Determine a buffer size for reading the underlying character stream.
*
* @param value The Clob value
*
* @return The appropriate buffer size ({@link Clob#length()} by default.
*
*/
private static long determineLengthForBufferSizing(Clob value) throws SQLException {
try {
return value.length();
}
catch ( SQLFeatureNotSupportedException e ) {
return BUFFER_SIZE;
}
}
/**
* Make sure we allocate a buffer sized not bigger than 2048,
* not higher than what is actually needed, and at least one.
*
* @param lengthHint the expected size of the full value
* @return the buffer size
*/
private static int getSuggestedBufferSize(final int lengthHint) {
return Math.max( 1, Math.min( lengthHint , BUFFER_SIZE ) );
}
}

View File

@ -138,10 +138,10 @@ public class LongPrimitiveArrayJavaType extends AbstractArrayJavaType<long[], Lo
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -92,9 +92,9 @@ public class NClobJavaType extends AbstractClassJavaType<NClob> {
try {
if ( CharacterStream.class.isAssignableFrom( type ) ) {
if (value instanceof NClobImplementer) {
if (value instanceof NClobImplementer clobImplementer) {
// if the incoming NClob is a wrapper, just pass along its BinaryStream
return (X) ( (NClobImplementer) value ).getUnderlyingStream();
return (X) clobImplementer.getUnderlyingStream();
}
else {
// otherwise we need to build a BinaryStream...

View File

@ -120,15 +120,15 @@ public class PrimitiveByteArrayJavaType extends AbstractClassJavaType<byte[]>
if ( value == null ) {
return null;
}
if (value instanceof byte[]) {
return (byte[]) value;
if (value instanceof byte[] bytes) {
return bytes;
}
if (value instanceof InputStream) {
return DataHelper.extractBytes( (InputStream) value );
if (value instanceof InputStream inputStream) {
return DataHelper.extractBytes( inputStream );
}
if ( value instanceof Blob || DataHelper.isNClob( value.getClass() ) ) {
if ( value instanceof Blob blob ) {
try {
return DataHelper.extractBytes( ( (Blob) value ).getBinaryStream() );
return DataHelper.extractBytes( blob.getBinaryStream() );
}
catch ( SQLException e ) {
throw new HibernateException( "Unable to access lob stream", e );

View File

@ -121,15 +121,15 @@ public class SerializableJavaType<T extends Serializable> extends AbstractClassJ
if ( value == null ) {
return null;
}
else if (value instanceof byte[]) {
return fromBytes( (byte[]) value );
else if (value instanceof byte[] bytes) {
return fromBytes( bytes );
}
else if (value instanceof InputStream) {
return fromBytes( DataHelper.extractBytes( (InputStream) value ) );
else if (value instanceof InputStream inputStream) {
return fromBytes( DataHelper.extractBytes( inputStream ) );
}
else if (value instanceof Blob) {
else if (value instanceof Blob blob) {
try {
return fromBytes( DataHelper.extractBytes( ((Blob) value).getBinaryStream() ) );
return fromBytes( DataHelper.extractBytes( blob.getBinaryStream() ) );
}
catch ( SQLException e ) {
throw new HibernateException( e );

View File

@ -138,10 +138,10 @@ public class ShortPrimitiveArrayJavaType extends AbstractArrayJavaType<short[],
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.

View File

@ -77,9 +77,6 @@ public class StringJavaType extends AbstractClassJavaType<String> {
// Since NClob extends Clob, we need to check if type is an NClob
// before checking if type is a Clob. That will ensure that
// the correct type is returned.
if ( DataHelper.isNClob( type ) ) {
return (X) options.getLobCreator().createNClob( value );
}
if ( NClob.class.isAssignableFrom( type ) ) {
return (X) options.getLobCreator().createNClob( value );
}
@ -87,12 +84,10 @@ public class StringJavaType extends AbstractClassJavaType<String> {
return (X) options.getLobCreator().createClob( value );
}
if ( Integer.class.isAssignableFrom( type ) ) {
Integer parsed = Integer.parseInt( value );
return (X) parsed;
return (X) (Integer) Integer.parseInt( value );
}
if ( Long.class.isAssignableFrom( type ) ) {
Long parsed = Long.parseLong( value );
return (X) parsed;
return (X) (Long) Long.parseLong( value );
}
throw unknownUnwrap( type );

View File

@ -379,10 +379,10 @@ public class BasicCollectionJavaType<C extends Collection<E>, E> extends Abstrac
return null;
}
if ( value instanceof java.sql.Array ) {
if ( value instanceof java.sql.Array array ) {
try {
//noinspection unchecked
value = (X) ( (java.sql.Array) value ).getArray();
value = (X) array.getArray();
}
catch ( SQLException ex ) {
// This basically shouldn't happen unless you've lost connection to the database.