Skip to content

Commit 03155b5

Browse files
committed
Refactoring the ldh:href function to make its calls uniform
New `ldh:url-decode` XSLT extension function `graph` URL param deprecated
1 parent 6c133ce commit 03155b5

File tree

23 files changed

+251
-158
lines changed

23 files changed

+251
-158
lines changed

src/main/java/com/atomgraph/linkeddatahub/Application.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,7 @@ protected PasswordAuthentication getPasswordAuthentication()
747747

748748
xsltProc.registerExtensionFunction(new UUID());
749749
xsltProc.registerExtensionFunction(new DecodeURI());
750+
xsltProc.registerExtensionFunction(new com.atomgraph.linkeddatahub.writer.function.URLDecode());
750751
xsltProc.registerExtensionFunction(new com.atomgraph.linkeddatahub.writer.function.Construct(xsltProc));
751752
xsltProc.registerExtensionFunction(new com.atomgraph.linkeddatahub.writer.function.SendHTTPRequest(xsltProc, client));
752753

src/main/java/com/atomgraph/linkeddatahub/server/filter/request/ApplicationFilter.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import com.atomgraph.client.vocabulary.AC;
2020
import com.atomgraph.linkeddatahub.vocabulary.LAPP;
21-
import com.atomgraph.linkeddatahub.vocabulary.LDH;
2221
import com.atomgraph.linkeddatahub.writer.Mode;
2322
import java.io.IOException;
2423
import java.util.Collections;
@@ -72,21 +71,20 @@ public void filter(ContainerRequestContext request) throws IOException
7271
com.atomgraph.linkeddatahub.apps.model.Application app = appResource.as(com.atomgraph.linkeddatahub.apps.model.Application.class);
7372
request.setProperty(LAPP.Application.getURI(), app); // wrap into a helper class so it doesn't interfere with injection of Application
7473

75-
// use the ?graph URL parameter to override the effective request URI if its URI value is relative to the app's base URI
74+
// use the ?uri URL parameter to override the effective request URI if its URI value is relative to the app's base URI
7675
final URI requestURI;
77-
if (request.getUriInfo().getQueryParameters().containsKey(LDH.graph.getLocalName()))
76+
if (request.getUriInfo().getQueryParameters().containsKey(AC.uri.getLocalName()))
7877
try
7978
{
80-
URI graphURI = new URI(request.getUriInfo().getQueryParameters().getFirst(LDH.graph.getLocalName()));
79+
URI graphURI = new URI(request.getUriInfo().getQueryParameters().getFirst(AC.uri.getLocalName()));
8180
if (!app.getBaseURI().relativize(graphURI).isAbsolute()) // if ?graph query param value is relative to the app's base URI
8281
{
8382
// pass on query parameters except ?graph
8483
MultivaluedMap<String, String> queryParams = new MultivaluedHashMap();
8584
queryParams.putAll(request.getUriInfo().getQueryParameters());
86-
queryParams.remove(LDH.graph.getLocalName());
8785
queryParams.remove(AC.uri.getLocalName());
8886

89-
UriBuilder builder = UriBuilder.fromUri(graphURI);;
87+
UriBuilder builder = UriBuilder.fromUri(graphURI);
9088

9189
for (Entry<String, List<String>> params : queryParams.entrySet())
9290
for (String value : params.getValue())

src/main/java/com/atomgraph/linkeddatahub/vocabulary/LDH.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,6 @@ public static String getURI()
107107

108108
/**
109109
* Graph URI property */
110-
public static final ObjectProperty graph = m_model.createObjectProperty( NS + "graph" );
110+
//public static final ObjectProperty graph = m_model.createObjectProperty( NS + "graph" );
111111

112112
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* Copyright 2025 Martynas Jusevičius <[email protected]>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package com.atomgraph.linkeddatahub.writer.function;
18+
19+
import java.io.UnsupportedEncodingException;
20+
import java.net.URLDecoder;
21+
import net.sf.saxon.expr.XPathContext;
22+
import net.sf.saxon.lib.ExtensionFunctionCall;
23+
import net.sf.saxon.lib.ExtensionFunctionDefinition;
24+
import net.sf.saxon.om.Sequence;
25+
import net.sf.saxon.om.StructuredQName;
26+
import net.sf.saxon.trans.XPathException;
27+
import net.sf.saxon.value.SequenceType;
28+
import net.sf.saxon.value.StringValue;
29+
30+
/**
31+
* Saxon extension function that URL-decodes a string using java.net.URLDecoder.
32+
*
33+
* @author Martynas Jusevičius {@literal <[email protected]>}
34+
*/
35+
public class URLDecode extends ExtensionFunctionDefinition
36+
{
37+
38+
public static final String LOCAL_NAME = "url-decode";
39+
40+
@Override
41+
public StructuredQName getFunctionQName()
42+
{
43+
return new StructuredQName("ldh", "https://w3id.org/atomgraph/linkeddatahub#", LOCAL_NAME);
44+
}
45+
46+
@Override
47+
public int getMinimumNumberOfArguments()
48+
{
49+
return 1;
50+
}
51+
52+
@Override
53+
public int getMaximumNumberOfArguments()
54+
{
55+
return 2;
56+
}
57+
58+
@Override
59+
public SequenceType[] getArgumentTypes()
60+
{
61+
return new SequenceType[]
62+
{
63+
SequenceType.SINGLE_STRING, // encoded string
64+
SequenceType.OPTIONAL_STRING // encoding (optional, defaults to UTF-8)
65+
};
66+
}
67+
68+
@Override
69+
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes)
70+
{
71+
return SequenceType.SINGLE_STRING;
72+
}
73+
74+
@Override
75+
public ExtensionFunctionCall makeCallExpression()
76+
{
77+
return new ExtensionFunctionCall()
78+
{
79+
80+
@Override
81+
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException
82+
{
83+
String encodedString = arguments[0].head().getStringValue();
84+
String encoding = arguments.length > 1 && arguments[1].head() != null ?
85+
arguments[1].head().getStringValue() : "UTF-8";
86+
87+
try
88+
{
89+
// Handle + to space conversion for application/x-www-form-urlencoded format
90+
String plusDecoded = encodedString.replace("+", " ");
91+
String decoded = URLDecoder.decode(plusDecoded, encoding);
92+
return StringValue.makeStringValue(decoded);
93+
}
94+
catch (UnsupportedEncodingException ex)
95+
{
96+
throw new XPathException("Unsupported encoding: " + encoding, ex);
97+
}
98+
}
99+
100+
};
101+
}
102+
103+
}

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/acl/imports/acl.xsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ exclude-result-prefixes="#all">
6464

6565
<xsl:template match="*[rdf:type/@rdf:resource = '&lacl;AuthorizationRequest']" priority="1">
6666
<xsl:param name="method" select="'post'" as="xs:string"/>
67-
<xsl:param name="action" select="ldh:href($ldt:base, resolve-uri(ac:uuid() || '/', resolve-uri('acl/authorizations/', $ldt:base)), map{ '_method': 'PUT' })" as="xs:anyURI"/> <!-- create new authorization document -->
67+
<xsl:param name="action" select="ldh:href(resolve-uri(ac:uuid() || '/', resolve-uri('acl/authorizations/', $ldt:base)), map{ '_method': 'PUT' })" as="xs:anyURI"/> <!-- create new authorization document -->
6868
<xsl:param name="id" select="concat('form-', generate-id())" as="xs:string?"/>
6969
<xsl:param name="class" select="'form-horizontal'" as="xs:string?"/>
7070
<xsl:param name="accept-charset" select="'UTF-8'" as="xs:string?"/>

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/layout.xsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ exclude-result-prefixes="#all">
103103
<xsl:param name="id" select="concat('form-', generate-id())" as="xs:string?"/>
104104
<xsl:param name="class" select="'row-fluid'" as="xs:string?"/>
105105
<xsl:param name="method" select="'patch'" as="xs:string"/>
106-
<xsl:param name="action" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, ac:build-uri(ac:absolute-path(ldh:base-uri(.)), map{ '_method': 'PUT', 'mode': for $mode in $ac:mode return string($mode) }))" as="xs:anyURI"/>
106+
<xsl:param name="action" select="ldh:href(ac:build-uri(ac:absolute-path(ldh:base-uri(.)), map{ '_method': 'PUT' }), map{ 'mode': for $mode in $ac:mode return string($mode) })" as="xs:anyURI"/>
107107
<xsl:param name="enctype" select="'multipart/form-data'" as="xs:string?"/>
108108
<xsl:param name="create-resource" select="true()" as="xs:boolean"/>
109109
<!-- TO-DO: generate ontology classes from the OWL vocabulary -->

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/admin/signup.xsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ exclude-result-prefixes="#all">
6767
<xsl:template match="*[*][@rdf:about or @rdf:nodeID][ac:absolute-path($ldh:requestUri) = resolve-uri(encode-for-uri('sign up'), $ldt:base)]" mode="bs2:Right" use-when="system-property('xsl:product-name') = 'SAXON'"/>
6868

6969
<xsl:template match="rdf:RDF[ac:absolute-path($ldh:requestUri) = resolve-uri(encode-for-uri('sign up'), $ldt:base)]" mode="bs2:Row" priority="2">
70-
<xsl:variable name="constructors" select="ldh:query-result(map{}, resolve-uri('ns', $ldt:base), $constructor-query || ' VALUES $Type { ' || string-join(for $type in '&foaf;Person' return '&lt;' || $type || '&gt;', ' ') || ' }')" as="document-node()?"/>
70+
<xsl:variable name="constructors" select="ldh:query-result(resolve-uri('ns', $ldt:base), $constructor-query || ' VALUES $Type { ' || string-join(for $type in '&foaf;Person' return '&lt;' || $type || '&gt;', ' ') || ' }')" as="document-node()?"/>
7171
<xsl:apply-templates select="ldh:construct(map{ xs:anyURI('&foaf;Person'): $constructors//srx:result[srx:binding[@name = 'Type'] = '&foaf;Person']/srx:binding[@name = 'construct']/srx:literal/string() })" mode="bs2:RowForm">
7272
<xsl:with-param name="id" select="'form-signup'"/>
7373
<xsl:with-param name="method" select="'post'"/> <!-- don't use PATCH which is the default -->

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ exclude-result-prefixes="#all"
235235
<xsl:variable name="block-uri" select="$block/@about" as="xs:anyURI"/>
236236
<xsl:variable name="update-string" select="replace($block-delete-string, '$this', '&lt;' || ac:absolute-path(ldh:base-uri(.)) || '&gt;', 'q')" as="xs:string"/>
237237
<xsl:variable name="update-string" select="replace($update-string, '$block', '&lt;' || $block-uri || '&gt;', 'q')" as="xs:string"/>
238-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, ac:absolute-path(ldh:base-uri(.)))" as="xs:anyURI"/>
238+
<xsl:variable name="request-uri" select="ldh:href(ac:absolute-path(ldh:base-uri(.)), map{})" as="xs:anyURI"/>
239239
<xsl:variable name="request" as="item()*">
240240
<ixsl:schedule-action http-request="map{ 'method': 'PATCH', 'href': $request-uri, 'media-type': 'application/sparql-update', 'body': $update-string }">
241241
<xsl:call-template name="onBlockDelete">
@@ -316,7 +316,7 @@ exclude-result-prefixes="#all"
316316
<xsl:variable name="update-string" select="replace($block-swap-string, '$this', '&lt;' || ac:absolute-path(ldh:base-uri(.)) || '&gt;', 'q')" as="xs:string"/>
317317
<xsl:variable name="update-string" select="replace($update-string, '$targetBlock', '&lt;' || $block-uri || '&gt;', 'q')" as="xs:string"/>
318318
<xsl:variable name="update-string" select="replace($update-string, '$sourceBlock', '&lt;' || $drop-block-uri || '&gt;', 'q')" as="xs:string"/>
319-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, ac:absolute-path(ldh:base-uri(.)))" as="xs:anyURI"/>
319+
<xsl:variable name="request-uri" select="ldh:href(ac:absolute-path(ldh:base-uri(.)), map{})" as="xs:anyURI"/>
320320
<xsl:variable name="request" as="item()*">
321321
<ixsl:schedule-action http-request="map{ 'method': 'PATCH', 'href': $request-uri, 'media-type': 'application/sparql-update', 'body': $update-string }">
322322
<xsl:call-template name="onBlockSwap"/>

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ exclude-result-prefixes="#all"
291291
<ixsl:set-style name="width" select="'66%'" object="."/>
292292
</xsl:for-each>
293293

294-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, $query-uri)" as="xs:anyURI"/>
294+
<xsl:variable name="request-uri" select="ldh:href($query-uri, map{})" as="xs:anyURI"/>
295295
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }" as="map(*)"/>
296296
<xsl:variable name="context" as="map(*)" select="
297297
map{
@@ -658,7 +658,7 @@ exclude-result-prefixes="#all"
658658
<xsl:apply-templates select="$constructed-doc" mode="bs2:RowForm">
659659
<xsl:with-param name="about" select="()"/> <!-- don't set @about on the container until after the resource is saved -->
660660
<xsl:with-param name="method" select="$method"/>
661-
<xsl:with-param name="action" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, $doc-uri)" as="xs:anyURI"/>
661+
<xsl:with-param name="action" select="ldh:href($doc-uri, map{})" as="xs:anyURI"/>
662662
<xsl:with-param name="type-metadata" select="$type-metadata" tunnel="yes"/>
663663
<xsl:with-param name="property-metadata" select="$property-metadata" tunnel="yes"/>
664664
<xsl:with-param name="constructor" select="$constructed-doc" tunnel="yes"/>
@@ -722,7 +722,7 @@ exclude-result-prefixes="#all"
722722
</rdf:RDF>
723723
</xsl:document>
724724
</xsl:variable>
725-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, $action)" as="xs:anyURI"/>
725+
<xsl:variable name="request-uri" select="ldh:href($action, map{})" as="xs:anyURI"/>
726726
<!-- If-Match header checks preconditions, i.e. that the graph has not been modified in the meanwhile -->
727727
<xsl:variable name="request" select="map{ 'method': $method, 'href': $request-uri, 'media-type': 'application/sparql-update', 'body': $update-string, 'headers': map{ 'If-Match': $etag, 'Accept': 'application/rdf+xml', 'Cache-Control': 'no-cache' } }" as="map(*)"/>
728728
<xsl:variable name="context" as="map(*)" select="
@@ -772,7 +772,7 @@ exclude-result-prefixes="#all"
772772
<xsl:variable name="service" select="if ($service-uri) then key('resources', $service-uri, document(ac:build-uri(ac:document-uri($service-uri), map{ 'accept': 'application/rdf+xml' }))) else ()" as="element()?"/> <!-- TO-DO: refactor asynchronously -->
773773
<xsl:variable name="endpoint" select="($service/sd:endpoint/@rdf:resource/xs:anyURI(.), sd:endpoint())[1]" as="xs:anyURI"/>
774774
<xsl:variable name="results-uri" select="ac:build-uri($endpoint, map{ 'query': $query-string })" as="xs:anyURI"/>
775-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, $results-uri)" as="xs:anyURI"/>
775+
<xsl:variable name="request-uri" select="ldh:href($results-uri, map{})" as="xs:anyURI"/>
776776

777777
<!-- update progress bar -->
778778
<xsl:for-each select="$block//div[contains-token(@class, 'bar')]">

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,22 @@ exclude-result-prefixes="#all"
6969
</xsl:for-each>
7070

7171
<!-- don't use ldh:base-uri(.) because its value comes from the last HTML document load -->
72-
<xsl:variable name="request-uri" select="ldh:href($ldt:base, if (starts-with($graph, $ldt:base)) then $graph else ac:absolute-path(xs:anyURI(ixsl:location())), map{}, ac:document-uri($resource-uri), $graph, ())" as="xs:anyURI"/>
72+
<xsl:variable name="request-uri" select="ldh:href(($graph, ac:document-uri($resource-uri))[1], map{})" as="xs:anyURI"/>
73+
74+
<xsl:message>
75+
LDH:OBJECT
76+
($graph, ac:document-uri($resource-uri))[1]: <xsl:value-of select="($graph, ac:document-uri($resource-uri))[1]"/>
77+
$resource-uri: <xsl:value-of select="$resource-uri"/>
78+
$request-uri: <xsl:value-of select="$request-uri"/>
79+
</xsl:message>
80+
7381
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }" as="map(*)"/>
7482
<xsl:variable name="context" as="map(*)" select="
7583
map{
7684
'request': $request,
7785
'block': $block,
7886
'container': $container,
7987
'resource-uri': $resource-uri,
80-
'graph': $graph,
8188
'mode': $mode,
8289
'show-edit-button': $show-edit-button
8390
}"/>
@@ -162,7 +169,7 @@ exclude-result-prefixes="#all"
162169
<xsl:variable name="block" select="$context('block')" as="element()"/>
163170
<xsl:variable name="container" select="$context('container')" as="element()"/>
164171
<xsl:variable name="resource-uri" select="$context('resource-uri')" as="xs:anyURI"/>
165-
<xsl:variable name="graph" select="$context('graph')" as="xs:anyURI?"/>
172+
<!-- <xsl:variable name="graph" select="$context('graph')" as="xs:anyURI?"/>-->
166173
<xsl:variable name="mode" select="$context('mode')" as="xs:anyURI?"/>
167174
<xsl:variable name="show-edit-button" select="$context('show-edit-button')" as="xs:boolean?"/>
168175

@@ -191,7 +198,6 @@ exclude-result-prefixes="#all"
191198
'block': $block,
192199
'container': $container,
193200
'resource': $resource,
194-
'graph': $graph,
195201
'mode': $mode,
196202
'show-edit-button': $show-edit-button
197203
}"/>
@@ -255,7 +261,7 @@ exclude-result-prefixes="#all"
255261
<xsl:variable name="block" select="$context('block')" as="element()"/>
256262
<xsl:variable name="container" select="$context('container')" as="element()"/>
257263
<xsl:variable name="resource" select="$context('resource')" as="element()?"/>
258-
<xsl:variable name="graph" select="$context('graph')" as="xs:anyURI?"/>
264+
<!-- <xsl:variable name="graph" select="$context('graph')" as="xs:anyURI?"/>-->
259265
<xsl:variable name="mode" select="$context('mode')" as="xs:anyURI?"/>
260266
<xsl:variable name="show-edit-button" select="$context('show-edit-button')" as="xs:boolean?"/>
261267

@@ -275,7 +281,7 @@ exclude-result-prefixes="#all"
275281

276282
<xsl:variable name="row" as="node()*">
277283
<xsl:apply-templates select="$resource" mode="bs2:Row">
278-
<xsl:with-param name="graph" select="$graph" tunnel="yes"/>
284+
<!-- <xsl:with-param name="graph" select="$graph" tunnel="yes"/>-->
279285
<xsl:with-param name="mode" select="$mode"/>
280286
<xsl:with-param name="show-edit-button" select="$show-edit-button" tunnel="yes"/>
281287
<xsl:with-param name="object-metadata" select="$object-metadata" tunnel="yes"/>

0 commit comments

Comments
 (0)