package org.openrosa.client.jr.core.model.instance.utils;
import java.util.HashMap;
import java.util.Vector;
import org.openrosa.client.jr.core.model.instance.FormInstance;
/**
* Instance template manager that caches the template instances in memory. Useful for when deserializing
* many saved forms of the same form type at once.
*
* Instance templates are lazily loaded into the cache upon the first request for the instance of that type.
*
* Instances stay cached until explicitly cleared.
*
* Keeping too many FormInstances cached at once may exhaust your memory. It's best if all saved forms
* being deserialized in bulk belong to a set of a few, known form types. It is possible to explicitly
* set the allowed form types, such that any attempt to deserialize a form of a different type will throw
* an error, instead of caching the new instance template.
*
* @author Drew Roos
*
*/
public class CachingInstanceTemplateManager implements InstanceTemplateManager {
private HashMap<Integer, FormInstance> templateCache;
private Vector<Integer> allowedFormTypes;
private boolean restrictFormTypes;
public CachingInstanceTemplateManager () {
this(true);
}
/**
*
* @param restrictFormTypes if true, only allowed form types will be cached; any requests for the templates
* for other form types will throw an error; the list of allowed types starts out empty; register allowed
* form types with addFormType(). if false, all form types will be handled and cached
*/
public CachingInstanceTemplateManager (boolean restrictFormTypes) {
this.templateCache = new HashMap<Integer, FormInstance>();
this.restrictFormTypes = restrictFormTypes;
this.allowedFormTypes = new Vector<Integer>();
}
/**
* Remove all model templates from the cache. Frees up memory.
*/
public void clearCache () {
templateCache.clear();
}
/**
* Set a form type as allowed for caching. Only has an effect if this class has been set to restrict form types
* @param formID
*/
public void addFormType (int formID) {
if (!allowedFormTypes.contains(new Integer(formID))) {
allowedFormTypes.addElement(new Integer(formID));
}
}
/**
* Empty the list of allowed form types
*/
public void resetFormTypes () {
allowedFormTypes.removeAllElements();
}
/**
* Return the template model for the given form type. Serves the template out of the cache, if cached; fetches it
* fresh and caches it otherwise. If form types are restricted and the given form type is not allowed, throw an error
*/
public FormInstance getTemplateInstance (int formID) {
if (restrictFormTypes && !allowedFormTypes.contains(new Integer(formID))) {
throw new RuntimeException ("form ID [" + formID + "] is not an allowed form type!");
}
FormInstance template = templateCache.get(new Integer(formID));
if (template == null) {
template = CompactInstanceWrapper.loadTemplateInstance(formID);
if (template == null) {
throw new RuntimeException("no formdef found for form id [" + formID + "]");
}
templateCache.put(new Integer(formID), template);
}
return template;
}
}