Skip to content

Make Metadata class more extensible #1085

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions core/api/src/main/java/org/trellisldp/api/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
package org.trellisldp.api;

import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableMap;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand All @@ -36,9 +39,11 @@ public final class Metadata {
private final IRI membershipResource;
private final IRI memberOfRelation;
private final IRI insertedContentRelation;
private final IRI agent;
private final BinaryMetadata binary;
private final Set<IRI> graphNames;
private final String revision;
private final Map<String, String> properties;

/**
* A Metadata-bearing data structure for use with resource manipulation.
Expand All @@ -50,26 +55,31 @@ public final class Metadata {
* @param memberRelation an LDP hasMemberRelation predicate, may be {@code null}
* @param memberOfRelation an LDP isMemberOfRelation predicate, may be {@code null}
* @param insertedContentRelation an LDP insertedContentRelation, may be {@code null}
* @param agent the agent associated with the operation, may be {@code null}
* @param binary metadata about a BinaryMetadata, may be {@code null}
* @param revision a revision value, may be {@code null}. This value may be used by a
* {@link ResourceService} implementation for additional concurrency control.
* This value would typically be used in tandem with the {@link Resource#getRevision}
* method.
* @param graphNames a collection of metadata graphNames
* @param properties a collection of additional properties
*/
private Metadata(final IRI identifier, final IRI ixnModel, final IRI container, final IRI membershipResource,
final IRI memberRelation, final IRI memberOfRelation, final IRI insertedContentRelation,
final BinaryMetadata binary, final String revision, final Set<IRI> graphNames) {
final IRI memberRelation, final IRI memberOfRelation, final IRI insertedContentRelation, final IRI agent,
final BinaryMetadata binary, final String revision, final Set<IRI> graphNames,
final Map<String, String> properties) {
this.identifier = requireNonNull(identifier, "Identifier cannot be null!");
this.ixnModel = requireNonNull(ixnModel, "Interaction model cannot be null!");
this.container = container;
this.membershipResource = membershipResource;
this.memberRelation = memberRelation;
this.memberOfRelation = memberOfRelation;
this.insertedContentRelation = insertedContentRelation;
this.agent = agent;
this.binary = binary;
this.revision = revision;
this.graphNames = graphNames;
this.properties = properties;
}

/**
Expand Down Expand Up @@ -129,6 +139,14 @@ public Optional<IRI> getContainer() {
return ofNullable(container);
}

/**
* Retrieve the agent associated with this opertation, if known.
* @return the agent identified with a WebID
*/
public Optional<IRI> getAgent() {
return ofNullable(agent);
}

/**
* Retrieve the membership resource if this is an LDP Direct or Indirect container.
*
Expand Down Expand Up @@ -194,6 +212,14 @@ public Optional<String> getRevision() {
return ofNullable(revision);
}

/**
* Retrieve any additional properties.
* @return an immutable collection of properties
*/
public Map<String, String> getProperties() {
return properties;
}

/**
* A mutable builder for a {@link Metadata} object.
*/
Expand All @@ -205,9 +231,11 @@ public static final class Builder {
private IRI membershipResource;
private IRI memberOfRelation;
private IRI insertedContentRelation;
private IRI agent;
private BinaryMetadata binary;
private String revision;
private Set<IRI> graphNames = emptySet();
private Map<String, String> properties = new HashMap<>();

/**
* Create a Metadata builder with the provided identifier.
Expand Down Expand Up @@ -277,6 +305,16 @@ public Builder insertedContentRelation(final IRI insertedContentRelation) {
return this;
}

/**
* Set the agent value.
* @param agent the agent associated with the operation
* @return this builder
*/
public Builder agent(final IRI agent) {
this.agent = agent;
return this;
}

/**
* Set the binary metadata.
* @param binary the binary metadata
Expand Down Expand Up @@ -307,13 +345,24 @@ public Builder revision(final String revision) {
return this;
}

/**
* Set a property on the resource metadata.
* @param key the property key
* @param value the property value
* @return this builder
*/
public Builder property(final String key, final String value) {
this.properties.put(key, value);
return this;
}

/**
* Build the Metadata object, transitioning this builder to the built state.
* @return the built Metadata
*/
public Metadata build() {
return new Metadata(identifier, ixnModel, container, membershipResource, memberRelation, memberOfRelation,
insertedContentRelation, binary, revision, graphNames);
insertedContentRelation, agent, binary, revision, graphNames, unmodifiableMap(properties));
}
}
}
6 changes: 6 additions & 0 deletions core/api/src/test/java/org/trellisldp/api/MetadataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class MetadataTest {
private static final IRI identifier = rdf.createIRI("trellis:data/resource");
private static final IRI member = rdf.createIRI("trellis:data/member");
private static final IRI root = rdf.createIRI("trellis:data/");
private static final IRI agent = rdf.createIRI("https://example.com/agent#i");

@Test
void testMetadataIndirectContainer() {
Expand All @@ -44,6 +45,7 @@ void testMetadataIndirectContainer() {
.container(root).memberRelation(LDP.member)
.membershipResource(member)
.insertedContentRelation(FOAF.primaryTopic)
.property("key", "value")
.revision("blahblahblah").build();
assertEquals(identifier, metadata.getIdentifier());
assertEquals(LDP.IndirectContainer, metadata.getInteractionModel());
Expand All @@ -54,20 +56,24 @@ void testMetadataIndirectContainer() {
assertFalse(metadata.getMemberOfRelation().isPresent());
assertTrue(metadata.getMetadataGraphNames().isEmpty());
assertFalse(metadata.getBinary().isPresent());
assertFalse(metadata.getAgent().isPresent());
assertEquals(of("blahblahblah"), metadata.getRevision());
assertEquals("value", metadata.getProperties().get("key"));
}

@Test
void testMetadataDirectContainer() {
final Metadata metadata = Metadata.builder(identifier)
.interactionModel(LDP.DirectContainer)
.agent(agent)
.container(root).memberOfRelation(DC.isPartOf)
.membershipResource(member).metadataGraphNames(singleton(Trellis.PreferAccessControl)).build();
assertEquals(identifier, metadata.getIdentifier());
assertEquals(LDP.DirectContainer, metadata.getInteractionModel());
assertEquals(of(root), metadata.getContainer());
assertEquals(of(member), metadata.getMembershipResource());
assertEquals(of(DC.isPartOf), metadata.getMemberOfRelation());
assertEquals(of(agent), metadata.getAgent());
assertFalse(metadata.getInsertedContentRelation().isPresent());
assertFalse(metadata.getMemberRelation().isPresent());
assertFalse(metadata.getBinary().isPresent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ protected CompletionStage<Void> persistBinaryContent(final BinaryMetadata metada
}

protected Metadata.Builder metadataBuilder(final IRI identifier, final IRI ixnModel, final Dataset mutable) {
final Metadata.Builder builder = Metadata.builder(identifier).interactionModel(ixnModel);
final Metadata.Builder builder = Metadata.builder(identifier).interactionModel(ixnModel)
.agent(getSession().getAgent());
mutable.getGraph(Trellis.PreferUserManaged).ifPresent(graph -> {
graph.stream(null, LDP.membershipResource, null)
.filter(triple -> matchIdentifier(triple.getSubject(), identifier)).findFirst().map(Triple::getObject)
Expand Down