Open rwalkerands opened 9 months ago
This is also further to https://github.com/epimorphics/elda/issues/171; therefore, see also the fixes made in commits ae1a2fbc108c10d21eb7f4c6d0bcf55fe97300ed and 7ea2e64344b8023069981edb9a1905212924c75b.
OK, so on examination of the code, I quickly figured out how to add an element, but not an attribute.
So here's a quick-and-dirty-hack to see if it's possible to add an element for termBindings for which the shortname is defined:
diff -U10 ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java-o ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java
--- ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java-o 2021-09-22 00:12:09.000000000 +1000
+++ ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java 2024-01-11 15:43:37.073859061 +1100
@@ -300,31 +300,37 @@
}
int bnodeCounter = 1000;
private Resource createBNode(Model m) {
Resource b = m.createResource( new AnonId( "bnode-" + bnodeCounter++ ) );
return b;
}
public void addTermBindings( Model toScan, Model meta, Resource exec, CompleteContext cc ) {
+ Map<String, String> termBindingsBeforeIncluding = cc.Do();
+ Set<String> uriSetBeforeIncluding = new HashSet<>();
+ uriSetBeforeIncluding.addAll(termBindingsBeforeIncluding.keySet());
Map<String, String> termBindings = cc.include(toScan).Do();
List<String> uriList = new ArrayList<String>( termBindings.keySet() );
Collections.sort( uriList );
for (String uri: uriList) {
Resource term = meta.createResource( uri );
if (toScan.containsResource( term )) {
String shorty = termBindings.get( uri );
Resource tb = createBNode( meta );
exec.addProperty( API.termBinding, tb );
tb.addProperty( API.label, shorty );
tb.addProperty( API.property, term );
+ if (uriSetBeforeIncluding.contains(uri)) {
+ tb.addProperty( API.definition, "true" );
+ }
}
}
}
// following the Puelia model.
public void addExecution( Model meta, Resource anExec ) {
Resource exec = anExec.inModel(meta), page = thisPage.inModel(meta);
exec.addProperty( RDF.type, API.Execution );
Resource P = createBNode( meta );
ELDA.addEldaMetadata( P );
(Yes, I overloaded the use of the api:definition
property.)
Well, it seems to produce the correct answer. The resulting XML output now shows:
<item id="_:item-1029">
<label>issued</label>
<property href="http://purl.org/dc/terms/issued"/>
</item>
<item id="_:item-1030">
<api_definition>true</api_definition>
<label>label</label>
<property href="http://www.w3.org/2000/01/rdf-schema#label"/>
</item>
In my own testing, this seems to be working correctly, with one exception: there's some strangeness with a non-shortname publisher
. The XML now has:
<item id="_:item-1039">
<label>publisher</label>
<property href="http://purl.org/dc/terms/publisher"/>
</item>
i.e., without the new api_definition
element. I also checked the /api-config
page and drilled down to the endpoint's list of shortnames. It doesn't list publisher
as a shortname either. And I checked my endpoint definition, and I definitely don't add an api:label
for it.
But publisher
still seems to work as a shortname, i.e., adding _properties=publisher
to the URL succeeds.
(Edit: temporarily removed a URL showing this as it's not ready to show yet.)
OK, I forgot about auto-generation of shortnames; that explains why publisher
"works" as a shortname despite my not giving it an api:label
. The issue then is: how to mark them also as "defined" in the termBindings?
I re-did my quick-and-dirty-hack to use the ShortnameService
. It now produces the "correct answers".
$ diff -U10 ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java-o ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java
--- ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java-o 2021-09-22 00:12:09.000000000 +1000
+++ ./elda-lda/src/main/java/com/epimorphics/lda/core/EndpointMetadata.java 2024-01-16 15:52:37.407510677 +1100
@@ -10,20 +10,21 @@
import java.util.*;
import com.epimorphics.lda.bindings.Bindings;
import com.epimorphics.lda.core.APIResultSet.MergedModels;
import com.epimorphics.lda.metadata.MetaConfig;
import com.epimorphics.lda.core.property.ViewProperty;
import com.epimorphics.lda.query.QueryParameter;
import com.epimorphics.lda.query.WantsMetadata;
import com.epimorphics.lda.renderers.Factories.FormatNameAndType;
import com.epimorphics.lda.shortnames.CompleteContext;
+import com.epimorphics.lda.shortnames.ShortnameService;
import com.epimorphics.lda.sources.Source;
import com.epimorphics.lda.specs.APIEndpointSpec;
import com.epimorphics.lda.specs.EndpointDetails;
import com.epimorphics.lda.support.PropertyChain;
import com.epimorphics.lda.vocabularies.*;
import com.epimorphics.util.URIUtils;
import com.hp.hpl.jena.graph.compose.MultiUnion;
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.sparql.vocabulary.FOAF;
import com.hp.hpl.jena.util.ResourceUtils;
@@ -33,32 +34,44 @@
Class to handle the construction of metadata for API endpoint results.
Bit of a hotchpotch at the moment.
@author Chris
*/
public class EndpointMetadata {
protected final Bindings bindings;
protected final Resource thisPage;
protected final URI thisPageAsURI;
+ protected final ShortnameService sns;
protected final String pageNumber;
protected final boolean isListEndpoint;
protected final boolean isParameterBasedFormat;
public EndpointMetadata( EndpointDetails ep, Resource thisPage, String pageNumber, Bindings bindings ) {
this.bindings = bindings;
this.thisPage = thisPage;
this.pageNumber = pageNumber;
this.isListEndpoint = ep.isListEndpoint();
this.isParameterBasedFormat = ep.hasParameterBasedContentNegotiation();
this.thisPageAsURI = URIUtils.newURI( thisPage.getURI() );
+ this.sns = null;
+ }
+
+ public EndpointMetadata( EndpointDetails ep, Resource thisPage, String pageNumber, Bindings bindings, ShortnameService sns ) {
+ this.bindings = bindings;
+ this.thisPage = thisPage;
+ this.pageNumber = pageNumber;
+ this.isListEndpoint = ep.isListEndpoint();
+ this.isParameterBasedFormat = ep.hasParameterBasedContentNegotiation();
+ this.thisPageAsURI = URIUtils.newURI( thisPage.getURI() );
+ this.sns = sns;
}
public static void addAllMetadata
( APIEndpointSpec spec
, MergedModels mergedModels
, URI fullURI
, Resource uriForDefinition
, Bindings bindings
, CompleteContext cc
, boolean suppress_IPTO
@@ -133,21 +146,21 @@
.addProperty( API.definition, uriForDefinition )
.addProperty( RDF.type, API.ListEndpoint )
;
} else {
Resource content = firstOf(resultList).inModel(metaModel);
thisMetaPage.addProperty( FOAF.primaryTopic, content );
thisMetaPage.addProperty( RDF.type, API.ItemEndpoint );
if (suppress_IPTO == false) content.addProperty( FOAF.isPrimaryTopicOf, thisMetaPage );
}
//
- EndpointMetadata em = new EndpointMetadata( details, thisMetaPage, "" + page, bindings);
+ EndpointMetadata em = new EndpointMetadata( details, thisMetaPage, "" + page, bindings, spec.getAPISpec().getShortnameService() );
Model metaModel1 = mergedModels.getMetaModel();
Model mergedModels1 = mergedModels.getMergedModel();
//
Resource exec = metaModel1.createResource();
Model versionsModel = ModelFactory.createDefaultModel();
Model formatsModel = ModelFactory.createDefaultModel();
Model bindingsModel = ModelFactory.createDefaultModel();
Model execution = ModelFactory.createDefaultModel();
//
em.addVersions( versionsModel, cc, views );
@@ -311,20 +324,23 @@
List<String> uriList = new ArrayList<String>( termBindings.keySet() );
Collections.sort( uriList );
for (String uri: uriList) {
Resource term = meta.createResource( uri );
if (toScan.containsResource( term )) {
String shorty = termBindings.get( uri );
Resource tb = createBNode( meta );
exec.addProperty( API.termBinding, tb );
tb.addProperty( API.label, shorty );
tb.addProperty( API.property, term );
+ if ( sns != null && sns.expand(shorty) != null ) {
+ tb.addProperty( API.definition, "true" );
+ }
}
}
}
// following the Puelia model.
public void addExecution( Model meta, Resource anExec ) {
Resource exec = anExec.inModel(meta), page = thisPage.inModel(meta);
exec.addProperty( RDF.type, API.Execution );
Resource P = createBNode( meta );
ELDA.addEldaMetadata( P );
This is somewhat related to https://github.com/epimorphics/elda/issues/221.
I'm (yes, still) using Elda 1.4.3, but I've just also tested with 2.0.2 and the underlying issue is the same. And I'm (yes, still) using XSLT to generate HTML.
The XML that is fed into the XSLT doesn't contain information about which shortnames are valid, i.e., which ones are explicitly defined for the endpoint using the
api:label
property. As a result, the generated HTML page may offer icons and links that won't work, and indeed, produce the error screen "Sorry ... That shortname is unrecognised."Current example that shows the problem: https://test.vocabs.ardc.edu.au/repository/api/lda/autestingorgrole/r29-testing/v1/resource?uri=http://test.ands.org.au/testresolution/eh_tmc/concepts/100394
Click either:
<
or>
icons at the right side of theissued
field,issued
label in the View panel.It'd be helpful if the
<termBinding>
element were enhanced to flag the shortnames that are explicitly defined. Then the XSLT can stop generating those icons/links that won't work.For example, the XML for the above page has a
<termBinding>
element that includes this fragment:From this, it would appear that both
issued
andlabel
are both "usable" shortnames. But only the second one is.Random example of a way of addressing this: