1 package com.bumptech.glide.load.model; 2 3 import android.net.Uri; 4 import android.text.TextUtils; 5 6 import java.net.MalformedURLException; 7 import 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 */ 22 public 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 GlideUrl(URL url)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 GlideUrl(String url)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 toURL()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. getSafeUrl()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 toString()66 public String toString() { 67 if (TextUtils.isEmpty(stringUrl)) { 68 stringUrl = url.toString(); 69 } 70 return stringUrl; 71 } 72 73 @Override equals(Object o)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 hashCode()86 public int hashCode() { 87 return toString().hashCode(); 88 } 89 } 90