Modifying resources¶
As described here, there is a generic solution for modifying resources as a result of PATCH requests. It consists of doing the following steps:
- Convert the stored resource to a stream of quad objects (a/k/a, a quad stream).
- Read the quad stream and ingest the quads into an N3.js Store.
- If the target resource is metadata, ensure that the immutable triples don't get changed.
- Apply the patch to the quad store.
- Convert the quad store to a quad stream.
- Convert the quad stream back to the original media type of the resource.
The architecture is described more in-depth below.
flowchart LR
PatchingStore("<strong>ResourceStore_Patching</strong><br>ResourceStore")
PatchingStore --> PatchHandler("<strong>PatchHandler</strong><br>RepresentationPatchHandler")
PatchHandler --> Patchers("<br>WaterfallHandler")
Patchers --> ConvertingPatcher("<br>ConvertingPatcher")
ConvertingPatcher --> RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher")
flowchart LR
RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher")
RdfPatcher --> RDFStore("<strong>PatchHandler_RDFStore</strong><br>WaterfallHandler")
RDFStore --> RDFStoreArgs
subgraph RDFStoreArgs[" "]
Immutable("<strong>PatchHandler_ImmutableMetadata</strong><br>ImmutableMetadataPatcher")
RDF("<strong>PatchHandler_RDF</strong><br>WaterfallHandler")
Immutable --> RDF
end
RDF --> RDFArgs
subgraph RDFArgs[" "]
direction LR
N3("<br>N3Patcher")
SPARQL("<br>SparqlUpdatePatcher")
end
The PatchingStore
is the entry point.
It first checks whether the next store supports modifying resources.
Only if this is not the case will it start the generic patching solution by calling its PatchHandler
.
The RepresentationPatchHandler
calls the source ResourceStore
to get a data stream representing the current state of the resource.
It feeds that stream as input into a RepresentationPatcher
,
and then writes the result back to the store.
Similarly to the way accessing resources is done through a stack of ResourceStore
s,
patching is done through a stack of RepresentationPatcher
s,
each performing a step in the patching process.
The ConvertingPatcher
is responsible for converting the original resource to a stream of quad objects,
and converting the modified result back to the original type.
By converting to quads, all other relevant classes can act independently of the actual RDF serialization type.
For similar reasons, the RdfPatcher
converts the quad stream to an N3.js
Store
so the next patchers do not have to worry about handling stream data
and have access to the entire resource in memory.
The ImmutableMetadataPatcher
keeps track of a list of triples that cannot be modified
in the metadata of a resource.
For example, it is not possible to modify the metadata to indicate whether it is
a storage root.
The ImmutableMetadataPatcher
tracks all these triples before and after a metadata resource is modified,
and throws an error if one is modified.
If the target resource is not metadata but a standard resource, this class will be skipped.
Finally, either the N3Patcher
or the SparqlUpdatePatcher
will be called,
depending on the type of patch that is requested.