package com.ripple.client.transport.impl;

import com.ripple.client.transport.TransportEventHandler;
import com.ripple.client.transport.WebSocketTransport;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.URI;

class WS extends WebSocketClient {
    TransportEventHandler h;

    public WS(URI serverURI) {
        super(serverURI, new Draft_17());
    }

    public void muteEventHandler() {
        h = TransportEventHandler.Dummy;
    }

    public void setEventHandler(TransportEventHandler eventHandler) {
        h = eventHandler;
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        h.onConnected();
    }

    @Override
    public void onMessage(String message) {
        try {
            h.onMessage(new JSONObject(message));
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        h.onDisconnected(false);
    }

    @Override
    public void onError(Exception ex) {
        h.onError(ex);
    }
}
public class JavaWebSocketTransportImpl implements WebSocketTransport {
    TransportEventHandler handler;
    WS client = null;

    @Override
    public void setHandler(TransportEventHandler events) {
        handler = events;
        if (client != null) {
            client.setEventHandler(events);
        }
    }

    @Override
    public void sendMessage(JSONObject msg) {
        client.send(msg.toString());
    }

    @Override
    public void connect(URI uri) {
        if (handler == null) {
            throw new RuntimeException("must call setEventHandler() before connect(...)");
        }
        disconnect();
        client = new WS(uri);
        client.setEventHandler(handler);
        handler.onConnecting(1);
        client.connect();
    }

    @Override
    public void disconnect() {
        if (client != null) {
            client.muteEventHandler();
            client = null;
        }
    }
}

@@ -149,16 +149,52 @@
 nsport;%0A
+import java.lang.ref.WeakReference;%0A
 import o
@@ -444,28 +444,43 @@
 ketClient %7B%0A
+%0A
     
+WeakReference%3C
 TransportEve
@@ -488,16 +488,17 @@
 tHandler
+%3E
  h;%0A%0A   
@@ -624,38 +624,16 @@
    h
- = TransportEventHandler.Dummy
+.clear()
 ;%0A  
@@ -719,16 +719,57 @@
     h = 
+new WeakReference%3CTransportEventHandler%3E(
 eventHan
@@ -768,24 +768,25 @@
 eventHandler
+)
 ;%0A    %7D%0A%0A   
@@ -860,17 +860,107 @@
         
-h
+TransportEventHandler handler = h.get();%0A        if (handler != null) %7B%0A            handler
 .onConne
@@ -963,24 +963,34 @@
 onnected();%0A
+        %7D%0A
     %7D%0A%0A    @
@@ -1068,17 +1068,115 @@
         
-h
+TransportEventHandler handler = h.get();%0A            if (handler != null) %7B%0A                handler
 .onMessa
@@ -1200,24 +1200,38 @@
 (message));%0A
+            %7D%0A
         %7D ca
@@ -1403,17 +1403,107 @@
         
-h
+TransportEventHandler handler = h.get();%0A        if (handler != null) %7B%0A            handler
 .onDisco
@@ -1514,24 +1514,34 @@
 ted(false);%0A
+        %7D%0A
     %7D%0A%0A    @
@@ -1597,17 +1597,107 @@
         
-h
+TransportEventHandler handler = h.get();%0A        if (handler != null) %7B%0A            handler
 .onError
@@ -1702,24 +1702,34 @@
 or(ex);%0A
+        %7D%0A
     %7D%0A%7D%0A
 public c
@@ -1720,16 +1720,17 @@
     %7D%0A%7D%0A
+%0A
 public c
@@ -1793,20 +1793,35 @@
 sport %7B%0A
+%0A
     
+WeakReference%3C
 Transpor
@@ -1825,32 +1825,33 @@
 portEventHandler
+%3E
  handler;%0A    WS
@@ -1958,22 +1958,64 @@
 ndler = 
+new WeakReference%3CTransportEventHandler%3E(
 events
+)
 ;%0A      
@@ -2256,29 +2256,90 @@
 ) %7B%0A        
-if (h
+TransportEventHandler curHandler = handler.get();%0A        if (curH
 andler == nu
@@ -2497,16 +2497,17 @@
 S(uri);%0A
+%0A
         
@@ -2529,17 +2529,20 @@
 Handler(
-h
+curH
 andler);
@@ -2542,33 +2542,36 @@
 ndler);%0A        
-h
+curH
 andler.onConnect

Use WeakReference for callbacks