-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add minimal service support for adding, removing and replacing single…
…-cell data
- Loading branch information
Showing
17 changed files
with
762 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
gemma-core/src/main/java/ubic/gemma/persistence/hibernate/ByteArrayType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package ubic.gemma.persistence.hibernate; | ||
|
||
import org.hibernate.HibernateException; | ||
import org.hibernate.engine.spi.SessionImplementor; | ||
import org.hibernate.usertype.ParameterizedType; | ||
import org.hibernate.usertype.UserType; | ||
import org.springframework.jdbc.support.lob.DefaultLobHandler; | ||
import org.springframework.jdbc.support.lob.LobHandler; | ||
import org.springframework.util.Assert; | ||
import ubic.basecode.io.ByteArrayConverter; | ||
|
||
import java.io.Serializable; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Types; | ||
import java.util.Arrays; | ||
import java.util.Properties; | ||
|
||
/** | ||
* Represents a vector of scalars stored as a byte array in a single column. | ||
* <p> | ||
* The following types are supported for the {@code arrayType} parameter: | ||
* <ul> | ||
* <li>{@code int}</li> | ||
* <li>{@code double}</li> | ||
* </ul> | ||
* Other types supported by {@link ByteArrayConverter} can be added if necessary. | ||
* @author poirigui | ||
* @see ByteArrayConverter | ||
*/ | ||
public class ByteArrayType implements UserType, ParameterizedType { | ||
|
||
private enum ByteArrayTypes { | ||
INT( int[].class ), | ||
DOUBLE( double[].class ); | ||
|
||
private final Class<?> arrayClass; | ||
|
||
ByteArrayTypes( Class<?> arrayClass ) { | ||
this.arrayClass = arrayClass; | ||
} | ||
} | ||
|
||
private final ByteArrayConverter converter = new ByteArrayConverter(); | ||
private final LobHandler lobHandler = new DefaultLobHandler(); | ||
|
||
private ByteArrayTypes arrayType; | ||
|
||
@Override | ||
public int[] sqlTypes() { | ||
return new int[] { Types.BLOB }; | ||
} | ||
|
||
@Override | ||
public Class<?> returnedClass() { | ||
return arrayType.arrayClass; | ||
} | ||
|
||
@Override | ||
public boolean equals( Object x, Object y ) throws HibernateException { | ||
switch ( arrayType ) { | ||
case INT: | ||
return Arrays.equals( ( int[] ) x, ( int[] ) y ); | ||
case DOUBLE: | ||
return Arrays.equals( ( double[] ) x, ( double[] ) y ); | ||
default: | ||
throw unsupportedArrayType( arrayType ); | ||
} | ||
} | ||
|
||
@Override | ||
public int hashCode( Object x ) throws HibernateException { | ||
switch ( arrayType ) { | ||
case INT: | ||
return Arrays.hashCode( ( int[] ) x ); | ||
case DOUBLE: | ||
return Arrays.hashCode( ( double[] ) x ); | ||
default: | ||
throw unsupportedArrayType( arrayType ); | ||
} | ||
} | ||
|
||
@Override | ||
public Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor session, Object owner ) throws HibernateException, SQLException { | ||
byte[] data = lobHandler.getBlobAsBytes( rs, 0 ); | ||
if ( data != null ) { | ||
switch ( arrayType ) { | ||
case INT: | ||
return converter.byteArrayToInts( data ); | ||
case DOUBLE: | ||
return converter.byteArrayToDoubles( data ); | ||
default: | ||
throw unsupportedArrayType( arrayType ); | ||
} | ||
} else { | ||
return null; | ||
} | ||
} | ||
|
||
@Override | ||
public void nullSafeSet( PreparedStatement st, Object value, int index, SessionImplementor session ) throws HibernateException, SQLException { | ||
byte[] blob; | ||
if ( value != null ) { | ||
switch ( arrayType ) { | ||
case INT: | ||
blob = converter.intArrayToBytes( ( int[] ) value ); | ||
break; | ||
case DOUBLE: | ||
blob = converter.doubleArrayToBytes( ( double[] ) value ); | ||
break; | ||
default: | ||
throw unsupportedArrayType( arrayType ); | ||
} | ||
} else { | ||
blob = null; | ||
} | ||
lobHandler.getLobCreator().setBlobAsBytes( st, index, blob ); | ||
} | ||
|
||
@Override | ||
public Object deepCopy( Object value ) throws HibernateException { | ||
if ( value == null ) { | ||
return null; | ||
} | ||
switch ( arrayType ) { | ||
case INT: | ||
return ( ( int[] ) value ).clone(); | ||
case DOUBLE: | ||
return ( ( double[] ) value ).clone(); | ||
default: | ||
throw unsupportedArrayType( arrayType ); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean isMutable() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public Serializable disassemble( Object value ) throws HibernateException { | ||
return ( Serializable ) deepCopy( value ); | ||
} | ||
|
||
@Override | ||
public Object assemble( Serializable cached, Object owner ) throws HibernateException { | ||
return deepCopy( cached ); | ||
} | ||
|
||
@Override | ||
public Object replace( Object original, Object target, Object owner ) throws HibernateException { | ||
return deepCopy( original ); | ||
} | ||
|
||
@Override | ||
public void setParameterValues( Properties parameters ) { | ||
Assert.isTrue( parameters != null && parameters.containsKey( "arrayType" ), | ||
"There must be an 'arrayType' parameter in the type declaration." ); | ||
arrayType = ByteArrayTypes.valueOf( parameters.getProperty( "arrayType" ).toUpperCase() ); | ||
} | ||
|
||
private HibernateException unsupportedArrayType( ByteArrayTypes type ) { | ||
return new HibernateException( String.format( "Unsupported array type: %s.", type ) ); | ||
} | ||
} |
Oops, something went wrong.