GlideUrl.java revision 5ba19a0e69ad3a651b8f13ba45de48a56b56ce36
1package com.bumptech.glide.load.model;
2
3import android.net.Uri;
4import android.text.TextUtils;
5
6import java.net.MalformedURLException;
7import java.net.URL;
8
9/**
10 * A wrapper for strings representing http/https URLs responsible for ensuring URLs are properly escaped and avoiding
11 * unnecessary URL instantiations for loaders that require only string urls rather than URL objects.
12 *
13 * <p>
14 *  Users wishing to replace the class for handling URLs must register a factory using GlideUrl.
15 * </p>
16 *
17 * <p>
18 *     To obtain a properly escaped URL, call {@link #toURL()}. To obtain a properly escaped string URL, call
19 *     {@link #toURL()} and then {@link java.net.URL#toString()}.
20 * </p>
21 */
22public class GlideUrl {
23    private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
24
25    private final URL url;
26    private String stringUrl;
27
28    private URL safeUrl;
29
30    public GlideUrl(URL url) {
31        if (url == null) {
32            throw new IllegalArgumentException("URL must not be null!");
33        }
34        this.url = url;
35        stringUrl = null;
36    }
37
38    public GlideUrl(String url) {
39        if (TextUtils.isEmpty(url)) {
40            throw new IllegalArgumentException("String url must not be empty or null: " + url);
41        }
42        this.stringUrl = url;
43        this.url = null;
44    }
45
46
47    public URL toURL() throws MalformedURLException {
48        return getSafeUrl();
49    }
50
51    // See http://stackoverflow.com/questions/3286067/url-encoding-in-android. Although the answer using URI would work,
52    // using it would require both decoding and encoding each string which is more complicated, slower and generates
53    // more objects than the solution below. See also issue #133.
54    private URL getSafeUrl() throws MalformedURLException {
55        if (safeUrl != null) {
56            return safeUrl;
57        }
58        String unsafe = toString();
59        String safe = Uri.encode(unsafe, ALLOWED_URI_CHARS);
60
61        safeUrl = new URL(safe);
62        return safeUrl;
63    }
64
65    @Override
66    public String toString() {
67        if (TextUtils.isEmpty(stringUrl)) {
68            stringUrl = url.toString();
69        }
70        return stringUrl;
71    }
72
73    @Override
74    public boolean equals(Object o) {
75        if (this == o) {
76            return true;
77        }
78        if (o == null || getClass() != o.getClass()) {
79            return false;
80        }
81
82        return toString().equals(o.toString());
83    }
84
85    @Override
86    public int hashCode() {
87        return toString().hashCode();
88    }
89}
90