Skip to content

Commit ba7080e

Browse files
committed
PATCH gets sent from settings form
1 parent 35c5fca commit ba7080e

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

src/main/java/com/atomgraph/linkeddatahub/resource/Settings.java

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@
1616
*/
1717
package com.atomgraph.linkeddatahub.resource;
1818

19+
import com.atomgraph.core.util.ModelUtils;
1920
import com.atomgraph.linkeddatahub.apps.model.Application;
21+
import com.atomgraph.linkeddatahub.server.io.ValidatingModelProvider;
2022
import jakarta.inject.Inject;
2123
import jakarta.ws.rs.BadRequestException;
2224
import jakarta.ws.rs.GET;
25+
import jakarta.ws.rs.InternalServerErrorException;
2326
import jakarta.ws.rs.NotFoundException;
2427
import jakarta.ws.rs.PATCH;
28+
import jakarta.ws.rs.core.Context;
29+
import jakarta.ws.rs.core.EntityTag;
30+
import jakarta.ws.rs.core.Request;
2531
import jakarta.ws.rs.core.Response;
32+
import jakarta.ws.rs.ext.MessageBodyReader;
33+
import jakarta.ws.rs.ext.Providers;
2634
import java.io.IOException;
2735
import org.apache.jena.query.Dataset;
2836
import org.apache.jena.query.DatasetFactory;
@@ -44,18 +52,24 @@ public class Settings
4452

4553
private final Application application;
4654
private final com.atomgraph.linkeddatahub.Application system;
55+
private final Providers providers;
56+
private final Request request;
4757

4858
/**
4959
* Constructs the Settings endpoint.
5060
*
5161
* @param application the current dataspace application
5262
* @param system the system application
63+
* @param providers JAX-RS provider registry
64+
* @param request JAX-RS request context
5365
*/
5466
@Inject
55-
public Settings(Application application, com.atomgraph.linkeddatahub.Application system)
67+
public Settings(Application application, com.atomgraph.linkeddatahub.Application system, @Context Providers providers, @Context Request request)
5668
{
5769
this.application = application;
5870
this.system = system;
71+
this.providers = providers;
72+
this.request = request;
5973
}
6074

6175
/**
@@ -76,7 +90,13 @@ public Response get()
7690

7791
if (log.isDebugEnabled()) log.debug("Retrieved settings for dataspace <{}>", getApplication().getURI());
7892

79-
return Response.ok(dataspaceModel).build();
93+
EntityTag entityTag = getEntityTag(dataspaceModel);
94+
Response.ResponseBuilder rb = getRequest().evaluatePreconditions(entityTag);
95+
if (rb != null) return rb.build();
96+
97+
return Response.ok(dataspaceModel).
98+
tag(entityTag).
99+
build();
80100
}
81101

82102
/**
@@ -103,6 +123,16 @@ public Response patch(UpdateRequest updateRequest) throws IOException
103123
Dataset dataset = DatasetFactory.wrap(dataspaceModel);
104124
UpdateAction.execute(updateRequest, dataset);
105125

126+
// if PATCH results in an empty model, reject it as Bad Request
127+
if (dataspaceModel.isEmpty())
128+
{
129+
if (log.isWarnEnabled()) log.warn("PATCH resulted in empty dataspace model for <{}>", getApplication().getURI());
130+
throw new BadRequestException("PATCH cannot result in empty dataspace model");
131+
}
132+
133+
// validate the updated model
134+
validate(dataspaceModel);
135+
106136
// Write the updated model back to the context dataset file
107137
getSystem().updateDataspace(getApplication(), dataspaceModel);
108138

@@ -131,4 +161,49 @@ public com.atomgraph.linkeddatahub.Application getSystem()
131161
return system;
132162
}
133163

164+
/**
165+
* Returns the JAX-RS providers registry.
166+
*
167+
* @return the providers
168+
*/
169+
public Providers getProviders()
170+
{
171+
return providers;
172+
}
173+
174+
/**
175+
* Validates model against SPIN and SHACL constraints.
176+
*
177+
* @param model RDF model
178+
* @return validated model
179+
*/
180+
public Model validate(Model model)
181+
{
182+
MessageBodyReader<Model> reader = getProviders().getMessageBodyReader(Model.class, null, null, com.atomgraph.core.MediaType.APPLICATION_NTRIPLES_TYPE);
183+
if (reader instanceof ValidatingModelProvider validatingModelProvider) return validatingModelProvider.processRead(model);
184+
185+
throw new InternalServerErrorException("Could not obtain ValidatingModelProvider instance");
186+
}
187+
188+
/**
189+
* Returns the JAX-RS request context.
190+
*
191+
* @return the request
192+
*/
193+
public Request getRequest()
194+
{
195+
return request;
196+
}
197+
198+
/**
199+
* Generates an ETag for the given model.
200+
*
201+
* @param model RDF model
202+
* @return entity tag
203+
*/
204+
public EntityTag getEntityTag(Model model)
205+
{
206+
return new EntityTag(Long.toHexString(ModelUtils.hashModel(model)));
207+
}
208+
134209
}

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/form.xsl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,8 @@ WHERE
457457
</xsl:document>
458458
</xsl:variable>
459459
<xsl:sequence select="map:merge(($context, map{
460-
'document': $document
460+
'document': $document,
461+
'action': if (map:contains($context, 'action')) then $context('action') else ldh:href(ac:absolute-path(ldh:base-uri($document)), map{})
461462
}), map{ 'duplicates': 'use-last' })"/>
462463
</xsl:function>
463464

@@ -514,7 +515,7 @@ WHERE
514515
<xsl:variable name="shapes" select="$context('shapes')" as="document-node()"/>
515516
<xsl:variable name="object-metadata" select="$context('object-metadata')" as="document-node()?"/>
516517
<xsl:variable name="method" select="$context('method')" as="xs:string"/>
517-
<xsl:variable name="action" select="ldh:href(ac:absolute-path(ldh:base-uri($document)), map{})" as="xs:anyURI"/>
518+
<xsl:variable name="action" select="$context('action')" as="xs:anyURI"/>
518519

519520
<xsl:for-each select="$block">
520521
<xsl:variable name="form" as="node()*">
@@ -652,13 +653,13 @@ WHERE
652653

653654
<xsl:template match="div[contains-token(@class, 'modal-constructor')]//form[contains-token(@class, 'form-horizontal')][upper-case(@method) = 'PATCH']" mode="ixsl:onsubmit" priority="2">
654655
<xsl:param name="block" select="ancestor::div[contains-token(@class, 'modal-constructor')]" as="element()"/>
656+
<xsl:param name="about" select="$block/@about" as="xs:anyURI"/>
655657
<xsl:sequence select="ixsl:call(ixsl:event(), 'preventDefault', [])"/>
656658
<xsl:variable name="form" select="." as="element()"/>
657659
<xsl:variable name="method" select="upper-case(@method)" as="xs:string"/>
658660
<xsl:variable name="id" select="ixsl:get($form, 'id')" as="xs:string"/>
659661
<xsl:variable name="action" select="ixsl:get($form, 'action')" as="xs:anyURI"/>
660662
<xsl:variable name="enctype" select="ixsl:get($form, 'enctype')" as="xs:string"/>
661-
<xsl:variable name="about" select="$block/@about" as="xs:anyURI"/>
662663
<xsl:variable name="etag" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || ac:absolute-path(ldh:base-uri(.)) || '`'), 'etag')" as="xs:string"/>
663664

664665
<ixsl:set-style name="cursor" select="'progress'" object="ixsl:page()//body"/>

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -745,10 +745,10 @@ LIMIT 10
745745

746746
<xsl:for-each select="$content-body">
747747
<xsl:result-document href="?." method="ixsl:append-content">
748-
<div class="modal modal-constructor fade in">
748+
<div class="modal modal-constructor fade in" about="{$lapp:application}">
749749
<div class="modal-header">
750750
<button type="button" class="close">&#215;</button>
751-
751+
752752
<legend>
753753
<xsl:value-of>
754754
<xsl:apply-templates select="key('resources', 'application-settings', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
@@ -770,7 +770,8 @@ LIMIT 10
770770
'request': $request,
771771
'block': $block,
772772
'about': $lapp:application,
773-
'method': $method
773+
'method': $method,
774+
'action': resolve-uri('settings', ldt:base())
774775
}"/>
775776
<ixsl:promise select="
776777
ixsl:http-request($context('request'))

0 commit comments

Comments
 (0)