Skip to content

Commit c6e14f0

Browse files
CMath04PascalLike
authored andcommitted
Patch core for DCAT2 plugin
Signed-off-by: Antonio Cerciello <[email protected]>
1 parent cae3aa5 commit c6e14f0

File tree

15 files changed

+253
-11
lines changed

15 files changed

+253
-11
lines changed

core/src/main/java/org/fao/geonet/kernel/search/EsSearchManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ public class EsSearchManager implements ISearchManager {
137137
.add(Geonet.IndexFieldNames.RESOURCEABSTRACT)
138138
.add(Geonet.IndexFieldNames.RESOURCEABSTRACT + "Object")
139139
.add("operatesOn")
140+
.add("rdfResourceIdentifier")
140141
.build();
141142

142143
FIELDLIST_RELATED_SCRIPTED = ImmutableMap.<String, String>builder()

core/src/main/java/org/fao/geonet/util/XslUtil.java

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
package org.fao.geonet.util;
2525

26+
import co.elastic.clients.elasticsearch.core.SearchResponse;
2627
import co.elastic.clients.elasticsearch.core.search.Hit;
2728
import com.fasterxml.jackson.core.JsonProcessingException;
2829
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -54,20 +55,19 @@
5455
import org.fao.geonet.constants.Geonet;
5556
import org.fao.geonet.domain.*;
5657
import org.fao.geonet.kernel.*;
58+
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
5759
import org.fao.geonet.kernel.datamanager.base.BaseMetadataUtils;
5860
import org.fao.geonet.kernel.search.CodeListTranslator;
5961
import org.fao.geonet.kernel.search.EsSearchManager;
6062
import org.fao.geonet.kernel.search.Translator;
6163
import org.fao.geonet.kernel.security.SecurityProviderConfiguration;
6264
import org.fao.geonet.kernel.setting.SettingInfo;
6365
import org.fao.geonet.kernel.setting.SettingManager;
66+
import org.fao.geonet.kernel.setting.Settings;
6467
import org.fao.geonet.kernel.url.UrlChecker;
6568
import org.fao.geonet.languages.IsoLanguagesMapper;
6669
import org.fao.geonet.lib.Lib;
67-
import org.fao.geonet.repository.IsoLanguageRepository;
68-
import org.fao.geonet.repository.SourceRepository;
69-
import org.fao.geonet.repository.UiSettingsRepository;
70-
import org.fao.geonet.repository.UserRepository;
70+
import org.fao.geonet.repository.*;
7171
import org.fao.geonet.schema.iso19139.ISO19139Namespaces;
7272
import org.fao.geonet.utils.Log;
7373
import org.fao.geonet.utils.Xml;
@@ -1622,4 +1622,80 @@ public static String getWebAnalyticsJavascriptCode() {
16221622

16231623
return webAnalyticsConfiguration.getJavascriptCode();
16241624
}
1625+
1626+
// DCAT Custom
1627+
public static String getThesaurusTitleByName(String id) {
1628+
ApplicationContext applicationContext = ApplicationContextHolder.get();
1629+
ThesaurusManager thesaurusManager = applicationContext.getBean(ThesaurusManager.class);
1630+
Thesaurus thesaurus = thesaurusManager.getThesaurusByName(id);
1631+
return thesaurus == null ? "" : thesaurus.getTitle();
1632+
}
1633+
1634+
/**
1635+
* DCAT custom
1636+
* Generate a UUID based off a string for consistent results
1637+
*
1638+
* @param str
1639+
* @return UUID string
1640+
*/
1641+
public static String uuidFromString(String str) {
1642+
return UUID.nameUUIDFromBytes(str.getBytes()).toString();
1643+
}
1644+
1645+
// DCAT Custom
1646+
public static String getRecordResourceURI(String uuid) {
1647+
var searchManager = ApplicationContextHolder.get().getBean(EsSearchManager.class);
1648+
1649+
try {
1650+
Set<String> source = new HashSet<>();
1651+
source.add("rdfResourceIdentifier");
1652+
SearchResponse response = searchManager.query(String.format("+uuid:%s", uuid), null, source, 0, 1);
1653+
1654+
if (response.hits().hits().isEmpty()) {
1655+
return null;
1656+
}
1657+
ObjectMapper objectMapper = new ObjectMapper();
1658+
1659+
Hit h = (Hit) response.hits().hits().get(0);
1660+
Object rdfResourceIdentifier = objectMapper.convertValue(h.source(), Map.class).get("rdfResourceIdentifier");
1661+
if (rdfResourceIdentifier instanceof String) {
1662+
return (String) rdfResourceIdentifier;
1663+
} else if (rdfResourceIdentifier instanceof ArrayList) {
1664+
return ((ArrayList<String>) rdfResourceIdentifier).get(0);
1665+
} else {
1666+
throw new Exception("Cannot obtain resource URI from " + rdfResourceIdentifier.toString());
1667+
}
1668+
1669+
} catch (Exception e) {
1670+
Log.error(Log.JEEVES, "GET Record resource identifier '" + uuid + "' error: " + e.getMessage(), e);
1671+
}
1672+
return null;
1673+
}
1674+
1675+
/**
1676+
* DCAT Custom
1677+
* Get the metadata URI build pattern based on the source catalog
1678+
*
1679+
* @param uuid
1680+
*/
1681+
public static String getUriPattern(String uuid) {
1682+
ApplicationContext context = ApplicationContextHolder.get();
1683+
IMetadataUtils metadataUtils = context.getBean(IMetadataUtils.class);
1684+
1685+
AbstractMetadata metadata = metadataUtils.findOneByUuid(uuid);
1686+
1687+
if (metadata != null && metadata.getHarvestInfo().isHarvested()) {
1688+
HarvesterSettingRepository harvesterSetting = context.getBean(HarvesterSettingRepository.class);
1689+
HarvesterSetting uuidSetting = harvesterSetting.findOneByNameAndStoredValueLike("uuid", metadata.getHarvestInfo().getUuid());
1690+
if (uuidSetting != null && uuidSetting.getParent() != null) {
1691+
List<HarvesterSetting> resourceUriPatternSetting = harvesterSetting.findChildrenByName(uuidSetting.getParent().getId(), "resourceUriPattern");
1692+
if (resourceUriPatternSetting.size() > 0 && StringUtils.isNotEmpty(resourceUriPatternSetting.get(0).getValue())) {
1693+
return resourceUriPatternSetting.get(0).getValue();
1694+
}
1695+
}
1696+
}
1697+
1698+
SettingManager sm = context.getBean(SettingManager.class);
1699+
return sm.getValue(Settings.SYSTEM_RESOURCE_PREFIX) + "/{resourceType}/{resourceUuid}";
1700+
}
16251701
}

domain/src/main/java/org/fao/geonet/repository/HarvesterSettingRepository.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,15 @@ public interface HarvesterSettingRepository extends GeonetRepository<HarvesterSe
7474
*/
7575
@Nullable
7676
HarvesterSetting findOneByNameAndStoredValue(@Nonnull String name, @Nonnull String value);
77+
78+
/**
79+
* DCAT custom
80+
* Find the settings with the given name and value. Null is returned if not found.
81+
*
82+
* @param name the setting name.
83+
* @param value the setting value.
84+
* @return The setting with the given name and value.
85+
*/
86+
@Nullable
87+
HarvesterSetting findOneByNameAndStoredValueLike(@Nonnull String name, @Nonnull String value);
7788
}

harvesters/src/main/java/org/fao/geonet/kernel/harvest/harvester/csw/CswHarvester.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ protected void storeNodeExtra(CswParams params, String path, String siteId, Stri
6060
harvesterSettingsManager.add("id:" + siteId, "xslfilter", params.xslfilter);
6161
harvesterSettingsManager.add("id:" + siteId, "outputSchema", params.outputSchema);
6262
harvesterSettingsManager.add("id:" + siteId, "sortBy", params.sortBy);
63+
// DCAT custom
64+
harvesterSettingsManager.add("id:" + siteId, "resourceUriPattern", params.resourceUriPattern);
6365

6466
//--- store dynamic filter nodes
6567
String filtersID = harvesterSettingsManager.add(path, "filters", "");

harvesters/src/main/java/org/fao/geonet/kernel/harvest/harvester/csw/CswParams.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ public class CswParams extends AbstractParams {
5353

5454
public Integer hopCount;
5555

56+
// DCAT custom
57+
public String resourceUriPattern;
58+
5659
/**
5760
* The filter is a process (see schema/process folder) which depends on the schema. It could be
5861
* composed of parameter which will be sent to XSL transformation using the following syntax :
@@ -105,6 +108,8 @@ public void create(Element node) throws BadInputEx {
105108

106109
bboxFilter = node.getChild("bboxFilter");
107110

111+
// DCAT custom
112+
resourceUriPattern = Util.getParam(site, "resourceUriPattern", "");
108113
}
109114

110115
/**
@@ -136,6 +141,9 @@ public void update(Element node) throws BadInputEx {
136141
}
137142

138143
bboxFilter = node.getChild("bboxFilter");
144+
145+
// DCAT custom
146+
resourceUriPattern = Util.getParam(site, "resourceUriPattern", "");
139147
}
140148

141149
/**
@@ -159,6 +167,9 @@ public CswParams copy() {
159167
copy.eltFilters = eltFilters;
160168
copy.bboxFilter = bboxFilter;
161169

170+
// DCAT custom
171+
copy.resourceUriPattern = resourceUriPattern;
172+
162173
return copy;
163174
}
164175

harvesters/src/main/java/org/fao/geonet/kernel/harvest/harvester/geonet/GeonetHarvester.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ protected void storeNodeExtra(GeonetParams params, String path,
7575
harvesterSettingsManager.add("id:" + groupID, "name", g.name);
7676
harvesterSettingsManager.add("id:" + groupID, "policy", g.policy);
7777
}
78+
79+
// DCAT custom
80+
harvesterSettingsManager.add("id:" + siteId, "resourceUriPattern", params.resourceUriPattern);
7881
}
7982

8083
public void addHarvestInfo(Element info, String id, String uuid) {

harvesters/src/main/java/org/fao/geonet/kernel/harvest/harvester/geonet/GeonetParams.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public class GeonetParams extends AbstractParams {
6060

6161
private ArrayList<Group> alCopyPolicy = new ArrayList<Group>();
6262

63+
// VL
64+
public String resourceUriPattern;
65+
6366
public GeonetParams(DataManager dm) {
6467
super(dm);
6568
}
@@ -80,6 +83,9 @@ public void create(Element node) throws BadInputEx {
8083
mefFormatFull = Util.getParam(site, "mefFormatFull", false);
8184
xslfilter = Util.getParam(site, "xslfilter", "");
8285

86+
// VL
87+
resourceUriPattern = Util.getParam(site, "resourceUriPattern", "");
88+
8389
//checkPort(port);
8490
addSearches(searches);
8591
addCopyPolicy(policy);
@@ -109,6 +115,9 @@ public void update(Element node) throws BadInputEx {
109115

110116
if (policy != null)
111117
addCopyPolicy(policy);
118+
119+
// DCAT custom
120+
resourceUriPattern = Util.getParam(site, "resourceUriPattern", "");
112121
}
113122

114123
public Iterable<Search> getSearches() {
@@ -152,6 +161,9 @@ public GeonetParams copy() {
152161
for (Group g : alCopyPolicy)
153162
copy.alCopyPolicy.add(g.copy());
154163

164+
// VL
165+
copy.resourceUriPattern = resourceUriPattern;
166+
155167
return copy;
156168
}
157169

schemas/iso19139/src/main/plugin/iso19139/index-fields/index.xsl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
xmlns:gml="http://www.opengis.net/gml/3.2"
3232
xmlns:gml320="http://www.opengis.net/gml"
3333
xmlns:xlink="http://www.w3.org/1999/xlink"
34+
xmlns:geonet="http://www.fao.org/geonetwork"
3435
xmlns:gn-fn-index="http://geonetwork-opensource.org/xsl/functions/index"
3536
xmlns:index="java:org.fao.geonet.kernel.search.EsSearchManager"
3637
xmlns:digestUtils="java:org.apache.commons.codec.digest.DigestUtils"
@@ -72,6 +73,8 @@
7273
<xsl:variable name="parentAssociatedResourceType" select="'partOfSeamlessDatabase'"/>
7374
<xsl:variable name="childrenAssociatedResourceType" select="'isComposedOf'"/>
7475

76+
<xsl:variable name="uuidRegex" select="'([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}){1}'"/>
77+
7578
<xsl:template match="/">
7679
<xsl:apply-templates mode="index"/>
7780
</xsl:template>
@@ -1445,4 +1448,72 @@
14451448
</xsl:for-each>
14461449
</xsl:for-each>
14471450
</xsl:template>
1451+
1452+
1453+
<!-- RDF URI functions -->
1454+
<xsl:template mode="index-extra-fields" match="gmd:MD_Metadata">
1455+
<rdfResourceIdentifier>
1456+
<xsl:value-of select="geonet:getRDFResourceURI(.)"/>
1457+
</rdfResourceIdentifier>
1458+
</xsl:template>
1459+
1460+
<xsl:function name="geonet:getRDFResourceURI">
1461+
<xsl:param name="md" as="node()"/>
1462+
1463+
<xsl:variable name="isoScopeCode">
1464+
<xsl:value-of select="normalize-space($md/gmd:hierarchyLevel/gmd:MD_ScopeCode/@codeListValue)"/>
1465+
</xsl:variable>
1466+
<xsl:variable name="resourceType">
1467+
<xsl:choose>
1468+
<xsl:when test="$isoScopeCode = 'dataset' or $isoScopeCode = 'nonGeographicDataset'">
1469+
<xsl:text>dataset</xsl:text>
1470+
</xsl:when>
1471+
<xsl:otherwise>
1472+
<xsl:value-of select="$isoScopeCode"/>
1473+
</xsl:otherwise>
1474+
</xsl:choose>
1475+
</xsl:variable>
1476+
1477+
<xsl:variable name="uriPattern" select="util:getUriPattern($md/gmd:fileIdentifier/gco:CharacterString)"/>
1478+
<xsl:variable name="resourceUUID" select="geonet:getResourceBaseURIOrUUID($md)"/>
1479+
<xsl:choose>
1480+
<xsl:when test="starts-with($resourceUUID, 'http://') or starts-with($resourceUUID, 'https://')">
1481+
<xsl:value-of select="geonet:escapeURI($resourceUUID)"/>
1482+
</xsl:when>
1483+
<xsl:otherwise>
1484+
<xsl:value-of select="geonet:escapeURI(replace(replace($uriPattern, '\{resourceType\}', concat($resourceType, 's')), '\{resourceUuid\}', $resourceUUID))"/>
1485+
</xsl:otherwise>
1486+
</xsl:choose>
1487+
</xsl:function>
1488+
1489+
<xsl:function name="geonet:getResourceBaseURIOrUUID">
1490+
<xsl:param name="md" as="node()"/>
1491+
<xsl:variable name="resourceIdentifiers">
1492+
<xsl:for-each select="$md/gmd:identificationInfo[1]/*/gmd:citation/*/gmd:identifier/*">
1493+
<xsl:choose>
1494+
<xsl:when test="gmd:codeSpace/gco:CharacterString/text() != ''">
1495+
<xsl:value-of select="concat(gmd:codeSpace/gco:CharacterString/text(), gmd:code/gco:CharacterString/text())"/>
1496+
</xsl:when>
1497+
<xsl:otherwise>
1498+
<xsl:value-of select="gmd:code/gco:CharacterString/text()"/>
1499+
</xsl:otherwise>
1500+
</xsl:choose>
1501+
</xsl:for-each>
1502+
</xsl:variable>
1503+
<xsl:choose>
1504+
<xsl:when test="$resourceIdentifiers[matches(., $uuidRegex)][1]">
1505+
<xsl:value-of select="$resourceIdentifiers[matches(., $uuidRegex)][1]"/>
1506+
</xsl:when>
1507+
<xsl:otherwise>
1508+
<xsl:value-of select="util:uuidFromString($md/gmd:fileIdentifier/gco:CharacterString)"/>
1509+
</xsl:otherwise>
1510+
</xsl:choose>
1511+
</xsl:function>
1512+
1513+
<xsl:function name="geonet:escapeURI">
1514+
<xsl:param name="uri"/>
1515+
<xsl:if test="$uri">
1516+
<xsl:value-of select="replace(replace(replace(replace(normalize-space($uri), ' ', '%20'), '&lt;', '%3C'), '&gt;', '%3E'), '\\', '%5C')"/>
1517+
</xsl:if>
1518+
</xsl:function>
14481519
</xsl:stylesheet>

services/src/main/java/org/fao/geonet/api/records/MetadataUtils.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.fao.geonet.repository.SourceRepository;
6161
import org.fao.geonet.repository.specification.MetadataValidationSpecs;
6262
import org.fao.geonet.services.relations.Get;
63+
import org.fao.geonet.util.XslUtil;
6364
import org.fao.geonet.utils.Log;
6465
import org.jdom.Content;
6566
import org.jdom.Element;
@@ -174,16 +175,27 @@ public static Map<RelatedItemType, List<AssociatedRecord>> getAssociated(
174175
// brothers&sisters
175176
//
176177
// * All of them could be remote records
178+
String mdURI = XslUtil.getRecordResourceURI(md.getUuid());
177179
Arrays.stream(types).forEach(type -> {
178180
if (type == RelatedItemType.associated
179181
|| type == RelatedItemType.hasfeaturecats
180182
|| type == RelatedItemType.services
181183
|| type == RelatedItemType.hassources) {
182-
queries.put(type,
183-
new RelatedTypeDetails(
184-
String.format("+%s:\"%s\"",
185-
RELATED_INDEX_FIELDS.get(type.value()), md.getUuid())
186-
));
184+
// VL Custom
185+
String luceneQuery;
186+
if (mdURI != null) {
187+
luceneQuery = String.format(
188+
"%s:\"%s\" OR %s:\"%s\"",
189+
RELATED_INDEX_FIELDS.get(type.value()),
190+
md.getUuid(),
191+
RELATED_INDEX_FIELDS.get(type.value()),
192+
mdURI
193+
);
194+
} else {
195+
luceneQuery = String.format("+%s:\"%s\"", RELATED_INDEX_FIELDS.get(type.value()), md.getUuid());
196+
}
197+
198+
queries.put(type, new RelatedTypeDetails(luceneQuery));
187199
} else if (schemaPlugin != null
188200
&& (type == RelatedItemType.siblings
189201
|| type == RelatedItemType.parent

web-ui/src/main/resources/catalog/templates/admin/harvest/type/csw.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,23 @@
337337
data-lang="{{lang}}"
338338
data-label="csw-category"
339339
></div>
340+
341+
<div>
342+
<label
343+
id="gn-harvest-settings-gn-advanced-resource-uri-pattern-label"
344+
class="control-label"
345+
data-translate=""
346+
>resourceUriPattern</label
347+
>
348+
<input
349+
id="gn-harvest-settings-gn-advanced-resource-uri-pattern-input"
350+
type="text"
351+
class="form-control gn-csw-criteria"
352+
data-ng-model="harvesterSelected.site.resourceUriPattern"
353+
/>
354+
355+
<p class="help-block" data-translate="">resourceUriPatternHelp</p>
356+
</div>
340357
</fieldset>
341358

342359
<div

0 commit comments

Comments
 (0)