Commit 5925f924 by eguven Committed by Oliver Woodman

Persist content redirected URI in CacheDataSource

Issue: #2360

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=190597773
parent f0bb6bb2
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
* Add release method to Cache interface. * Add release method to Cache interface.
* Prevent multiple instances of SimpleCache in the same folder. * Prevent multiple instances of SimpleCache in the same folder.
Previous instance must be released. Previous instance must be released.
* Store redirected URI
([#2360](https://github.com/google/ExoPlayer/issues/2360)).
* DRM: * DRM:
* Allow multiple listeners for `DefaultDrmSessionManager`. * Allow multiple listeners for `DefaultDrmSessionManager`.
* Pass `DrmSessionManager` to `ExoPlayerFactory` instead of `RendererFactory`. * Pass `DrmSessionManager` to `ExoPlayerFactory` instead of `RendererFactory`.
......
...@@ -21,11 +21,11 @@ public class CachedContentIndexTest extends InstrumentationTestCase { ...@@ -21,11 +21,11 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
0, 0, 0, 1, // version 0, 0, 0, 1, // version
0, 0, 0, 0, // flags 0, 0, 0, 0, // flags
0, 0, 0, 2, // number_of_CachedContent 0, 0, 0, 2, // number_of_CachedContent
0, 0, 0, 5, // cache_id 0, 0, 0, 5, // cache_id 5
0, 5, 65, 66, 67, 68, 69, // cache_key 0, 5, 65, 66, 67, 68, 69, // cache_key "ABCDE"
0, 0, 0, 0, 0, 0, 0, 10, // original_content_length 0, 0, 0, 0, 0, 0, 0, 10, // original_content_length
0, 0, 0, 2, // cache_id 0, 0, 0, 2, // cache_id 2
0, 5, 75, 76, 77, 78, 79, // cache_key 0, 5, 75, 76, 77, 78, 79, // cache_key "KLMNO"
0, 0, 0, 0, 0, 0, 10, 0, // original_content_length 0, 0, 0, 0, 0, 0, 10, 0, // original_content_length
(byte) 0xF6, (byte) 0xFB, 0x50, 0x41 // hashcode_of_CachedContent_array (byte) 0xF6, (byte) 0xFB, 0x50, 0x41 // hashcode_of_CachedContent_array
}; };
...@@ -285,8 +285,7 @@ public class CachedContentIndexTest extends InstrumentationTestCase { ...@@ -285,8 +285,7 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
Set<String> keys2 = index2.getKeys(); Set<String> keys2 = index2.getKeys();
assertThat(keys2).isEqualTo(keys); assertThat(keys2).isEqualTo(keys);
for (String key : keys) { for (String key : keys) {
assertThat(index2.getContentLength(key)).isEqualTo(index.getContentLength(key)); assertThat(index2.get(key)).isEqualTo(index.get(key));
assertThat(index2.get(key).getSpans()).isEqualTo(index.get(key).getSpans());
} }
} }
} }
...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.upstream.cache; ...@@ -18,6 +18,7 @@ package com.google.android.exoplayer2.upstream.cache;
import android.net.Uri; import android.net.Uri;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSink; import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
...@@ -51,6 +52,8 @@ public final class CacheDataSource implements DataSource { ...@@ -51,6 +52,8 @@ public final class CacheDataSource implements DataSource {
*/ */
public static final long DEFAULT_MAX_CACHE_FILE_SIZE = 2 * 1024 * 1024; public static final long DEFAULT_MAX_CACHE_FILE_SIZE = 2 * 1024 * 1024;
private static final String TAG = "CacheDataSource";
/** /**
* Flags controlling the cache's behavior. * Flags controlling the cache's behavior.
*/ */
...@@ -125,6 +128,7 @@ public final class CacheDataSource implements DataSource { ...@@ -125,6 +128,7 @@ public final class CacheDataSource implements DataSource {
private DataSource currentDataSource; private DataSource currentDataSource;
private boolean currentDataSpecLengthUnset; private boolean currentDataSpecLengthUnset;
private Uri uri; private Uri uri;
private Uri actualUri;
private int flags; private int flags;
private String key; private String key;
private long readPosition; private long readPosition;
...@@ -212,9 +216,10 @@ public final class CacheDataSource implements DataSource { ...@@ -212,9 +216,10 @@ public final class CacheDataSource implements DataSource {
@Override @Override
public long open(DataSpec dataSpec) throws IOException { public long open(DataSpec dataSpec) throws IOException {
try { try {
key = CacheUtil.getKey(dataSpec);
uri = dataSpec.uri; uri = dataSpec.uri;
actualUri = loadRedirectedUriOrReturnGivenUri(cache, key, uri);
flags = dataSpec.flags; flags = dataSpec.flags;
key = CacheUtil.getKey(dataSpec);
readPosition = dataSpec.position; readPosition = dataSpec.position;
currentRequestIgnoresCache = (ignoreCacheOnError && seenCacheError) currentRequestIgnoresCache = (ignoreCacheOnError && seenCacheError)
|| (dataSpec.length == C.LENGTH_UNSET && ignoreCacheForUnsetLengthRequests); || (dataSpec.length == C.LENGTH_UNSET && ignoreCacheForUnsetLengthRequests);
...@@ -251,7 +256,7 @@ public final class CacheDataSource implements DataSource { ...@@ -251,7 +256,7 @@ public final class CacheDataSource implements DataSource {
} }
int bytesRead = currentDataSource.read(buffer, offset, readLength); int bytesRead = currentDataSource.read(buffer, offset, readLength);
if (bytesRead != C.RESULT_END_OF_INPUT) { if (bytesRead != C.RESULT_END_OF_INPUT) {
if (currentDataSource == cacheReadDataSource) { if (isReadingFromCache()) {
totalCachedBytesRead += bytesRead; totalCachedBytesRead += bytesRead;
} }
readPosition += bytesRead; readPosition += bytesRead;
...@@ -259,7 +264,7 @@ public final class CacheDataSource implements DataSource { ...@@ -259,7 +264,7 @@ public final class CacheDataSource implements DataSource {
bytesRemaining -= bytesRead; bytesRemaining -= bytesRead;
} }
} else if (currentDataSpecLengthUnset) { } else if (currentDataSpecLengthUnset) {
setBytesRemaining(0); setBytesRemainingAndMaybeStoreLength(0);
} else if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) { } else if (bytesRemaining > 0 || bytesRemaining == C.LENGTH_UNSET) {
closeCurrentSource(); closeCurrentSource();
openNextSource(false); openNextSource(false);
...@@ -268,7 +273,7 @@ public final class CacheDataSource implements DataSource { ...@@ -268,7 +273,7 @@ public final class CacheDataSource implements DataSource {
return bytesRead; return bytesRead;
} catch (IOException e) { } catch (IOException e) {
if (currentDataSpecLengthUnset && isCausedByPositionOutOfRange(e)) { if (currentDataSpecLengthUnset && isCausedByPositionOutOfRange(e)) {
setBytesRemaining(0); setBytesRemainingAndMaybeStoreLength(0);
return C.RESULT_END_OF_INPUT; return C.RESULT_END_OF_INPUT;
} }
handleBeforeThrow(e); handleBeforeThrow(e);
...@@ -278,12 +283,13 @@ public final class CacheDataSource implements DataSource { ...@@ -278,12 +283,13 @@ public final class CacheDataSource implements DataSource {
@Override @Override
public Uri getUri() { public Uri getUri() {
return currentDataSource == upstreamDataSource ? currentDataSource.getUri() : uri; return actualUri;
} }
@Override @Override
public void close() throws IOException { public void close() throws IOException {
uri = null; uri = null;
actualUri = null;
notifyBytesRead(); notifyBytesRead();
try { try {
closeCurrentSource(); closeCurrentSource();
...@@ -371,7 +377,7 @@ public final class CacheDataSource implements DataSource { ...@@ -371,7 +377,7 @@ public final class CacheDataSource implements DataSource {
? readPosition + MIN_READ_BEFORE_CHECKING_CACHE ? readPosition + MIN_READ_BEFORE_CHECKING_CACHE
: Long.MAX_VALUE; : Long.MAX_VALUE;
if (checkCache) { if (checkCache) {
Assertions.checkState(currentDataSource == upstreamDataSource); Assertions.checkState(isBypassingCache());
if (nextDataSource == upstreamDataSource) { if (nextDataSource == upstreamDataSource) {
// Continue reading from upstream. // Continue reading from upstream.
return; return;
...@@ -395,8 +401,45 @@ public final class CacheDataSource implements DataSource { ...@@ -395,8 +401,45 @@ public final class CacheDataSource implements DataSource {
currentDataSpecLengthUnset = nextDataSpec.length == C.LENGTH_UNSET; currentDataSpecLengthUnset = nextDataSpec.length == C.LENGTH_UNSET;
long resolvedLength = nextDataSource.open(nextDataSpec); long resolvedLength = nextDataSource.open(nextDataSpec);
if (currentDataSpecLengthUnset && resolvedLength != C.LENGTH_UNSET) { if (currentDataSpecLengthUnset && resolvedLength != C.LENGTH_UNSET) {
setBytesRemaining(resolvedLength); setBytesRemainingAndMaybeStoreLength(resolvedLength);
}
// TODO find a way to store length and redirected uri in one metadata mutation.
maybeUpdateActualUriFieldAndRedirectedUriMetadata();
}
private void maybeUpdateActualUriFieldAndRedirectedUriMetadata() {
if (!isReadingFromUpstream()) {
return;
} }
actualUri = currentDataSource.getUri();
maybeUpdateRedirectedUriMetadata();
}
private void maybeUpdateRedirectedUriMetadata() {
if (!isWritingToCache()) {
return;
}
ContentMetadataMutations mutations = new ContentMetadataMutations();
boolean isRedirected = !uri.equals(actualUri);
if (isRedirected) {
mutations.set(ContentMetadata.METADATA_NAME_REDIRECTED_URI, actualUri.toString());
} else {
mutations.remove(ContentMetadata.METADATA_NAME_REDIRECTED_URI);
}
try {
cache.applyContentMetadataMutations(key, mutations);
} catch (CacheException e) {
String message =
"Couldn't update redirected URI. "
+ "This might cause relative URIs get resolved incorrectly.";
Log.w(TAG, message, e);
}
}
private static Uri loadRedirectedUriOrReturnGivenUri(Cache cache, String key, Uri uri) {
ContentMetadata metadata = cache.getContentMetadata(key);
String redirection = metadata.get(ContentMetadata.METADATA_NAME_REDIRECTED_URI, (String) null);
return redirection == null ? uri : Uri.parse(redirection);
} }
private static boolean isCausedByPositionOutOfRange(IOException e) { private static boolean isCausedByPositionOutOfRange(IOException e) {
...@@ -413,13 +456,25 @@ public final class CacheDataSource implements DataSource { ...@@ -413,13 +456,25 @@ public final class CacheDataSource implements DataSource {
return false; return false;
} }
private void setBytesRemaining(long bytesRemaining) throws IOException { private void setBytesRemainingAndMaybeStoreLength(long bytesRemaining) throws IOException {
this.bytesRemaining = bytesRemaining; this.bytesRemaining = bytesRemaining;
if (isWritingToCache()) { if (isWritingToCache()) {
cache.setContentLength(key, readPosition + bytesRemaining); cache.setContentLength(key, readPosition + bytesRemaining);
} }
} }
private boolean isReadingFromUpstream() {
return !isReadingFromCache();
}
private boolean isBypassingCache() {
return currentDataSource == upstreamDataSource;
}
private boolean isReadingFromCache() {
return currentDataSource == cacheReadDataSource;
}
private boolean isWritingToCache() { private boolean isWritingToCache() {
return currentDataSource == cacheWriteDataSource; return currentDataSource == cacheWriteDataSource;
} }
...@@ -441,7 +496,7 @@ public final class CacheDataSource implements DataSource { ...@@ -441,7 +496,7 @@ public final class CacheDataSource implements DataSource {
} }
private void handleBeforeThrow(IOException exception) { private void handleBeforeThrow(IOException exception) {
if (currentDataSource == cacheReadDataSource || exception instanceof CacheException) { if (isReadingFromCache() || exception instanceof CacheException) {
seenCacheError = true; seenCacheError = true;
} }
} }
......
...@@ -29,8 +29,7 @@ import java.util.TreeSet; ...@@ -29,8 +29,7 @@ import java.util.TreeSet;
/*package*/ final class CachedContent { /*package*/ final class CachedContent {
private static final int VERSION_METADATA_INTRODUCED = 2; private static final int VERSION_METADATA_INTRODUCED = 2;
private static final String EXOPLAYER_METADATA_NAME_PREFIX = "exo_"; private static final int VERSION_MAX = Integer.MAX_VALUE;
private static final String METADATA_NAME_LENGTH = EXOPLAYER_METADATA_NAME_PREFIX + "len";
/** The cache file id that uniquely identifies the original stream. */ /** The cache file id that uniquely identifies the original stream. */
public final int id; public final int id;
...@@ -94,21 +93,28 @@ import java.util.TreeSet; ...@@ -94,21 +93,28 @@ import java.util.TreeSet;
return metadata; return metadata;
} }
/** Applies {@code mutations} to the metadata. */ /**
public void applyMetadataMutations(ContentMetadataMutations mutations) { * Applies {@code mutations} to the metadata.
this.metadata = new DefaultContentMetadata(metadata, mutations); *
* @return Whether {@code mutations} changed any metadata.
*/
public boolean applyMetadataMutations(ContentMetadataMutations mutations) {
DefaultContentMetadata oldMetadata = metadata;
metadata = metadata.copyWithMutationsApplied(mutations);
return metadata.equals(oldMetadata);
} }
/** /**
* Returns the length of the original stream, or {@link C#LENGTH_UNSET} if the length is unknown. * Returns the length of the original stream, or {@link C#LENGTH_UNSET} if the length is unknown.
*/ */
public long getLength() { public long getLength() {
return metadata.get(METADATA_NAME_LENGTH, C.LENGTH_UNSET); return metadata.get(ContentMetadata.METADATA_NAME_LENGTH, C.LENGTH_UNSET);
} }
/** Sets the length of the content. */ /** Sets the length of the content. */
public void setLength(long length) { public void setLength(long length) {
applyMetadataMutations(new ContentMetadataMutations().set(METADATA_NAME_LENGTH, length)); applyMetadataMutations(
new ContentMetadataMutations().set(ContentMetadata.METADATA_NAME_LENGTH, length));
} }
/** Returns whether the content is locked. */ /** Returns whether the content is locked. */
...@@ -234,4 +240,25 @@ import java.util.TreeSet; ...@@ -234,4 +240,25 @@ import java.util.TreeSet;
return result; return result;
} }
@Override
public int hashCode() {
int result = headerHashCode(VERSION_MAX);
result = 31 * result + cachedSpans.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CachedContent that = (CachedContent) o;
return id == that.id
&& key.equals(that.key)
&& cachedSpans.equals(that.cachedSpans)
&& metadata.equals(that.metadata);
}
} }
...@@ -224,7 +224,9 @@ import javax.crypto.spec.SecretKeySpec; ...@@ -224,7 +224,9 @@ import javax.crypto.spec.SecretKeySpec;
*/ */
public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations) { public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations) {
CachedContent cachedContent = getOrAdd(key); CachedContent cachedContent = getOrAdd(key);
cachedContent.applyMetadataMutations(mutations); if (cachedContent.applyMetadataMutations(mutations)) {
changed = true;
}
} }
/** Returns a {@link ContentMetadata} for the given key. */ /** Returns a {@link ContentMetadata} for the given key. */
......
...@@ -15,9 +15,21 @@ ...@@ -15,9 +15,21 @@
*/ */
package com.google.android.exoplayer2.upstream.cache; package com.google.android.exoplayer2.upstream.cache;
/** Interface for an immutable snapshot of keyed metadata. */ /**
* Interface for an immutable snapshot of keyed metadata.
*
* <p>Internal metadata names are prefixed with {@value #INTERNAL_METADATA_NAME_PREFIX}. Custom
* metadata names should avoid this prefix to prevent clashes.
*/
public interface ContentMetadata { public interface ContentMetadata {
/** Prefix of internal metadata names. */
String INTERNAL_METADATA_NAME_PREFIX = "exo_";
/** Name of internal metadata to hold redirected URI. */
String METADATA_NAME_REDIRECTED_URI = INTERNAL_METADATA_NAME_PREFIX + "redir";
/** Name of internal metadata to hold content length. */
String METADATA_NAME_LENGTH = INTERNAL_METADATA_NAME_PREFIX + "len";
/** /**
* Returns a metadata value. * Returns a metadata value.
* *
......
...@@ -63,19 +63,23 @@ public final class DefaultContentMetadata implements ContentMetadata { ...@@ -63,19 +63,23 @@ public final class DefaultContentMetadata implements ContentMetadata {
private final Map<String, byte[]> metadata; private final Map<String, byte[]> metadata;
/**
* Constructs a {@link DefaultContentMetadata} by copying metadata values from {@code other} and
* applying {@code mutations}.
*/
public DefaultContentMetadata(DefaultContentMetadata other, ContentMetadataMutations mutations) {
this(applyMutations(other.metadata, mutations));
}
private DefaultContentMetadata(Map<String, byte[]> metadata) { private DefaultContentMetadata(Map<String, byte[]> metadata) {
this.metadata = Collections.unmodifiableMap(metadata); this.metadata = Collections.unmodifiableMap(metadata);
} }
/** /**
* Returns a copy {@link DefaultContentMetadata} with {@code mutations} applied. If {@code
* mutations} don't change anything, returns this instance.
*/
public DefaultContentMetadata copyWithMutationsApplied(ContentMetadataMutations mutations) {
Map<String, byte[]> mutatedMetadata = applyMutations(metadata, mutations);
if (isMetadataEqual(mutatedMetadata)) {
return this;
}
return new DefaultContentMetadata(mutatedMetadata);
}
/**
* Serializes itself to a {@link DataOutputStream}. * Serializes itself to a {@link DataOutputStream}.
* *
* @param output Output stream to store the values. * @param output Output stream to store the values.
...@@ -134,8 +138,10 @@ public final class DefaultContentMetadata implements ContentMetadata { ...@@ -134,8 +138,10 @@ public final class DefaultContentMetadata implements ContentMetadata {
if (o == null || getClass() != o.getClass()) { if (o == null || getClass() != o.getClass()) {
return false; return false;
} }
DefaultContentMetadata that = (DefaultContentMetadata) o; return isMetadataEqual(((DefaultContentMetadata) o).metadata);
Map<String, byte[]> otherMetadata = that.metadata; }
private boolean isMetadataEqual(Map<String, byte[]> otherMetadata) {
if (metadata.size() != otherMetadata.size()) { if (metadata.size() != otherMetadata.size()) {
return false; return false;
} }
......
...@@ -309,6 +309,18 @@ public final class SimpleCache implements Cache { ...@@ -309,6 +309,18 @@ public final class SimpleCache implements Cache {
return index.getContentLength(key); return index.getContentLength(key);
} }
@Override
public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations)
throws CacheException {
index.applyContentMetadataMutations(key, mutations);
index.store();
}
@Override
public ContentMetadata getContentMetadata(String key) {
return index.getContentMetadata(key);
}
/** /**
* Returns the cache {@link SimpleCacheSpan} corresponding to the provided lookup {@link * Returns the cache {@link SimpleCacheSpan} corresponding to the provided lookup {@link
* SimpleCacheSpan}. * SimpleCacheSpan}.
...@@ -458,15 +470,4 @@ public final class SimpleCache implements Cache { ...@@ -458,15 +470,4 @@ public final class SimpleCache implements Cache {
private static synchronized void releaseFolder(File cacheDir) { private static synchronized void releaseFolder(File cacheDir) {
lockedCacheDirs.remove(cacheDir.getAbsoluteFile()); lockedCacheDirs.remove(cacheDir.getAbsoluteFile());
} }
@Override
public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations)
throws CacheException {
index.applyContentMetadataMutations(key, mutations);
index.store();
}
@Override
public ContentMetadata getContentMetadata(String key) {
return index.getContentMetadata(key);
}
} }
...@@ -62,14 +62,14 @@ public class DefaultContentMetadataTest { ...@@ -62,14 +62,14 @@ public class DefaultContentMetadataTest {
@Test @Test
public void testEmptyMutationDoesNotFail() throws Exception { public void testEmptyMutationDoesNotFail() throws Exception {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
new DefaultContentMetadata(DefaultContentMetadata.EMPTY, mutations); DefaultContentMetadata.EMPTY.copyWithMutationsApplied(mutations);
} }
@Test @Test
public void testAddNewMetadata() throws Exception { public void testAddNewMetadata() throws Exception {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.set("metadata name", "value"); mutations.set("metadata name", "value");
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("value"); assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("value");
} }
...@@ -77,7 +77,7 @@ public class DefaultContentMetadataTest { ...@@ -77,7 +77,7 @@ public class DefaultContentMetadataTest {
public void testAddNewIntMetadata() throws Exception { public void testAddNewIntMetadata() throws Exception {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.set("metadata name", 5); mutations.set("metadata name", 5);
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", 0)).isEqualTo(5); assertThat(contentMetadata.get("metadata name", 0)).isEqualTo(5);
} }
...@@ -86,7 +86,7 @@ public class DefaultContentMetadataTest { ...@@ -86,7 +86,7 @@ public class DefaultContentMetadataTest {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
byte[] value = {1, 2, 3}; byte[] value = {1, 2, 3};
mutations.set("metadata name", value); mutations.set("metadata name", value);
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", new byte[] {})).isEqualTo(value); assertThat(contentMetadata.get("metadata name", new byte[] {})).isEqualTo(value);
} }
...@@ -102,7 +102,7 @@ public class DefaultContentMetadataTest { ...@@ -102,7 +102,7 @@ public class DefaultContentMetadataTest {
contentMetadata = createContentMetadata("metadata name", "value"); contentMetadata = createContentMetadata("metadata name", "value");
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.set("metadata name", "edited value"); mutations.set("metadata name", "edited value");
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("edited value"); assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("edited value");
} }
...@@ -111,7 +111,7 @@ public class DefaultContentMetadataTest { ...@@ -111,7 +111,7 @@ public class DefaultContentMetadataTest {
contentMetadata = createContentMetadata("metadata name", "value"); contentMetadata = createContentMetadata("metadata name", "value");
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.remove("metadata name"); mutations.remove("metadata name");
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("default value"); assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("default value");
} }
...@@ -120,7 +120,7 @@ public class DefaultContentMetadataTest { ...@@ -120,7 +120,7 @@ public class DefaultContentMetadataTest {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.set("metadata name", "value"); mutations.set("metadata name", "value");
mutations.remove("metadata name"); mutations.remove("metadata name");
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("default value"); assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("default value");
} }
...@@ -129,7 +129,7 @@ public class DefaultContentMetadataTest { ...@@ -129,7 +129,7 @@ public class DefaultContentMetadataTest {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
mutations.remove("metadata name"); mutations.remove("metadata name");
mutations.set("metadata name", "value"); mutations.set("metadata name", "value");
contentMetadata = new DefaultContentMetadata(contentMetadata, mutations); contentMetadata = contentMetadata.copyWithMutationsApplied(mutations);
assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("value"); assertThat(contentMetadata.get("metadata name", "default value")).isEqualTo("value");
} }
...@@ -194,6 +194,6 @@ public class DefaultContentMetadataTest { ...@@ -194,6 +194,6 @@ public class DefaultContentMetadataTest {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
return new DefaultContentMetadata(DefaultContentMetadata.EMPTY, mutations); return DefaultContentMetadata.EMPTY.copyWithMutationsApplied(mutations);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment