Skip to content

Commit

Permalink
Add initial signposting headers (#493)
Browse files Browse the repository at this point in the history
* Add first draft of signposting headers.

* Fixed checkstyle issues.
  • Loading branch information
kburger authored Mar 30, 2024
1 parent 8379a41 commit 6e161e1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import nl.dtls.fairdatapoint.database.rdf.repository.RepositoryMode;
import jakarta.servlet.http.HttpServletResponse;
import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException;
import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository;
import nl.dtls.fairdatapoint.entity.exception.ForbiddenException;
Expand All @@ -46,7 +47,9 @@
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.impl.LinkedHashModel;
import org.eclipse.rdf4j.model.util.Models;
import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -149,7 +152,8 @@ public Model getMetaDataExpanded(
)
public Model getMetaData(
@PathVariable final Optional<String> oUrlPrefix,
@PathVariable final Optional<String> oRecordId
@PathVariable final Optional<String> oRecordId,
HttpServletResponse response
) throws MetadataServiceException {
// 1. Init
final Model resultRdf = new LinkedHashModel();
Expand All @@ -171,7 +175,9 @@ public Model getMetaData(
metadataEnhancer.enhanceWithLinks(entityUri, entity, rd, persistentUrl, resultRdf);
metadataEnhancer.enhanceWithResourceDefinition(entityUri, rd, resultRdf);

// 5. Create response
enhanceWithSignposting(response, entityUri, resultRdf);

// 6. Create response
return resultRdf;
}

Expand Down Expand Up @@ -416,4 +422,37 @@ private Optional<Model> retrieveChildModel(MetadataService childMetadataService,
private String createLink(String entityUrl, String childPrefix, int page, int size, String rel) {
return format("<%s/page/%s?page=%d&size=%d>; rel=\"%s\"", entityUrl, childPrefix, page, size, rel);
}

private void enhanceWithSignposting(HttpServletResponse response, IRI entityUri, Model resultRdf) {
// author
Models.getProperty(resultRdf, entityUri, DCTERMS.PUBLISHER).ifPresent(pub -> {
addSignpostingHeader(response, pub, "author");
});

// cite-as
addSignpostingHeader(response, entityUri, "cite-as");

// describedby
// TODO

// type
Models.getProperties(resultRdf, entityUri, RDF.TYPE).forEach(type -> {
addSignpostingHeader(response, type, "type");
});

// license
Models.getPropertyIRI(resultRdf, entityUri, DCTERMS.LICENSE).ifPresent(license -> {
addSignpostingHeader(response, license, "license");
});

// item
// TODO

// collection
// TODO
}

private void addSignpostingHeader(HttpServletResponse response, Value link, String rel) {
response.addHeader(HttpHeaders.LINK, format("<%s>; rel=\"%s\"", link, rel));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* The MIT License
* Copyright © 2017 DTL
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package nl.dtls.fairdatapoint.acceptance.metadata;

import static java.lang.String.format;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsIn.in;
import static org.hamcrest.core.Is.is;
import java.net.URI;
import nl.dtls.fairdatapoint.WebIntegrationTest;
import org.junit.jupiter.api.Test;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.RequestEntity;

public class SingpostingTest extends WebIntegrationTest {
private URI url(String id) {
return URI.create(format("/catalog/%s", id));
}

@Test
public void testCatalogSignpostingHeaders() {
// GIVEN:
var request = RequestEntity
.get(url("catalog-1"))
.header(HttpHeaders.ACCEPT, "text/turtle")
.build();
var responseType = new ParameterizedTypeReference<String>() {};

// WHEN:
var result = client.exchange(request, responseType);

// THEN:
var linkHeaderMatcher = is(in(result.getHeaders().get(HttpHeaders.LINK)));
assertThat("<http://example.com/publisher>; rel=\"author\"", linkHeaderMatcher);
assertThat("<http://localhost:8088/catalog/catalog-1>; rel=\"cite-as\"", linkHeaderMatcher);
assertThat("<http://www.w3.org/ns/dcat#Catalog>; rel=\"type\"", linkHeaderMatcher);
assertThat("<http://rdflicense.appspot.com/rdflicense/cc-by-nc-nd3.0>; rel=\"license\"", linkHeaderMatcher);
}
}

0 comments on commit 6e161e1

Please sign in to comment.