-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Work toward #198.
- Loading branch information
Showing
4 changed files
with
230 additions
and
69 deletions.
There are no files selected for viewing
77 changes: 77 additions & 0 deletions
77
library/src/main/java/com/bumptech/glide/load/model/BasicHeaders.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package com.bumptech.glide.load.model; | ||
|
||
import android.text.TextUtils; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* A wrapper class for a set of headers to be included in a Glide request. | ||
*/ | ||
public final class BasicHeaders implements Headers { | ||
|
||
private final Map<String, Set<String>> headers; | ||
private volatile Map<String, String> combinedHeaders; | ||
|
||
BasicHeaders(Map<String, Set<String>> headers) { | ||
this.headers = Collections.unmodifiableMap(headers); | ||
} | ||
|
||
public Map<String, String> getHeaders() { | ||
if (combinedHeaders == null) { | ||
synchronized (this) { | ||
if (combinedHeaders == null) { | ||
this.combinedHeaders = generateCombinedHeaders(); | ||
} | ||
} | ||
} | ||
|
||
return combinedHeaders; | ||
} | ||
|
||
private Map<String, String> generateCombinedHeaders() { | ||
Map<String, String> combinedHeaders = new HashMap<String, String>(); | ||
for (Map.Entry<String, Set<String>> entry : headers.entrySet()) { | ||
combinedHeaders.put(entry.getKey(), TextUtils.join(",", entry.getValue())); | ||
} | ||
return Collections.unmodifiableMap(combinedHeaders); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (o instanceof BasicHeaders) { | ||
BasicHeaders other = (BasicHeaders) o; | ||
return headers.equals(other.headers); | ||
} | ||
return false; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return headers.hashCode(); | ||
} | ||
|
||
/** | ||
* Builder class for {@link Headers}. | ||
*/ | ||
public static final class Builder { | ||
private final Map<String, Set<String>> headers = new HashMap<String, Set<String>>(); | ||
|
||
public void addHeader(String key, String value) { | ||
if (headers.containsKey(key)) { | ||
headers.get(key).add(value); | ||
} else { | ||
Set<String> values = new HashSet<String>(); | ||
values.add(value); | ||
headers.put(key, values); | ||
} | ||
} | ||
|
||
public BasicHeaders build() { | ||
return new BasicHeaders(headers); | ||
} | ||
} | ||
} |
75 changes: 6 additions & 69 deletions
75
library/src/main/java/com/bumptech/glide/load/model/Headers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,16 @@ | ||
package com.bumptech.glide.load.model; | ||
|
||
import android.text.TextUtils; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* A wrapper class for a set of headers to be included in a Glide request. | ||
* An interface for a wrapper for a set of headers to be included in a Glide request. | ||
* Implementations must implement equals() and hashcode(). | ||
*/ | ||
public final class Headers { | ||
|
||
public static final Headers NONE = new Builder().build(); | ||
|
||
private final Map<String, Set<String>> headers; | ||
private volatile Map<String, String> combinedHeaders; | ||
|
||
Headers(Map<String, Set<String>> headers) { | ||
this.headers = Collections.unmodifiableMap(headers); | ||
} | ||
|
||
public Map<String, String> getHeaders() { | ||
if (combinedHeaders == null) { | ||
synchronized (this) { | ||
if (combinedHeaders == null) { | ||
this.combinedHeaders = generateCombinedHeaders(); | ||
} | ||
} | ||
} | ||
|
||
return combinedHeaders; | ||
} | ||
|
||
private Map<String, String> generateCombinedHeaders() { | ||
Map<String, String> combinedHeaders = new HashMap<String, String>(); | ||
for (Map.Entry<String, Set<String>> entry : headers.entrySet()) { | ||
combinedHeaders.put(entry.getKey(), TextUtils.join(",", entry.getValue())); | ||
} | ||
return Collections.unmodifiableMap(combinedHeaders); | ||
} | ||
|
||
/** | ||
* Builder class for {@link Headers}. | ||
*/ | ||
public static final class Builder { | ||
private final Map<String, Set<String>> headers = new HashMap<String, Set<String>>(); | ||
|
||
public void addHeader(String key, String value) { | ||
if (headers.containsKey(key)) { | ||
headers.get(key).add(value); | ||
} else { | ||
Set<String> values = new HashSet<String>(); | ||
values.add(value); | ||
headers.put(key, values); | ||
} | ||
} | ||
public interface Headers { | ||
|
||
public Headers build() { | ||
return new Headers(headers); | ||
} | ||
} | ||
/** An empty Headers object that can be used if users don't want to provide headers. */ | ||
Headers NONE = new BasicHeaders.Builder().build(); | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (o instanceof Headers) { | ||
Headers other = (Headers) o; | ||
return headers.equals(other.headers); | ||
} | ||
return false; | ||
} | ||
Map<String, String> getHeaders(); | ||
|
||
@Override | ||
public int hashCode() { | ||
return headers.hashCode(); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
library/src/main/java/com/bumptech/glide/load/model/LazyHeaderFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.bumptech.glide.load.model; | ||
|
||
/** | ||
* An interface for lazily creating headers that allows expensive to calculate headers (oauth for | ||
* example) to be generated in the background during the first fetch. | ||
* | ||
* <p> Implementations should implement equals() and hashcode() </p> . | ||
*/ | ||
public interface LazyHeaderFactory { | ||
|
||
String buildHeader(); | ||
|
||
} |
134 changes: 134 additions & 0 deletions
134
library/src/main/java/com/bumptech/glide/load/model/LazyHeaders.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package com.bumptech.glide.load.model; | ||
|
||
import android.text.TextUtils; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
/** | ||
* A wrapper class for a set of headers to be included in a Glide request, allowing headers to be | ||
* constructed lazily. | ||
* | ||
* <p> Should be used instead of BasicHeaders when constructing headers requires I/O. </p> | ||
*/ | ||
public final class LazyHeaders implements Headers { | ||
private final Map<String, Set<String>> eagerHeaders; | ||
private final Map<String, Set<LazyHeaderFactory>> lazyHeaders; | ||
private volatile Map<String, String> combinedHeaders; | ||
|
||
LazyHeaders(Map<String, Set<String>> eagerHeaders, | ||
Map<String, Set<LazyHeaderFactory>> lazyHeaders) { | ||
this.eagerHeaders = Collections.unmodifiableMap(eagerHeaders); | ||
this.lazyHeaders = Collections.unmodifiableMap(lazyHeaders); | ||
} | ||
|
||
@Override | ||
public Map<String, String> getHeaders() { | ||
if (combinedHeaders == null) { | ||
synchronized (this) { | ||
if (combinedHeaders == null) { | ||
this.combinedHeaders = Collections.unmodifiableMap(generateHeaders()); | ||
} | ||
} | ||
} | ||
|
||
return combinedHeaders; | ||
} | ||
|
||
private Map<String, String> generateHeaders() { | ||
Map<String, String> combinedHeaders = new HashMap<String, String>(); | ||
Set<String> combinedKeys = new HashSet<String>(eagerHeaders.keySet()); | ||
combinedKeys.addAll(lazyHeaders.keySet()); | ||
|
||
for (String key : combinedKeys) { | ||
Set<String> values = new HashSet<String>(); | ||
if (eagerHeaders.containsKey(key)) { | ||
values.addAll(eagerHeaders.get(key)); | ||
} | ||
if (lazyHeaders.containsKey(key)) { | ||
for (LazyHeaderFactory factory : lazyHeaders.get(key)) { | ||
values.add(factory.buildHeader()); | ||
} | ||
} | ||
combinedHeaders.put(key, TextUtils.join(",", values)); | ||
} | ||
|
||
return combinedHeaders; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
Set<String> combinedKeys = new HashSet<String>(eagerHeaders.keySet()); | ||
combinedKeys.addAll(lazyHeaders.keySet()); | ||
|
||
StringBuilder stringBuilder = new StringBuilder(); | ||
for (String key : combinedKeys) { | ||
stringBuilder.append(key) | ||
.append(": "); | ||
if (eagerHeaders.containsKey(key)) { | ||
stringBuilder.append(TextUtils.join(",", eagerHeaders.get(key))); | ||
} | ||
if (lazyHeaders.containsKey(key)) { | ||
for (LazyHeaderFactory factory : lazyHeaders.get(key)) { | ||
stringBuilder.append(factory.toString()); | ||
stringBuilder.append(','); | ||
} | ||
} | ||
stringBuilder.append('\n'); | ||
} | ||
return stringBuilder.toString(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
|
||
LazyHeaders otherHeaders = (LazyHeaders) o; | ||
return eagerHeaders.equals(otherHeaders.eagerHeaders) | ||
&& lazyHeaders.equals(otherHeaders.lazyHeaders); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return eagerHeaders.hashCode() + 31 * lazyHeaders.hashCode(); | ||
} | ||
|
||
/** | ||
* Builder class for {@link BasicHeaders}. | ||
*/ | ||
public static final class Builder { | ||
private final Map<String, Set<String>> eagerHeaders = new HashMap<String, Set<String>>(); | ||
private final Map<String, Set<LazyHeaderFactory>> lazyHeaders = | ||
new HashMap<String, Set<LazyHeaderFactory>>(); | ||
|
||
public void addHeader(String key, String value) { | ||
Set<String> values = eagerHeaders.get(key); | ||
if (values == null) { | ||
values = new HashSet<String>(); | ||
eagerHeaders.put(key, values); | ||
} | ||
values.add(value); | ||
} | ||
|
||
public void addHeader(String key, LazyHeaderFactory factory) { | ||
Set<LazyHeaderFactory> factories = lazyHeaders.get(key); | ||
if (factories == null) { | ||
factories = new HashSet<LazyHeaderFactory>(); | ||
lazyHeaders.put(key, factories); | ||
} | ||
factories.add(factory); | ||
} | ||
|
||
public LazyHeaders build() { | ||
return new LazyHeaders(eagerHeaders, lazyHeaders); | ||
} | ||
} | ||
} |
fee6ed6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think about this: Sets VS Lists in the Maps. I didn't read the full header spec, but there are some orderings appear in it: search for "the order" in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. Most used multivalued headers seems to be using the quality qualifier
;q=
though for ordering.fee6ed6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, thanks for looking as always, filed #361.