package carbonite;

import clojure.lang.RT;
import clojure.lang.Var;
import com.esotericsoftware.kryo.Kryo;

public class JavaBridge {
    static final Var require = RT.var("clojure.core", "require");
    static final Var symbol = RT.var("clojure.core", "symbol");

    static Var defaultReg;
    static Var regSerializers;
    static Var cljPrimitives;
    static Var javaPrimitives;
    static Var cljCollections;

    static boolean registryEnhanced = false;

    public static void initialize() {
        try {
            require.invoke(symbol.invoke("carbonite.api"));
            requireCarbonite();
        } catch (Exception e) {
            e.printStackTrace();
        }

        defaultReg = RT.var("carbonite.api", "default-registry");
        regSerializers = RT.var("carbonite.api", "register-serializers");
        cljPrimitives  = RT.var("carbonite.serializer", "clojure-primitives");
        javaPrimitives = RT.var("carbonite.serializer", "java-primitives");
        cljCollections = RT.var("carbonite.serializer", "clojure-collections");
    }

    public static void registerPrimitives(Kryo registry) throws Exception {
        initialize();
        regSerializers.invoke(registry, cljPrimitives.deref());
    }

    public static void registerCollections(Kryo registry) throws Exception {
        initialize();
        regSerializers.invoke(registry, cljCollections.deref());
    }

    public static void registerJavaPrimitives(Kryo registry) throws Exception {
        initialize();
        regSerializers.invoke(registry, javaPrimitives.deref());
    }

    public static Kryo defaultRegistry() throws Exception {
        initialize();
        return (Kryo) defaultReg.invoke();
    }

    public static void requireCarbonite () {
        require.invoke(symbol.invoke("carbonite.serializer"));
    }

    public static synchronized void enhanceRegistry(Kryo registry) throws Exception {
        if(!registryEnhanced) {
            registerPrimitives(registry);
            registerJavaPrimitives(registry);
            registerCollections(registry);
            registryEnhanced = true;
        }
    }
}

@@ -409,16 +409,20 @@
 ctions;%0A
+    
 %0A    sta
@@ -433,30 +433,25 @@
 boolean 
-registryEnhanc
+initializ
 ed = fal
@@ -469,24 +469,37 @@
 blic static 
+synchronized 
 void initial
@@ -502,24 +502,55 @@
 tialize() %7B%0A
+        if(!initialized) %7B%0A    
         try 
@@ -555,32 +555,36 @@
 y %7B%0A            
+ 
+   
 require.invoke(s
@@ -623,24 +623,28 @@
             
+    
 requireCarbo
@@ -647,24 +647,28 @@
 arbonite();%0A
+    
         %7D ca
@@ -699,16 +699,20 @@
         
+    
 e.printS
@@ -736,19 +736,36 @@
     
-%7D%0A%0A
+    %7D%0A            %0A 
         
 defa
@@ -760,16 +760,19 @@
         
+   
 defaultR
@@ -817,24 +817,28 @@
 registry%22);%0A
+    
         regS
@@ -895,24 +895,28 @@
 ializers%22);%0A
+    
         cljP
@@ -990,16 +990,20 @@
         
+    
 javaPrim
@@ -1054,32 +1054,36 @@
 a-primitives%22);%0A
+    
         cljColle
@@ -1141,24 +1141,67 @@
 llections%22);
+%0A%0A            initialized = true;%0A        %7D
 %0A    %7D%0A%0A    
@@ -1206,32 +1206,45 @@
   public static 
+synchronized 
 void registerPri
@@ -1388,32 +1388,45 @@
   public static 
+synchronized 
 void registerCol
@@ -1576,24 +1576,37 @@
 blic static 
+synchronized 
 void registe
@@ -1767,16 +1767,29 @@
  static 
+synchronized 
 Kryo def
@@ -1912,16 +1912,29 @@
  static 
+synchronized 
 void req
@@ -2112,44 +2112,8 @@
 n %7B%0A
-        if(!registryEnhanced) %7B%0A    
     
@@ -2138,36 +2138,32 @@
 ives(registry);%0A
-    
         register
@@ -2192,28 +2192,24 @@
 y);%0A        
- 
-   
 registerColl
@@ -2231,55 +2231,8 @@
 y);%0A
-            registryEnhanced = true;%0A        %7D%0A
     

synchronize all methods and protect initialize from being called more that once.