GenericLoaderFactory.java revision 0ae32dc10d668a04f9f0484d587aefe5a7210e1c
10ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Juddpackage com.bumptech.glide.loader.bitmap.model; 20ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 30ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Juddimport android.content.Context; 40ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 50ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Juddimport java.util.HashMap; 60ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Juddimport java.util.Map; 70ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 80ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd/** 90ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd * Maintain a map of model class to factory to retrieve a {@link ModelLoaderFactory} and/or a {@link ModelLoader} 100ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd * for a given model type. 110ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd */ 120ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Juddpublic class GenericLoaderFactory { 130ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd private Map<Class, Map<Class, ModelLoaderFactory>> modelClassToResourceFactories = 140ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd new HashMap<Class, Map<Class, ModelLoaderFactory>>(); 150ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 160ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd @SuppressWarnings("unchecked") 170ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd public <T, Y> ModelLoaderFactory<T, Y> register(Class<T> modelClass, Class<Y> resourceClass, 180ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd ModelLoaderFactory<T, Y> factory) { 190ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd Map<Class, ModelLoaderFactory> resourceToFactories = modelClassToResourceFactories.get(modelClass); 200ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (resourceToFactories == null) { 210ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd resourceToFactories = new HashMap<Class, ModelLoaderFactory>(); 220ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd modelClassToResourceFactories.put(modelClass, resourceToFactories); 230ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 240ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 250ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd ModelLoaderFactory<T, Y> previous = resourceToFactories.put(resourceClass, factory); 260ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 270ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (previous != null) { 280ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // This factory may be being used by another model. We don't want to say it has been removed unless we 290ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // know it has been removed for all models. 300ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd for (Map<Class, ModelLoaderFactory> currentResourceToFactories : modelClassToResourceFactories.values()) { 310ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (currentResourceToFactories.containsValue(previous)) { 320ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd previous = null; 330ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd break; 340ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 350ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 360ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 370ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd return previous; 380ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 390ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 400ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd public <T, Y> ModelLoader<T, Y> buildModelLoader(Class<T> modelClass, Class<Y> resourceClass, Context context) { 410ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd final ModelLoaderFactory<T, Y> factory = getFactory(modelClass, resourceClass); 420ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (factory == null) { 430ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd throw new IllegalArgumentException("No ModelLoaderFactory registered for class=" + modelClass); 440ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 450ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd return factory.build(context, this); 460ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 470ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 480ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd @SuppressWarnings("unchecked") 490ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd public <T, Y> ModelLoaderFactory<T, Y> getFactory(Class<T> modelClass, Class<Y> resourceClass) { 500ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd Map<Class, ModelLoaderFactory> resourceToFactories = modelClassToResourceFactories.get(modelClass); 510ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd ModelLoaderFactory result = null; 520ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (resourceToFactories != null) { 530ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd result = resourceToFactories.get(resourceClass); 540ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 550ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 560ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 570ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (result == null) { 580ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd for (Class registeredModelClass : modelClassToResourceFactories.keySet()) { 590ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // This accounts for model subclasses, our map only works for exact matches. We should however still 600ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // match a subclass of a model with a factory for a super class of that model if if there isn't a 610ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // factory for that particular subclass. Uris are a great example of when this happens, most uris 620ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // are actually subclasses for Uri, but we'd generally rather load them all with the same factory rather 630ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd // than trying to register for each subclass individually. 640ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (registeredModelClass.isAssignableFrom(modelClass)) { 650ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd Map<Class, ModelLoaderFactory> currentResourceToFactories = 660ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd modelClassToResourceFactories.get(registeredModelClass); 670ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (currentResourceToFactories != null) { 680ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd result = currentResourceToFactories.get(resourceClass); 690ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd if (result != null) { 700ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd break; 710ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 720ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 730ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 740ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 750ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 760ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd 770ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd return result; 780ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd } 790ae32dc10d668a04f9f0484d587aefe5a7210e1cSam Judd} 80