package org.javarosa.core.model.instance;

import org.javarosa.core.services.Logger;

import java.util.Hashtable;

/**
 * Dispatchs on instance ID to create new external data instances.  Useful for
 * injecting custom functionality for specific data instances, for instance if
 * you want casedb template resolution to behave different than normal external
 * instance resolution.
 *
 * @author Phillip Mates (pmates@dimagi.com)
 */
public class ExternalDataInstanceFactory {
    private static final Hashtable<String, ExternalDataInstanceBuilder> instanceIdToBuilder =
            new Hashtable<String, ExternalDataInstanceBuilder>();
    private static final Object lock = new Object();
    private static final ExternalDataInstance dummyDefaultInstance =
            new ExternalDataInstance();

    /**
     * Builds a new external data instance using the instance builder
     * registered to the given instanceId.  Defaults to building an
     * ExternalDataInstance instnace if no builder is registered under the
     * provided instanceId.
     */
    public static ExternalDataInstance getNewExternalDataInstance(String instanceId,
                                                                  String dataReference) {
        if (instanceIdToBuilder.containsKey(instanceId)) {
            ExternalDataInstanceBuilder builder = instanceIdToBuilder.get(instanceId);
            return builder.buildExternalDataInstance(dataReference, instanceId);
        } else {
            return dummyDefaultInstance.buildExternalDataInstance(dataReference, instanceId);
        }
    }

    /**
     * Register that instances of a given id should be represented with
     * particular external data instance class
     */
    public static void registerExternalDataInstanceBuilder(String instanceId,
                                                           ExternalDataInstanceBuilder instanceBuilder) {
        synchronized (lock) {
            if (instanceIdToBuilder.contains(instanceId)) {
                Logger.log("Warning", "registering an existing external data instance");
            }
            instanceIdToBuilder.put(instanceId, instanceBuilder);
        }
    }
}

@@ -1220,24 +1220,58 @@
 eference) %7B%0A
+        synchronized (lock) %7B%0A    
         if (
@@ -1309,32 +1309,36 @@
 (instanceId)) %7B%0A
+    
             Exte
@@ -1416,24 +1416,28 @@
             
+  
+  
 return build
@@ -1501,16 +1501,20 @@
         
+    
 %7D else %7B
@@ -1522,24 +1522,28 @@
             
+  
+  
 return dummy
@@ -1604,32 +1604,46 @@
 e, instanceId);%0A
+            %7D%0A
         %7D%0A    %7D%0A

Synchronize access to static hashtable