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
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
RepresentationPatchHandler calls the source
to get a data stream representing the current state of the resource.
It feeds that stream as input into a
and then writes the result back to the store.
Similarly to the way accessing resources is done through a stack of
patching is done through a stack of
each performing a step in the patching process.
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
so the next patchers do not have to worry about handling stream data
and have access to the entire resource in memory.
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.
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.