/** * Appends a new {@link ModelLoaderFactory} onto the end of the existing set so that the * constructed {@link ModelLoader} will be tried after all default and previously registered * {@link ModelLoader}s for the given model and data classes. * * <p>If you're attempting to replace an existing {@link ModelLoader}, use * {@link #prepend(Class, Class, ModelLoaderFactory)}. This method is best for new types of models * and/or data or as a way to add an additional fallback loader for an existing type of * model/data. * * <p>If multiple {@link ModelLoaderFactory}s are registered for the same model and/or data * classes, the {@link ModelLoader}s they produce will be attempted in the order the * {@link ModelLoaderFactory}s were registered. Only if all {@link ModelLoader}s fail will the * entire request fail. * * @see #prepend(Class, Class, ModelLoaderFactory) * @see #replace(Class, Class, ModelLoaderFactory) * * @param modelClass The model class (e.g. URL, file path). * @param dataClass the data class (e.g. {@link java.io.InputStream}, * {@link java.io.FileDescriptor}). */ @NonNull public <Model, Data> Registry append( @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass, @NonNull ModelLoaderFactory<Model, Data> factory) { modelLoaderRegistry.append(modelClass, dataClass, factory); return this; }
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") @NonNull public <A> List<ModelLoader<A, ?>> getModelLoaders(@NonNull A model) { List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model)); int size = modelLoaders.size(); boolean isEmpty = true; List<ModelLoader<A, ?>> filteredLoaders = Collections.emptyList(); //noinspection ForLoopReplaceableByForEach to improve perf for (int i = 0; i < size; i++) { ModelLoader<A, ?> loader = modelLoaders.get(i); if (loader.handles(model)) { if (isEmpty) { filteredLoaders = new ArrayList<>(size - i); isEmpty = false; } filteredLoaders.add(loader); } } return filteredLoaders; }
@NonNull public <Model, TResource, Transcode> List<Class<?>> getRegisteredResourceClasses( @NonNull Class<Model> modelClass, @NonNull Class<TResource> resourceClass, @NonNull Class<Transcode> transcodeClass) { List<Class<?>> result = modelToResourceClassCache.get(modelClass, resourceClass, transcodeClass); if (result == null) { result = new ArrayList<>(); List<Class<?>> dataClasses = modelLoaderRegistry.getDataClasses(modelClass); for (Class<?> dataClass : dataClasses) { List<? extends Class<?>> registeredResourceClasses = decoderRegistry.getResourceClasses(dataClass, resourceClass); for (Class<?> registeredResourceClass : registeredResourceClasses) { List<Class<Transcode>> registeredTranscodeClasses = transcoderRegistry .getTranscodeClasses(registeredResourceClass, transcodeClass); if (!registeredTranscodeClasses.isEmpty() && !result.contains(registeredResourceClass)) { result.add(registeredResourceClass); } } } modelToResourceClassCache.put( modelClass, resourceClass, transcodeClass, Collections.unmodifiableList(result)); } return result; }
public synchronized <Model, Data> void replace( @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass, @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) { tearDown(multiModelLoaderFactory.replace(modelClass, dataClass, factory)); cache.clear(); }
public Registry() { this.modelLoaderRegistry = new ModelLoaderRegistry(throwableListPool); this.encoderRegistry = new EncoderRegistry(); this.decoderRegistry = new ResourceDecoderRegistry(); this.resourceEncoderRegistry = new ResourceEncoderRegistry(); this.dataRewinderRegistry = new DataRewinderRegistry(); this.transcoderRegistry = new TranscoderRegistry(); this.imageHeaderParserRegistry = new ImageHeaderParserRegistry(); setResourceDecoderBucketPriorityList( Arrays.asList(BUCKET_GIF, BUCKET_BITMAP, BUCKET_BITMAP_DRAWABLE)); }
@NonNull public <Model> List<ModelLoader<Model, ?>> getModelLoaders(@NonNull Model model) { List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model); if (result.isEmpty()) { throw new NoModelLoaderAvailableException(model); } return result; }
@NonNull Class<Data> dataClass, @NonNull ModelLoaderFactory<? extends Model, ? extends Data> factory) { modelLoaderRegistry.replace(modelClass, dataClass, factory); return this;
/** * Prepends a new {@link ModelLoaderFactory} onto the beginning of the existing set so that the * constructed {@link ModelLoader} will be tried before all default and previously registered * {@link ModelLoader}s for the given model and data classes. * * <p>If you're attempting to add additional functionality or add a backup that should run only * after the default {@link ModelLoader}s run, use * {@link #append(Class, Class, ModelLoaderFactory)}. This method is best for adding an additional * case to Glide's existing functionality that should run first. This method will still run * Glide's default {@link ModelLoader}s if the prepended {@link ModelLoader}s fail. * * <p>If multiple {@link ModelLoaderFactory}s are registered for the same model and/or data * classes, the {@link ModelLoader}s they produce will be attempted in the order the * {@link ModelLoaderFactory}s were registered. Only if all {@link ModelLoader}s fail will the * entire request fail. * * @see #append(Class, Class, ModelLoaderFactory) * @see #replace(Class, Class, ModelLoaderFactory) * * @param modelClass The model class (e.g. URL, file path). * @param dataClass the data class (e.g. {@link java.io.InputStream}, * {@link java.io.FileDescriptor}). */ @NonNull public <Model, Data> Registry prepend( @NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass, @NonNull ModelLoaderFactory<Model, Data> factory) { modelLoaderRegistry.prepend(modelClass, dataClass, factory); return this; }
public synchronized <Model, Data> void remove(@NonNull Class<Model> modelClass, @NonNull Class<Data> dataClass) { tearDown(multiModelLoaderFactory.remove(modelClass, dataClass)); cache.clear(); }
public Registry() { this.modelLoaderRegistry = new ModelLoaderRegistry(exceptionListPool); this.encoderRegistry = new EncoderRegistry(); this.decoderRegistry = new ResourceDecoderRegistry(); this.resourceEncoderRegistry = new ResourceEncoderRegistry(); this.dataRewinderRegistry = new DataRewinderRegistry(); this.transcoderRegistry = new TranscoderRegistry(); this.imageHeaderParserRegistry = new ImageHeaderParserRegistry(); setResourceDecoderBucketPriorityList( Arrays.asList(BUCKET_GIF, BUCKET_BITMAP, BUCKET_BITMAP_DRAWABLE)); }
public <Model> List<ModelLoader<Model, ?>> getModelLoaders(Model model) { List<ModelLoader<Model, ?>> result = modelLoaderRegistry.getModelLoaders(model); if (result.isEmpty()) { throw new NoModelLoaderAvailableException(model); } return result; }
/** * Removes all default and previously registered {@link ModelLoaderFactory}s for the given data * and model class and replaces all of them with the single {@link ModelLoader} provided. * * <p>If you're attempting to add additional functionality or add a backup that should run only * after the default {@link ModelLoader}s run, use * {@link #append(Class, Class, ModelLoaderFactory)}. This method should be used only when you * want to ensure that Glide's default {@link ModelLoader}s do not run. * * <p>One good use case for this method is when you want to replace Glide's default networking * library with your OkHttp, Volley, or your own implementation. Using * {@link #prepend(Class, Class, ModelLoaderFactory)} or * {@link #append(Class, Class, ModelLoaderFactory)} may still allow Glide's default networking * library to run in some cases. Using this method will ensure that only your networking library * will run and that the request will fail otherwise. * * @see #prepend(Class, Class, ModelLoaderFactory) * @see #append(Class, Class, ModelLoaderFactory) * * @param modelClass The model class (e.g. URL, file path). * @param dataClass the data class (e.g. {@link java.io.InputStream}, * {@link java.io.FileDescriptor}). */ public <Model, Data> Registry replace(Class<Model> modelClass, Class<Data> dataClass, ModelLoaderFactory<Model, Data> factory) { modelLoaderRegistry.replace(modelClass, dataClass, factory); return this; }
/** * Prepends a new {@link ModelLoaderFactory} onto the beginning of the existing set so that the * constructed {@link ModelLoader} will be tried before all default and previously registered * {@link ModelLoader}s for the given model and data classes. * * <p>If you're attempting to add additional functionality or add a backup that should run only * after the default {@link ModelLoader}s run, use * {@link #append(Class, Class, ModelLoaderFactory)}. This method is best for adding an additional * case to Glide's existing functionality that should run first. This method will still run * Glide's default {@link ModelLoader}s if the prepended {@link ModelLoader}s fail. * * <p>If multiple {@link ModelLoaderFactory}s are registered for the same model and/or data * classes, the {@link ModelLoader}s they produce will be attempted in the order the * {@link ModelLoaderFactory}s were registered. Only if all {@link ModelLoader}s fail will the * entire request fail. * * @see #append(Class, Class, ModelLoaderFactory) * @see #replace(Class, Class, ModelLoaderFactory) * * @param modelClass The model class (e.g. URL, file path). * @param dataClass the data class (e.g. {@link java.io.InputStream}, * {@link java.io.FileDescriptor}). */ public <Model, Data> Registry prepend(Class<Model> modelClass, Class<Data> dataClass, ModelLoaderFactory<Model, Data> factory) { modelLoaderRegistry.prepend(modelClass, dataClass, factory); return this; }
public synchronized <A> List<ModelLoader<A, ?>> getModelLoaders(A model) { List<ModelLoader<A, ?>> modelLoaders = getModelLoadersForClass(getClass(model)); int size = modelLoaders.size(); List<ModelLoader<A, ?>> filteredLoaders = new ArrayList<>(size); for (int i = 0; i < size; i++) { ModelLoader<A, ?> loader = modelLoaders.get(i); if (loader.handles(model)) { filteredLoaders.add(loader); } } return filteredLoaders; }
public synchronized <Model, Data> void replace(Class<Model> modelClass, Class<Data> dataClass, ModelLoaderFactory<Model, Data> factory) { tearDown(multiModelLoaderFactory.replace(modelClass, dataClass, factory)); cache.clear(); }
public <Model, TResource, Transcode> List<Class<?>> getRegisteredResourceClasses( Class<Model> modelClass, Class<TResource> resourceClass, Class<Transcode> transcodeClass) { List<Class<?>> result = modelToResourceClassCache.get(modelClass, resourceClass); if (result == null) { result = new ArrayList<>(); List<Class<?>> dataClasses = modelLoaderRegistry.getDataClasses(modelClass); for (Class<?> dataClass : dataClasses) { List<? extends Class<?>> registeredResourceClasses = decoderRegistry.getResourceClasses(dataClass, resourceClass); for (Class<?> registeredResourceClass : registeredResourceClasses) { List<Class<Transcode>> registeredTranscodeClasses = transcoderRegistry .getTranscodeClasses(registeredResourceClass, transcodeClass); if (!registeredTranscodeClasses.isEmpty() && !result.contains(registeredResourceClass)) { result.add(registeredResourceClass); } } } modelToResourceClassCache.put(modelClass, resourceClass, Collections.unmodifiableList(result)); } return result; }
/** * Appends a new {@link ModelLoaderFactory} onto the end of the existing set so that the * constructed {@link ModelLoader} will be tried after all default and previously registered * {@link ModelLoader}s for the given model and data classes. * * <p>If you're attempting to replace an existing {@link ModelLoader}, use * {@link #prepend(Class, Class, ModelLoaderFactory)}. This method is best for new types of models * and/or data or as a way to add an additional fallback loader for an existing type of * model/data. * * <p>If multiple {@link ModelLoaderFactory}s are registered for the same model and/or data * classes, the {@link ModelLoader}s they produce will be attempted in the order the * {@link ModelLoaderFactory}s were registered. Only if all {@link ModelLoader}s fail will the * entire request fail. * * @see #prepend(Class, Class, ModelLoaderFactory) * @see #replace(Class, Class, ModelLoaderFactory) * * @param modelClass The model class (e.g. URL, file path). * @param dataClass the data class (e.g. {@link java.io.InputStream}, * {@link java.io.FileDescriptor}). */ public <Model, Data> Registry append(Class<Model> modelClass, Class<Data> dataClass, ModelLoaderFactory<Model, Data> factory) { modelLoaderRegistry.append(modelClass, dataClass, factory); return this; }
public synchronized <Model, Data> void remove(Class<Model> modelClass, Class<Data> dataClass) { tearDown(multiModelLoaderFactory.remove(modelClass, dataClass)); cache.clear(); }