BdioMetadata extends BdioObject { public BdioMetadata merge(Map<String, Object> other) { if (other instanceof BdioMetadata) { throwable = ExtraOptionals.merge(throwable, ((BdioMetadata) other).throwable, (a, b) -> { a.addSuppressed(b); return a; }); } other.forEach((key, value) -> { if (key.equals(JsonLdConsts.ID)) { checkArgument(value instanceof String, "identifier must be mapped to a string"); if (id() == null) { id((String) value); } else if (ExtraStrings.beforeLast((String) value, '#').equals(id())) { if (!value.equals(get(JsonLdConsts.ID))) { id(ExtraStrings.beforeLast((String) value, '#')); } } else { throw new IllegalArgumentException("identifier mismatch: " + value + " (was expecting " + id() + ")"); } } else if (key.equals(Bdio.DataProperty.publisher.toString())) { Object publisher = get(key); if (publisher != null) { ProductList.Builder builder = new ProductList.Builder(); ProductList.from(fromFieldValue(key, publisher)).forEach(builder::mergeProduct); ProductList.from(fromFieldValue(key, value)).forEach(builder::mergeProduct); putFieldValue(Bdio.DataProperty.publisher, builder.build()); } else { put(key, value); } } else if (key.equals(Bdio.DataProperty.creator.toString())) { Object creator = get(key); if (creator != null) { put(key, splitOnFirst(fromFieldValue(key, creator).toString(), '@', (user1, host1) -> splitOnFirst(fromFieldValue(key, value).toString(), '@', (user2, host2) -> { return ensureDelimiter(isNullOrEmpty(user1) ? user2 : user1, "@", isNullOrEmpty(host1) ? host2 : host1); }))); } else { put(key, value); } } else { put(key, value); } }); return this; } BdioMetadata();  BdioMetadata(Map<String, Object> other);  BdioMetadata(Throwable error); static BdioMetadata createRandomUUID(); Optional<Throwable> getThrowable(); Map<String, Object> asNamedGraph(Object graph, String... keys); Map<String, Object> asNamedGraph(); BdioMetadata merge(Map<String, Object> other); BdioMetadata id(@Nullable String id); BdioMetadata name(@Nullable String name); BdioMetadata captureOptions(@Nullable List<String> captureOptions); BdioMetadata captureInterval(@Nullable String captureInterval); BdioMetadata captureInterval(@Nullable ZonedDateTime start, @Nullable ZonedDateTime end); BdioMetadata creationDateTime(@Nullable ZonedDateTime creation); BdioMetadata creator(@Nullable String creator); BdioMetadata creator(@Nullable String user, @Nullable String host); BdioMetadata platform(@Nullable ProductList platform); BdioMetadata publisher(@Nullable ProductList publisher); BdioMetadata buildDetails(@Nullable String buildDetails); BdioMetadata buildNumber(@Nullable String buildNumber); BdioMetadata sourceRepository(@Nullable String sourceRepository); BdioMetadata sourceRevision(@Nullable String sourceRevision); BdioMetadata sourceBranch(@Nullable String sourceBranch); BdioMetadata sourceTag(@Nullable String sourceTag);  }
@Test public void mergeMetadataOverwrite() { BdioMetadata metadata = new BdioMetadata(); metadata.put("test1", "foo"); metadata.merge(ImmutableMap.of("test1", "bar")); assertThat(metadata).containsExactly("test1", "bar"); }