Skip to content
Snippets Groups Projects
Commit 64608f54 authored by Jesper Zedlitz's avatar Jesper Zedlitz
Browse files

Merge branch 'main' into 21-typen-von-eintraegen-einschliessen-und-ausschliessen

parents 4c550b5d 14c577ae
Branches
No related tags found
1 merge request!18Resolve "Typen von Einträgen einschließen und ausschließen"
Pipeline #496 passed
...@@ -267,16 +267,15 @@ public class CswInterface { ...@@ -267,16 +267,15 @@ public class CswInterface {
List<Element> findOperatesOn(String id) throws IOException, DocumentException { List<Element> findOperatesOn(String id) throws IOException, DocumentException {
final StringBuilder filter = new StringBuilder(); final StringBuilder filter = new StringBuilder();
if (filterOpendata) { if (filterOpendata) {
filter.append("<ogc:And>"); filter.append("<ogc:And>");
} }
filter.append(" <ogc:PropertyIsLike wildCard=\"%\" singleChar=\"_\" escapeChar=\"\\\">" + filter.append(" <ogc:PropertyIsEqualTo>" +
" <ogc:PropertyName>operatesOn</ogc:PropertyName>" + " <ogc:PropertyName>operatesOn</ogc:PropertyName>" +
" <ogc:Literal>%") " <ogc:Literal>")
.append(id) .append(id)
.append("</ogc:Literal>") .append("</ogc:Literal>")
.append(" </ogc:PropertyIsLike>\n"); .append(" </ogc:PropertyIsEqualTo>\n");
if (filterOpendata) { if (filterOpendata) {
filter.append("<ogc:PropertyIsEqualTo>" + filter.append("<ogc:PropertyIsEqualTo>" +
...@@ -286,7 +285,6 @@ public class CswInterface { ...@@ -286,7 +285,6 @@ public class CswInterface {
filter.append("</ogc:And>"); filter.append("</ogc:And>");
} }
final String xmlRequest = "<csw:GetRecords xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" xmlns:ogc=\"http://www.opengis.net/ogc\"\n" + final String xmlRequest = "<csw:GetRecords xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" xmlns:ogc=\"http://www.opengis.net/ogc\"\n" +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\"\n" + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\"\n" +
"xmlns:apiso=\"http://www.opengis.net/cat/apiso/1.0\" "+ "xmlns:apiso=\"http://www.opengis.net/cat/apiso/1.0\" "+
......
...@@ -8,10 +8,7 @@ import org.apache.jena.datatypes.RDFDatatype; ...@@ -8,10 +8,7 @@ import org.apache.jena.datatypes.RDFDatatype;
import org.apache.jena.datatypes.xsd.XSDDatatype; import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.iri.IRI; import org.apache.jena.iri.IRI;
import org.apache.jena.iri.IRIFactory; import org.apache.jena.iri.IRIFactory;
import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.*;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.vocabulary.DCAT; import org.apache.jena.vocabulary.DCAT;
import org.apache.jena.vocabulary.DCTerms; import org.apache.jena.vocabulary.DCTerms;
import org.apache.jena.vocabulary.RDF; import org.apache.jena.vocabulary.RDF;
...@@ -29,6 +26,7 @@ import org.slf4j.LoggerFactory; ...@@ -29,6 +26,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.time.LocalDate;
import java.util.*; import java.util.*;
/** /**
...@@ -702,16 +700,31 @@ public class MDMetadata2Dataset { ...@@ -702,16 +700,31 @@ public class MDMetadata2Dataset {
// some fixed properties // some fixed properties
dataset.addProperty(DCATAPde.contributorID, model.createResource(settings.contributorId)); dataset.addProperty(DCATAPde.contributorID, model.createResource(settings.contributorId));
final Element mdIdentifier = (Element) metadata.selectSingleNode("gmd:identificationInfo/gmd:MD_DataIdentification/gmd:citation/gmd:CI_Citation/gmd:identifier/gmd:MD_Identifier/gmd:code/gco:CharacterString");
final String searchId = mdIdentifier != null ? mdIdentifier.getTextTrim() : id;
LocalDate datasetModificationDate = RDFUtils.literalToDate(dataset.getProperty(DCTerms.modified).getLiteral());
// add coupled services // add coupled services
if (cswInterface != null && id != null) { if (cswInterface != null && searchId != null) {
final List<Element> services = cswInterface.findOperatesOn(id); final List<Element> services = cswInterface.findOperatesOn(searchId);
for (Element service : services) { for (Element service : services) {
try { try {
for (Resource dist : convertServiceToDistributions(service)) { for (Resource dist : convertServiceToDistributions(service)) {
dataset.addProperty(DCAT.distribution, dist); dataset.addProperty(DCAT.distribution, dist);
// Is the modification date of the service more recent?
final Literal distributionModified = dist.getProperty(DCTerms.modified).getLiteral();
final LocalDate distributionModificationDate = RDFUtils.literalToDate(distributionModified);
if (distributionModificationDate.isAfter(datasetModificationDate)) {
// update dct:modified value of the dataset
dataset.removeAll(DCTerms.modified);
dataset.addProperty(DCTerms.modified, distributionModified);
datasetModificationDate = distributionModificationDate;
}
} }
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
log.warn("Skipping distribution for dataset {}: {}", id, ex.getMessage()); log.warn("Skipping distribution for dataset {}: {}", searchId, ex.getMessage());
} }
} }
} }
......
...@@ -170,6 +170,8 @@ public class Mapping { ...@@ -170,6 +170,8 @@ public class Mapping {
return ResourceFactory.createResource("http://publications.europa.eu/resource/authority/file-type/ATOM"); return ResourceFactory.createResource("http://publications.europa.eu/resource/authority/file-type/ATOM");
} else if ("Excel".equals(format)) { } else if ("Excel".equals(format)) {
return ResourceFactory.createResource("http://publications.europa.eu/resource/authority/file-type/XLS"); return ResourceFactory.createResource("http://publications.europa.eu/resource/authority/file-type/XLS");
} else if ("GeoTIFF".equals(format)) {
return ResourceFactory.createResource("http://publications.europa.eu/resource/authority/file-type/GEOTIFF");
} else if (StringUtils.isEmpty(format)) { } else if (StringUtils.isEmpty(format)) {
throw new IllegalArgumentException("Format must not be empty."); throw new IllegalArgumentException("Format must not be empty.");
} else { } else {
......
package de.landsh.opendata.csw2dcat;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.rdf.model.Literal;
import java.time.LocalDate;
public class RDFUtils {
/**
* Convert a literal of type XSDdate or XSDdateTime into a LocalDate.
*/
public static LocalDate literalToDate(Literal literal) {
if (literal == null) {
return null;
}
String dateString;
if (XSDDatatype.XSDdate.equals(literal.getDatatype()) || XSDDatatype.XSDdateTime.equals(literal.getDatatype())) {
dateString = StringUtils.substring(literal.getString(), 0,10);
} else {
throw new IllegalArgumentException("Unknown datatype for a date: " + literal.getDatatypeURI());
}
return LocalDate.parse(dateString);
}
}
\ No newline at end of file
...@@ -10,6 +10,7 @@ import org.apache.hc.core5.http.ProtocolException; ...@@ -10,6 +10,7 @@ import org.apache.hc.core5.http.ProtocolException;
import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.io.entity.StringEntity;
import org.dom4j.DocumentException; import org.dom4j.DocumentException;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
...@@ -184,9 +185,9 @@ class CswInterfaceTest { ...@@ -184,9 +185,9 @@ class CswInterfaceTest {
assertNotNull(xml.element("Query").element("Constraint")); assertNotNull(xml.element("Query").element("Constraint"));
Element filter = xml.element("Query").element("Constraint").element("Filter"); Element filter = xml.element("Query").element("Constraint").element("Filter");
assertNotNull(filter ); assertNotNull(filter );
assertNotNull(filter.element("PropertyIsLike")); assertNotNull( filter.element("PropertyIsEqualTo"));
assertEquals("operatesOn", filter.element("PropertyIsLike").elementText("PropertyName")); assertEquals("operatesOn", filter.element("PropertyIsEqualTo").elementText("PropertyName"));
assertEquals("%5bf8d8c6-01bf-465b-98de-a0f32f3d739e", filter.element("PropertyIsLike").elementText("Literal")); assertEquals("5bf8d8c6-01bf-465b-98de-a0f32f3d739e", filter.element("PropertyIsEqualTo").elementText("Literal"));
} }
/** /**
...@@ -221,13 +222,15 @@ class CswInterfaceTest { ...@@ -221,13 +222,15 @@ class CswInterfaceTest {
Element elementAnd = filter.element("And"); Element elementAnd = filter.element("And");
assertNotNull( elementAnd); assertNotNull( elementAnd);
assertNotNull(elementAnd.element("PropertyIsLike")); assertEquals( 2, elementAnd.elements("PropertyIsEqualTo").size());
assertEquals("operatesOn", elementAnd.element("PropertyIsLike").elementText("PropertyName"));
assertEquals("%d8fee8c2-4385-46df-ab5e-8a372ac5a04d", elementAnd.element("PropertyIsLike").elementText("Literal"));
assertNotNull(elementAnd.element("PropertyIsEqualTo")); Map<String,String> propertyIsEqualTo = new HashMap<>();
assertEquals("apiso:Subject", elementAnd.element("PropertyIsEqualTo").elementText("PropertyName")); for (Element e : elementAnd.elements("PropertyIsEqualTo")) {
assertEquals("opendata", elementAnd.element("PropertyIsEqualTo").elementText("Literal")); propertyIsEqualTo.put(e.elementText("PropertyName"), e.elementText("Literal"));
}
assertEquals("d8fee8c2-4385-46df-ab5e-8a372ac5a04d", propertyIsEqualTo.get("operatesOn"));
assertEquals("opendata", propertyIsEqualTo.get("apiso:Subject"));
} }
@Test @Test
......
...@@ -363,12 +363,16 @@ public class MDMetadata2DatasetTests { ...@@ -363,12 +363,16 @@ public class MDMetadata2DatasetTests {
service.convert(inputDocument); service.convert(inputDocument);
} }
/**
* <pre>e95c2bed-84c0-4e7c-a194-1568887fc355</pre> is a dataset.
* <pre>5a9a19d0-f24b-427e-9bdd-c1c7da2e84e7</pre> is a coupled service of this dataset.
*/
@Test @Test
public void convert_coupledServices_Seehunde() throws DocumentException, IOException { public void convert_coupledServices_Seehunde() throws DocumentException, IOException {
final Element serviceElement = saxReader.read(getClass().getResourceAsStream("/5a9a19d0-f24b-427e-9bdd-c1c7da2e84e7.xml")).getRootElement(); final Element serviceElement = saxReader.read(getClass().getResourceAsStream("/5a9a19d0-f24b-427e-9bdd-c1c7da2e84e7.xml")).getRootElement();
Mockito.when(cswInterface.findOperatesOn("e95c2bed-84c0-4e7c-a194-1568887fc355")).thenReturn(Collections.singletonList(serviceElement)); Mockito.when(cswInterface.findOperatesOn("http://www.mdi-sh.org/#c365fcb1-f2b8-4e05-baf1-627b413da204")).thenReturn(Collections.singletonList(serviceElement));
final Document inputDocument = saxReader.read(getClass().getResourceAsStream("/e95c2bed-84c0-4e7c-a194-1568887fc355.xml")); final Document inputDocument = saxReader.read(getClass().getResourceAsStream("/e95c2bed-84c0-4e7c-a194-1568887fc355.xml"));
...@@ -376,6 +380,10 @@ public class MDMetadata2DatasetTests { ...@@ -376,6 +380,10 @@ public class MDMetadata2DatasetTests {
assertTrue(result.hasLiteral(DCTerms.identifier, "e95c2bed-84c0-4e7c-a194-1568887fc355")); assertTrue(result.hasLiteral(DCTerms.identifier, "e95c2bed-84c0-4e7c-a194-1568887fc355"));
// The modification date of the dataset itself is 2022-05-05. The modification date of the service is 2023-06-01.
// The resulting modification date of the dataset is the latest modification date of one of its coupled services.
assertEquals("2023-06-01^^http://www.w3.org/2001/XMLSchema#date", result.getProperty(DCTerms.modified).getLiteral().toString());
final Map<String, Resource> distributionMap = collectDistributions(result); final Map<String, Resource> distributionMap = collectDistributions(result);
checkSeehundeDistributions(distributionMap); checkSeehundeDistributions(distributionMap);
...@@ -622,7 +630,7 @@ public class MDMetadata2DatasetTests { ...@@ -622,7 +630,7 @@ public class MDMetadata2DatasetTests {
{ {
final Document document = saxReader.read(getClass().getResourceAsStream("/GetRecordsResponse_operatesOn_mekun.xml")); final Document document = saxReader.read(getClass().getResourceAsStream("/GetRecordsResponse_operatesOn_mekun.xml"));
List<Element> serviceElements = document.getRootElement().element("SearchResults").elements(); List<Element> serviceElements = document.getRootElement().element("SearchResults").elements();
Mockito.when(cswInterface.findOperatesOn("ad15c139-cf86-4027-a46c-470bc7c52d7c")).thenReturn(serviceElements); Mockito.when(cswInterface.findOperatesOn("https://registry.gdi-de.org/id/de.sh/ad15c139-cf86-4027-a46c-470bc7c52d7c")).thenReturn(serviceElements);
} }
// prepare input element // prepare input element
......
package de.landsh.opendata.csw2dcat;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.junit.jupiter.api.Test;
import java.time.LocalDate;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
class RDFUtilsTest {
final Model model = ModelFactory.createDefaultModel();
@Test
void literalToDate_null() {
assertNull(RDFUtils.literalToDate(null));
}
@Test
void literalToDate_date() {
assertEquals(
LocalDate.of(2023, 7, 22),
RDFUtils.literalToDate(model.createTypedLiteral("2023-07-22", "http://www.w3.org/2001/XMLSchema#date")));
}
@Test
void literalToDate_dateTime() {
assertEquals(
LocalDate.of(2020, 7, 14),
RDFUtils.literalToDate(model.createTypedLiteral("2020-07-14T12:17:01.654617", "http://www.w3.org/2001/XMLSchema#dateTime")));
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment