1package com.bumptech.glide.volley;
2
3import com.android.volley.NetworkResponse;
4import com.android.volley.Request;
5import com.android.volley.RequestQueue;
6import com.android.volley.Response;
7import com.android.volley.toolbox.HttpHeaderParser;
8import com.bumptech.glide.Priority;
9import com.bumptech.glide.load.data.DataFetcher;
10
11import java.io.ByteArrayInputStream;
12import java.io.InputStream;
13
14/**
15 * A DataFetcher backed by volley for fetching images via http.
16 */
17public class VolleyStreamFetcher implements DataFetcher<InputStream> {
18    private final RequestQueue requestQueue;
19    private final String url;
20    private VolleyRequestFuture<InputStream> requestFuture;
21
22    @SuppressWarnings("unused")
23    public VolleyStreamFetcher(RequestQueue requestQueue, String url) {
24        this(requestQueue, url,  null);
25    }
26
27    public VolleyStreamFetcher(RequestQueue requestQueue, String url, VolleyRequestFuture<InputStream> requestFuture) {
28        this.requestQueue = requestQueue;
29        this.url = url;
30        this.requestFuture = requestFuture;
31        if (requestFuture == null) {
32            this.requestFuture = VolleyRequestFuture.newFuture();
33        }
34    }
35
36    @Override
37    public InputStream loadData(Priority priority) throws Exception {
38        GlideRequest request = new GlideRequest(url, requestFuture, glideToVolleyPriority(priority));
39
40        requestFuture.setRequest(requestQueue.add(request));
41
42        return requestFuture.get();
43    }
44
45    @Override
46    public void cleanup() {
47        // Do nothing.
48    }
49
50    @Override
51    public String getId() {
52        return url;
53    }
54
55    @Override
56    public void cancel() {
57        VolleyRequestFuture<InputStream> localFuture = requestFuture;
58        if (localFuture != null) {
59            localFuture.cancel(true);
60        }
61    }
62
63    private static Request.Priority glideToVolleyPriority(Priority priority) {
64        switch (priority) {
65            case LOW:
66                return Request.Priority.LOW;
67            case HIGH:
68                return Request.Priority.HIGH;
69            case IMMEDIATE:
70                return Request.Priority.IMMEDIATE;
71            default:
72                return Request.Priority.NORMAL;
73
74        }
75    }
76
77    private static class GlideRequest extends Request<byte[]> {
78        private final VolleyRequestFuture<InputStream> future;
79        private Priority priority;
80
81        public GlideRequest(String url, VolleyRequestFuture<InputStream> future, Priority priority) {
82            super(Method.GET, url, future);
83            this.future = future;
84            this.priority = priority;
85        }
86
87        @Override
88        public Priority getPriority() {
89            return priority;
90        }
91
92        @Override
93        protected Response<byte[]> parseNetworkResponse(NetworkResponse response) {
94            return Response.success(response.data, HttpHeaderParser.parseCacheHeaders(response));
95        }
96
97        @Override
98        protected void deliverResponse(byte[] response) {
99            future.onResponse(new ByteArrayInputStream(response));
100        }
101    }
102}
103