2019-06-02 20:59:05 +02:00
package org.hso.texturesyncclient.controller.net
import com.google.gson.*
2019-06-02 22:32:19 +02:00
import org.hso.texturesyncclient.model.Texture
2019-06-02 20:59:05 +02:00
import java.io.*
2019-06-02 22:04:01 +02:00
import java.lang.RuntimeException
2019-06-02 20:59:05 +02:00
import java.net.*
2019-06-03 15:18:42 +02:00
import java.util.*
2019-06-02 20:59:05 +02:00
@Suppress ( " MemberVisibilityCanBePrivate " )
2019-06-03 15:03:25 +02:00
class Connection ( val address : InetAddress , val port : Int = 10796 ) : Closeable {
2019-06-02 20:59:05 +02:00
var socket : Socket ? = null
var output : DataOutputStream ? = null
var input : DataInputStream ? = null
@Throws ( IOException :: class )
2019-06-03 15:03:25 +02:00
@Synchronized
2019-06-02 20:59:05 +02:00
private fun getStreams ( ) : Pair < DataInputStream , DataOutputStream > {
val i : DataInputStream
val o : DataOutputStream
if ( socket == null || ! socket !! . isConnected ) {
2019-06-03 15:03:25 +02:00
val sock = Socket ( address , port )
2019-06-02 20:59:05 +02:00
i = DataInputStream ( BufferedInputStream ( sock . getInputStream ( ) ) )
o = DataOutputStream ( BufferedOutputStream ( sock . getOutputStream ( ) ) )
input = i
output = o
socket = sock
} else {
i = input !!
o = output !!
}
return Pair ( i , o )
}
2019-06-03 15:03:25 +02:00
@Throws ( IOException :: class , ConnectionException :: class )
@Synchronized
2019-06-02 20:59:05 +02:00
fun ping ( ) {
val io = getStreams ( )
val obj = JsonObject ( )
obj . add ( " ping " , JsonObject ( ) )
2019-06-03 15:03:25 +02:00
JsonPackage ( obj ) . write ( io . second )
2019-06-02 20:59:05 +02:00
2019-06-03 15:03:25 +02:00
when ( val pkg = Package . read ( io . first ) ) {
is JsonPackage -> return
is BinaryPackage -> throw ConnectionUnexpecedPacketException ( )
is ErrorPackage -> throw ConnectionErrorException ( pkg )
2019-06-02 22:04:01 +02:00
else -> throw RuntimeException ( " Unreachable " )
}
}
2019-06-03 15:03:25 +02:00
@Throws ( IOException :: class , ConnectionException :: class )
@Synchronized
2019-06-02 22:32:19 +02:00
fun query ( query : Array < String > ) : Array < Texture > {
2019-06-02 22:04:01 +02:00
val io = getStreams ( )
val obj = JsonObject ( )
obj . add ( " query " , {
2019-06-03 15:03:25 +02:00
val inner = JsonObject ( )
2019-06-02 22:04:01 +02:00
inner . add ( " query " , {
val array = JsonArray ( )
for ( queryString in query ) {
array . add ( queryString )
}
array
} ( ) )
inner
} ( ) )
2019-06-03 15:03:25 +02:00
JsonPackage ( obj ) . write ( io . second )
2019-06-02 22:04:01 +02:00
2019-06-03 15:03:25 +02:00
when ( val pkg = Package . read ( io . first ) ) {
is JsonPackage -> {
2019-06-02 22:04:01 +02:00
try {
2019-06-02 22:32:19 +02:00
return Gson ( ) . fromJson < Array < InternalTexture > > ( pkg . content , Array < InternalTexture > :: class . java ) . map {
tex -> tex . toTexture ( )
} . toTypedArray ( )
2019-06-02 22:04:01 +02:00
} catch ( e : JsonSyntaxException ) {
2019-06-02 22:32:19 +02:00
throw ConnectionInvalidJsonException ( )
2019-06-02 22:04:01 +02:00
}
}
2019-06-03 15:03:25 +02:00
is BinaryPackage -> throw ConnectionUnexpecedPacketException ( )
is ErrorPackage -> throw ConnectionErrorException ( pkg )
2019-06-02 22:04:01 +02:00
else -> throw RuntimeException ( " Unreachable " )
2019-06-02 20:59:05 +02:00
}
}
2019-06-03 15:18:42 +02:00
@Throws ( IOException :: class , ConnectionException :: class )
@Synchronized
fun getTextureById ( id : UUID ) : Optional < Texture > {
val io = getStreams ( )
val obj = JsonObject ( )
obj . add ( " get_texture " , {
val inner = JsonObject ( )
inner . addProperty ( " id " , id . toString ( ) )
inner
} ( ) )
JsonPackage ( obj ) . write ( io . second )
when ( val pkg = Package . read ( io . first ) ) {
is JsonPackage -> {
return if ( pkg . content . isJsonNull ) {
Optional . empty ( )
} else {
try {
Optional . of (
Gson ( )
. fromJson < InternalTexture > ( pkg . content , InternalTexture :: class . java )
. toTexture ( )
)
} catch ( e : JsonSyntaxException ) {
throw ConnectionInvalidJsonException ( )
}
}
}
is BinaryPackage -> throw ConnectionUnexpecedPacketException ( )
is ErrorPackage -> throw ConnectionErrorException ( pkg )
else -> throw RuntimeException ( " Unreachable " )
}
}
@Throws ( IOException :: class , ConnectionException :: class )
@Synchronized
fun getTextureByName ( name : String ) : Optional < Texture > {
val io = getStreams ( )
val obj = JsonObject ( )
obj . add ( " get_texture " , {
val inner = JsonObject ( )
inner . addProperty ( " name " , name )
inner
} ( ) )
JsonPackage ( obj ) . write ( io . second )
when ( val pkg = Package . read ( io . first ) ) {
is JsonPackage -> {
return if ( pkg . content . isJsonNull ) {
Optional . empty ( )
} else {
try {
Optional . of (
Gson ( )
. fromJson < InternalTexture > ( pkg . content , InternalTexture :: class . java )
. toTexture ( )
)
} catch ( e : JsonSyntaxException ) {
throw ConnectionInvalidJsonException ( )
}
}
}
is BinaryPackage -> throw ConnectionUnexpecedPacketException ( )
is ErrorPackage -> throw ConnectionErrorException ( pkg )
else -> throw RuntimeException ( " Unreachable " )
}
}
2019-06-02 20:59:05 +02:00
@Throws ( IOException :: class )
2019-06-03 15:03:25 +02:00
@Synchronized
2019-06-02 20:59:05 +02:00
override fun close ( ) {
if ( output != null ) {
output !! . close ( )
}
if ( input != null ) {
input !! . close ( )
}
if ( socket != null ) {
socket !! . close ( )
}
}
}