@ -17,21 +17,20 @@ package org.redisson.liveobject.misc;
import java.lang.reflect.Method ;
import java.util.Arrays ;
import java.util.BitSet ;
import java.util.HashMap ;
import java.util.List ;
import org.redisson.RedissonReference ;
import org.redisson.client.codec.Codec ;
import org.redisson.api.RBitSet ;
import org.redisson.api.RLiveObject ;
import org.redisson.api.RLiveObjectService ;
import org.redisson.api.RObject ;
import org.redisson.api.RObjectReactive ;
import org.redisson.api.RedissonClient ;
import org.redisson.api.RedissonReactiveClient ;
import org.redisson.api.annotation.REntity ;
import org.redisson.api.annotation.RId ;
import org.redisson.codec.CodecProvider ;
import org.redisson.liveobject.provider.ResolverProvider ;
import org.redisson.liveobject.resolver.NamingScheme ;
/ * *
@ -41,6 +40,7 @@ import org.redisson.liveobject.resolver.NamingScheme;
public class RedissonObjectFactory {
private static final HashMap < Class , HashMap < Boolean , Method > > builders = new HashMap < Class , HashMap < Boolean , Method > > ( ) ;
private static final HashMap < Class , HashMap < Boolean , Method > > reactiveBuilders = new HashMap < Class , HashMap < Boolean , Method > > ( ) ;
static {
for ( Method method : RedissonClient . class . getDeclaredMethods ( ) ) {
@ -52,7 +52,25 @@ public class RedissonObjectFactory {
builders . put ( cls , new HashMap < Boolean , Method > ( ) ) ;
}
HashMap < Boolean , Method > builder = builders . get ( cls ) ;
if ( method . getParameterTypes ( ) . length = = 2
if ( method . getParameterTypes ( ) . length = = 2 //first param is name, second param is codec.
& & Codec . class . isAssignableFrom ( method . getParameterTypes ( ) [ 1 ] ) ) {
builder . put ( Boolean . FALSE , method ) ;
} else if ( method . getParameterTypes ( ) . length = = 1 ) {
builder . put ( Boolean . TRUE , method ) ;
}
}
}
for ( Method method : RedissonReactiveClient . class . getDeclaredMethods ( ) ) {
if ( ! method . getReturnType ( ) . equals ( Void . TYPE )
& & RObjectReactive . class . isAssignableFrom ( method . getReturnType ( ) )
& & method . getName ( ) . startsWith ( "get" ) ) {
Class < ? > cls = method . getReturnType ( ) ;
if ( ! reactiveBuilders . containsKey ( cls ) ) {
reactiveBuilders . put ( cls , new HashMap < Boolean , Method > ( ) ) ;
}
HashMap < Boolean , Method > builder = reactiveBuilders . get ( cls ) ;
if ( method . getParameterTypes ( ) . length = = 2 //first param is name, second param is codec.
& & Codec . class . isAssignableFrom ( method . getParameterTypes ( ) [ 1 ] ) ) {
builder . put ( Boolean . FALSE , method ) ;
} else if ( method . getParameterTypes ( ) . length = = 1 ) {
@ -90,6 +108,30 @@ public class RedissonObjectFactory {
}
throw new ClassNotFoundException ( "No RObject is found to match class type of " + rr . getTypeName ( ) + " with codec type of " + rr . getCodecName ( ) ) ;
}
public static < T > T fromReference ( RedissonReactiveClient redisson , RedissonReference rr ) throws Exception {
return fromReference ( redisson , rr , null ) ;
}
public static < T > T fromReference ( RedissonReactiveClient redisson , RedissonReference rr , Class < ? > expected ) throws Exception {
Class < ? extends Object > type = rr . getReactiveType ( ) ;
CodecProvider codecProvider = redisson . getConfig ( ) . getCodecProvider ( ) ;
/ * *
* Live Object from reference in reactive client is not supported yet .
* /
if ( type ! = null ) {
List < Class < ? > > interfaces = Arrays . asList ( type . getInterfaces ( ) ) ;
for ( Class < ? > iType : interfaces ) {
if ( reactiveBuilders . containsKey ( iType ) ) { // user cache to speed up things a little.
Method builder = reactiveBuilders . get ( iType ) . get ( rr . isDefaultCodec ( ) ) ;
return ( T ) ( rr . isDefaultCodec ( )
? builder . invoke ( redisson , rr . getKeyName ( ) )
: builder . invoke ( redisson , rr . getKeyName ( ) , codecProvider . getCodec ( rr . getCodecType ( ) ) ) ) ;
}
}
}
throw new ClassNotFoundException ( "No RObjectReactive is found to match class type of " + rr . getReactiveTypeName ( ) + " with codec type of " + rr . getCodecName ( ) ) ;
}
public static RedissonReference toReference ( RedissonClient redisson , Object object ) {
if ( object instanceof RObject ) {
@ -117,20 +159,40 @@ public class RedissonObjectFactory {
return null ;
}
public static RedissonReference toReference ( RedissonReactiveClient redissonReactive , Object object ) {
if ( object instanceof RObjectReactive ) {
RObjectReactive rObject = ( ( RObjectReactive ) object ) ;
redissonReactive . getCodecProvider ( ) . registerCodec ( ( Class ) rObject . getCodec ( ) . getClass ( ) , ( Class ) rObject . getClass ( ) , rObject . getName ( ) , rObject . getCodec ( ) ) ;
return new RedissonReference ( object . getClass ( ) , ( ( RObjectReactive ) object ) . getName ( ) , ( ( RObjectReactive ) object ) . getCodec ( ) ) ;
}
try {
if ( object instanceof RLiveObject ) {
Class < ? extends Object > rEntity = object . getClass ( ) . getSuperclass ( ) ;
REntity anno = rEntity . getAnnotation ( REntity . class ) ;
NamingScheme ns = anno . namingScheme ( )
. getDeclaredConstructor ( Codec . class )
. newInstance ( redissonReactive . getCodecProvider ( ) . getCodec ( anno , ( Class ) rEntity ) ) ;
String name = Introspectior
. getFieldsWithAnnotation ( rEntity , RId . class )
. getOnly ( ) . getName ( ) ;
Class < ? > type = rEntity . getDeclaredField ( name ) . getType ( ) ;
return new RedissonReference ( rEntity ,
ns . getName ( rEntity , type , name , ( ( RLiveObject ) object ) . getLiveObjectId ( ) ) ) ;
}
} catch ( Exception e ) {
throw new IllegalArgumentException ( e ) ;
}
return null ;
}
public static < T extends RObject , K extends Codec > T createRObject ( RedissonClient redisson , Class < T > expectedType , String name , K codec ) throws Exception {
List < Class < ? > > interfaces = Arrays . asList ( expectedType . getInterfaces ( ) ) ;
for ( Method method : RedissonClient . class . getDeclaredMethods ( ) ) {
if ( method . getName ( ) . startsWith ( "get" )
& & method . getReturnType ( ) . isAssignableFrom ( expectedType )
& & interfaces . contains ( method . getReturnType ( ) ) ) {
if ( ( codec = = null | | RBitSet . class . isAssignableFrom ( method . getReturnType ( ) ) ) & & method . getParameterTypes ( ) . length = = 1 ) {
return ( T ) method . invoke ( redisson , name ) ;
} else if ( codec ! = null
& & method . getParameterTypes ( ) . length = = 2
& & String . class . equals ( method . getParameterTypes ( ) [ 0 ] )
& & Codec . class . equals ( method . getParameterTypes ( ) [ 1 ] ) ) {
return ( T ) method . invoke ( redisson , name , codec ) ;
}
for ( Class < ? > iType : interfaces ) {
if ( builders . containsKey ( iType ) ) { // user cache to speed up things a little.
Method builder = builders . get ( iType ) . get ( codec ! = null ) ;
return ( T ) ( codec ! = null
? builder . invoke ( redisson , name )
: builder . invoke ( redisson , name , codec ) ) ;
}
}
throw new ClassNotFoundException ( "No RObject is found to match class type of " + ( expectedType ! = null ? expectedType . getName ( ) : "null" ) + " with codec type of " + ( codec ! = null ? codec . getClass ( ) . getName ( ) : "null" ) ) ;