use of org.trellisldp.vocabulary.Trellis.PreferUserManaged in project trellis by trellis-ldp.
the class TriplestoreResourceService method buildUpdateRequest.
/**
* This is equivalent to the SPARQL below.
*
* <p><pre><code>
* DELETE WHERE { GRAPH IDENTIFIER { ?s ?p ?o } };
* DELETE WHERE { GRAPH IDENTIFIER?ext=acl { ?s ?p ?o } };
* DELETE WHERE { GRAPH trellis:PreferServerManaged {
* IDENTIFIER a ldp:NonRDFSource .
* IDENTIFIER dc:hasPart ?s .
* ?s ?p ?o .
* };
* DELETE WHERE { GRAPH trellis:PreferServerManaged { IDENTIFIER ?p ?o } };
* INSERT DATA {
* GRAPH IDENTIFIER { ... }
* GRAPH IDENTIFIER?ext=acl { ... }
* GRAPH trellis:PreferServerManaged { ... }
* GRAPH IDENTIFIER?ext=audit { ... }
* }
* </code></pre></p>
*/
private UpdateRequest buildUpdateRequest(final IRI identifier, final Literal time, final Dataset dataset, final OperationType operation) {
// Set the time
dataset.add(PreferServerManaged, identifier, DC.modified, time);
final UpdateRequest req = new UpdateRequest();
req.add(new UpdateDeleteWhere(new QuadAcc(singletonList(new Quad(toJena(identifier), SUBJECT, PREDICATE, OBJECT)))));
extensions.forEach((ext, graph) -> req.add(new UpdateDeleteWhere(new QuadAcc(singletonList(new Quad(getExtIRI(identifier, ext), SUBJECT, PREDICATE, OBJECT))))));
req.add(new UpdateDeleteWhere(new QuadAcc(asList(new Quad(toJena(PreferServerManaged), toJena(identifier), toJena(type), toJena(LDP.NonRDFSource)), new Quad(toJena(PreferServerManaged), toJena(identifier), toJena(DC.hasPart), SUBJECT), new Quad(toJena(PreferServerManaged), SUBJECT, PREDICATE, OBJECT)))));
req.add(new UpdateDeleteWhere(new QuadAcc(singletonList(new Quad(toJena(PreferServerManaged), toJena(identifier), PREDICATE, OBJECT)))));
final QuadDataAcc sink = new QuadDataAcc(synchronizedList(new ArrayList<>()));
if (operation == OperationType.DELETE) {
dataset.stream().filter(q -> q.getGraphName().filter(PreferServerManaged::equals).isPresent()).map(JenaCommonsRDF::toJena).forEach(sink::addQuad);
} else {
dataset.stream().filter(q -> q.getGraphName().filter(PreferServerManaged::equals).isPresent()).map(JenaCommonsRDF::toJena).forEach(sink::addQuad);
dataset.getGraph(PreferUserManaged).ifPresent(g -> g.stream().map(t -> new Quad(toJena(identifier), toJena(t))).forEach(sink::addQuad));
dataset.getGraph(PreferAudit).ifPresent(g -> g.stream().map(t -> new Quad(getExtIRI(identifier, "audit"), toJena(t))).forEach(sink::addQuad));
extensions.forEach((ext, graph) -> dataset.getGraph(graph).ifPresent(g -> g.stream().map(t -> new Quad(getExtIRI(identifier, ext), toJena(t))).forEach(sink::addQuad)));
}
req.add(new UpdateDataInsert(sink));
return req;
}
use of org.trellisldp.vocabulary.Trellis.PreferUserManaged in project trellis by trellis-ldp.
the class PutHandler method handleResourceUpdate.
private CompletionStage<ResponseBuilder> handleResourceUpdate(final Dataset mutable, final Dataset immutable, final ResponseBuilder builder, final IRI ldpType) {
final Metadata.Builder metadata;
final BinaryMetadata binary;
// Add user-supplied data
if (LDP.NonRDFSource.equals(ldpType) && rdfSyntax == null) {
LOGGER.trace("Successfully checked for bad digest value");
final String mimeType = getRequest().getContentType() != null ? getRequest().getContentType() : APPLICATION_OCTET_STREAM;
final IRI binaryLocation = rdf.createIRI(getServices().getBinaryService().generateIdentifier(internalId));
binary = BinaryMetadata.builder(binaryLocation).mimeType(mimeType).hints(getRequest().getHeaders()).build();
metadata = metadataBuilder(internalId, ldpType, mutable).binary(binary);
builder.link(getIdentifier() + "?ext=description", "describedby");
} else {
final RDFSyntax s = rdfSyntax != null ? rdfSyntax : TURTLE;
final IRI ext = getExtensionGraphName();
final IRI graphName = ext != null ? ext : PreferUserManaged;
readEntityIntoDataset(graphName, s, mutable);
// Check the mutable dataset for any constraints
checkConstraints(mutable, ldpType, s);
metadata = metadataBuilder(internalId, ldpType, mutable);
if (getResource() != null) {
getResource().getBinaryMetadata().ifPresent(metadata::binary);
}
binary = null;
}
if (getResource() != null) {
getResource().getContainer().ifPresent(metadata::container);
metadata.revision(getResource().getRevision());
LOGGER.debug("Resource {} found in persistence", getIdentifier());
try (final Stream<Quad> remaining = getResource().stream(getNonCurrentGraphNames())) {
remaining.forEachOrdered(mutable::add);
}
} else if (!createUncontained) {
getContainer(internalId).ifPresent(metadata::container);
}
getAuditQuadData().forEachOrdered(immutable::add);
LOGGER.trace("Successfully calculated and skolemized immutable data");
ldpResourceTypes(effectiveLdpType(ldpType)).map(IRI::getIRIString).forEach(type -> {
LOGGER.trace("Adding link for type {}", type);
builder.link(type, Link.TYPE);
});
LOGGER.trace("Persisting mutable data for {} with data: {}", internalId, mutable);
final Metadata m = metadata.build();
return createOrReplace(m, mutable, immutable).thenCompose(future -> persistBinaryContent(binary)).thenCompose(future -> handleUpdateNotification(ldpType, m.getRevision().orElse(null))).thenApply(future -> decorateResponse(builder));
}
use of org.trellisldp.vocabulary.Trellis.PreferUserManaged in project trellis by trellis-ldp.
the class PatchHandler method assembleResponse.
private CompletionStage<ResponseBuilder> assembleResponse(final Dataset mutable, final Dataset immutable, final ResponseBuilder builder) {
final IRI ext = getExtensionGraphName();
final IRI graphName = ext != null ? ext : PreferUserManaged;
// Put triples in buffer, short-circuit on exception
final List<Triple> triples;
try {
triples = updateGraph(syntax, graphName);
} catch (final TrellisRuntimeException ex) {
throw new BadRequestException("Invalid RDF: " + ex.getMessage(), ex);
}
triples.stream().map(skolemizeTriples(getServices().getResourceService(), getBaseUrl())).map(triple -> rdf.createQuad(graphName, triple.getSubject(), triple.getPredicate(), triple.getObject())).forEachOrdered(mutable::add);
// Check any constraints on the resulting dataset
final List<ConstraintViolation> violations = new ArrayList<>();
getServices().getConstraintServices().forEach(svc -> handleConstraintViolation(svc, getInternalId(), mutable, graphName, getLdpType()).forEach(violations::add));
// Short-ciruit if there is a constraint violation
if (!violations.isEmpty()) {
final ResponseBuilder err = status(CONFLICT);
violations.forEach(v -> err.link(v.getConstraint().getIRIString(), LDP.constrainedBy.getIRIString()));
throw new ClientErrorException(err.entity((StreamingOutput) out -> getServices().getIOService().write(violations.stream().flatMap(v2 -> v2.getTriples().stream()), out, RDFSyntax.TURTLE, getIdentifier())).type(RDFSyntax.TURTLE.mediaType()).build());
}
// When updating one particular graph, be sure to add the other category to the dataset
if (getResource() != null) {
try (final Stream<Quad> remaining = getResource().stream(getNonCurrentGraphNames())) {
remaining.forEachOrdered(mutable::add);
}
}
// Collect the audit data
getAuditQuadData().forEachOrdered(immutable::add);
final Metadata metadata;
if (getResource() == null) {
metadata = metadataBuilder(getInternalId(), LDP.RDFSource, mutable).container(TrellisUtils.getContainer(getInternalId()).orElse(null)).build();
} else {
final Metadata.Builder mbuilder = metadataBuilder(getResource().getIdentifier(), getResource().getInteractionModel(), mutable);
getResource().getContainer().ifPresent(mbuilder::container);
getResource().getBinaryMetadata().ifPresent(mbuilder::binary);
mbuilder.revision(getResource().getRevision());
metadata = mbuilder.build();
}
return createOrReplace(metadata, mutable, immutable).thenCompose(future -> emitNotification(metadata.getIdentifier(), getResource() == null ? AS.Create : AS.Update, getLdpType(), metadata.getRevision().orElse(null))).thenApply(future -> {
final RDFSyntax outputSyntax = getSyntax(getServices().getIOService(), getRequest().getAcceptableMediaTypes(), null);
if (preference != null) {
final IRI profile = getResponseProfile(outputSyntax);
return builder.header(PREFERENCE_APPLIED, "return=representation").type(outputSyntax.mediaType()).entity((StreamingOutput) out -> getServices().getIOService().write(triples.stream().map(unskolemizeTriples(getServices().getResourceService(), getBaseUrl())), out, outputSyntax, getIdentifier(), profile));
}
return builder.status(getResource() == null ? CREATED : NO_CONTENT);
});
}
use of org.trellisldp.vocabulary.Trellis.PreferUserManaged in project trellis by trellis-ldp.
the class TrellisWebDAV method resourceToMultiStatus.
private Function<Resource, CompletionStage<DavMultiStatus>> resourceToMultiStatus(final Document doc, final IRI identifier, final String location, final String baseUrl, final Session session, final DavPropertyUpdate propertyUpdate) {
return resource -> {
final Dataset dataset = rdf.createDataset();
final Set<IRI> removeProperties = getRemoveProperties(propertyUpdate);
final DavMultiStatus multistatus = new DavMultiStatus();
final DavResponse response = new DavResponse();
final Set<IRI> modifiedProperties = new HashSet<>();
response.setHref(location);
// Keep any extension data
try (final Stream<Quad> stream = resource.stream(extensions.values())) {
stream.forEach(dataset::add);
}
// Filter out any removable properties
try (final Stream<Quad> stream = resource.stream(PreferUserManaged)) {
stream.forEach(quad -> {
if (removeProperties.contains(quad.getPredicate())) {
modifiedProperties.add(quad.getPredicate());
} else {
dataset.add(rdf.createQuad(PreferUserManaged, identifier, quad.getPredicate(), quad.getObject()));
}
});
}
final DavSet set = propertyUpdate.getSet();
if (set != null) {
final DavProp prop = set.getProp();
if (prop != null) {
Optional.ofNullable(prop.getNodes()).ifPresent(nodes -> nodes.stream().flatMap(elementToQuads(identifier)).forEach(quad -> {
modifiedProperties.add(quad.getPredicate());
dataset.add(quad);
}));
}
}
response.setPropStats(modifiedProperties.stream().map(predicate -> {
final DavPropStat stat = new DavPropStat();
final DavProp prop = new DavProp();
prop.setNodes(List.of(doc.createElementNS(namespaceXML(predicate.getIRIString()), localnameXML(predicate.getIRIString()))));
stat.setProp(prop);
stat.setStatus(SUCCESS);
return stat;
}).collect(toList()));
multistatus.setDescription("Response to property update request");
multistatus.setResponses(List.of(response));
final Dataset immutable = rdf.createDataset();
services.getAuditService().creation(resource.getIdentifier(), session).stream().map(skolemizeQuads(services.getResourceService(), baseUrl)).forEachOrdered(immutable::add);
return services.getResourceService().replace(Metadata.builder(resource).build(), dataset).whenComplete((a, b) -> closeDataset(dataset)).thenCompose(future -> services.getResourceService().add(resource.getIdentifier(), immutable)).whenComplete((a, b) -> closeDataset(immutable)).thenCompose(future -> services.getMementoService().put(services.getResourceService(), resource.getIdentifier())).thenRun(() -> services.getNotificationService().emit(new SimpleNotification(location, session.getAgent(), List.of(PROV.Activity, AS.Update), List.of(resource.getInteractionModel()), null))).thenApply(future -> multistatus);
};
}
use of org.trellisldp.vocabulary.Trellis.PreferUserManaged in project trellis by trellis-ldp.
the class PostHandler method handleResourceCreation.
private CompletionStage<ResponseBuilder> handleResourceCreation(final Dataset mutable, final Dataset immutable, final ResponseBuilder builder) {
final Metadata metadata;
final BinaryMetadata binary;
// Add user-supplied data
if (ldpType.equals(LDP.NonRDFSource)) {
final String mimeType = contentType != null ? contentType : APPLICATION_OCTET_STREAM;
final IRI binaryLocation = rdf.createIRI(getServices().getBinaryService().generateIdentifier(internalId));
// Persist the content
binary = BinaryMetadata.builder(binaryLocation).mimeType(mimeType).hints(getRequest().getHeaders()).build();
metadata = metadataBuilder(internalId, ldpType, mutable).container(parentIdentifier).binary(binary).build();
builder.link(getIdentifier() + "?ext=description", "describedby");
} else {
final RDFSyntax s = rdfSyntax != null ? rdfSyntax : TURTLE;
readEntityIntoDataset(PreferUserManaged, s, mutable);
// Check for any constraints
mutable.getGraph(PreferUserManaged).ifPresent(graph -> checkConstraint(graph, ldpType, s));
metadata = metadataBuilder(internalId, ldpType, mutable).container(parentIdentifier).build();
binary = null;
}
getAuditQuadData().forEachOrdered(immutable::add);
return handleResourceCreation(metadata, mutable, immutable).thenCompose(future -> persistBinaryContent(binary)).thenCompose(future -> emitNotification(internalId, AS.Create, ldpType, null)).thenApply(future -> {
ldpResourceTypes(ldpType).map(IRI::getIRIString).forEach(type -> builder.link(type, Link.TYPE));
return builder.location(UriBuilder.fromUri(getIdentifier()).build());
});
}
Aggregations