Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions src/main/resources/com/atomgraph/linkeddatahub/ldh.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -576,14 +576,29 @@ dh:Item spin:constructor :TitleConstructor, :DescriptionConstructor, :PrimaryTop
WHERE {}""" ;
rdfs:isDefinedBy : .

:ChildrenViewContructor a :Constructor ;
rdfs:label "Container content constructor" ;
sp:text """
PREFIX ldh: <https://w3id.org/atomgraph/linkeddatahub#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX spin: <http://spinrdf.org/spin#>

CONSTRUCT {
$this rdf:_1 [
a ldh:Object ;
rdf:value ldh:ChildrenView ;
] .
}
WHERE {}""" ;
rdfs:isDefinedBy : .

:MissingContainer a :MissingPropertyValue ;
rdfs:label "Missing container" ;
rdfs:comment "Requires items to have a parent container" ;
sp:arg1 sioc:has_container ;
rdfs:isDefinedBy : .

dh:Container spin:constructor :TitleConstructor, :DescriptionConstructor, :PrimaryTopicConstructor ;
:template :ChildrenView .
dh:Container spin:constructor :TitleConstructor, :DescriptionConstructor, :PrimaryTopicConstructor, :ChildrenViewContructor .

:MissingParent a :MissingPropertyValue ;
rdfs:label "Missing parent" ;
Expand Down Expand Up @@ -678,4 +693,4 @@ sd:Service spin:constructor :ServiceConstructor ;
}
WHERE {}""" ;
rdfs:label "Service constructor" ;
rdfs:isDefinedBy : .
rdfs:isDefinedBy : .
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ exclude-result-prefixes="#all"

<!-- TEMPLATES -->

<!-- identity transform -->

<xsl:template match="@* | node()" mode="ldh:Identity">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>

<!-- render row -->

<xsl:template match="*" mode="ldh:RenderRow" as="(function(item()?) as map(*))?">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,54 @@ exclude-result-prefixes="#all"

<!-- TEMPLATES -->

<!-- set chart properties -->

<xsl:template match="ldh:chartType | ldh:categoryVarName | ldh:categoryProperty | ldh:seriesVarName | ldh:seriesProperty" mode="ldh:Identity" priority="1"/>

<xsl:template match="*[rdf:type/@rdf:resource = '&ldh;ResultSetChart']" mode="ldh:Identity" priority="1">
<xsl:param name="chart-type" as="xs:anyURI" tunnel="yes"/>
<xsl:param name="category" as="xs:string?" tunnel="yes"/>
<xsl:param name="series" as="xs:string*" tunnel="yes"/>

<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>

<xsl:for-each select="$chart-type">
<ldh:chartType rdf:resource="{.}"/>
</xsl:for-each>
<xsl:for-each select="$category">
<ldh:categoryVarName>
<xsl:value-of select="."/>
</ldh:categoryVarName>
</xsl:for-each>
<xsl:for-each select="$series">
<ldh:seriesVarName>
<xsl:value-of select="."/>
</ldh:seriesVarName>
</xsl:for-each>
</xsl:copy>
</xsl:template>

<xsl:template match="*[rdf:type/@rdf:resource = '&ldh;GraphChart']" mode="ldh:Identity" priority="1">
<xsl:param name="chart-type" as="xs:anyURI" tunnel="yes"/>
<xsl:param name="category" as="xs:string?" tunnel="yes"/>
<xsl:param name="series" as="xs:string*" tunnel="yes"/>

<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>

<xsl:for-each select="$chart-type">
<ldh:chartType rdf:resource="{.}"/>
</xsl:for-each>
<xsl:for-each select="$category">
<ldh:categoryProperty rdf:resource="{.}"/>
</xsl:for-each>
<xsl:for-each select="$series">
<ldh:seriesProperty rdf:resource="{.}"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>

<!-- TO-DO: make 'data-table' configurable -->
<xsl:template name="ac:draw-chart">
<xsl:param name="data-table"/>
Expand Down Expand Up @@ -216,9 +264,9 @@ exclude-result-prefixes="#all"
<xsl:param name="button-class" select="'btn'" as="xs:string?"/>
<xsl:param name="accept-charset" select="'UTF-8'" as="xs:string?"/>
<xsl:param name="enctype" as="xs:string?"/>
<xsl:param name="chart-type-id" select="'chart-type'" as="xs:string"/>
<xsl:param name="category-id" select="'category'" as="xs:string"/>
<xsl:param name="series-id" select="'series'" as="xs:string"/>
<xsl:param name="chart-type-id" select="'chart-type-' || generate-id()" as="xs:string"/>
<xsl:param name="category-id" select="'category-' || generate-id()" as="xs:string"/>
<xsl:param name="series-id" select="'series-' || generate-id()" as="xs:string"/>
<xsl:param name="form-actions" as="element()?">
<div class="form-actions">
<button class="btn btn-primary btn-save-chart" type="button">
Expand Down Expand Up @@ -627,6 +675,67 @@ exclude-result-prefixes="#all"
<ixsl:set-style name="cursor" select="'default'" object="ixsl:page()//body"/>
</xsl:template>

<!-- save chart onclick -->
<!-- TO-DO: use @typeof in match so that we don't need a custom button.btn-save-chart class -->

<xsl:template match="div[@typeof]//button[contains-token(@class, 'btn-save-chart')]" mode="ixsl:onclick">
<ixsl:set-style name="cursor" select="'progress'" object="ixsl:page()//body"/>
<xsl:variable name="block" select="ancestor::div[contains-token(@class, 'block')][1]" as="element()"/>
<xsl:variable name="container" select="ancestor::div[@typeof][1]" as="element()"/>
<xsl:variable name="about" select="$block/@about" as="xs:anyURI"/>
<xsl:variable name="query-uri" select="$container//descendant::*[@property = '&spin;query']/@resource" as="xs:anyURI"/>
<xsl:variable name="chart-type" select="$container//form//select[contains-token(@class, 'chart-type')]/ixsl:get(., 'value')" as="xs:anyURI?"/>
<xsl:variable name="category" select="$container//form//select[contains-token(@class, 'chart-category')]/ixsl:get(., 'value')" as="xs:string?"/>
<xsl:variable name="series" as="xs:string*">
<xsl:for-each select="$container//form//select[contains-token(@class, 'chart-series')]">
<xsl:variable name="select" select="." as="element()"/>
<xsl:for-each select="0 to xs:integer(ixsl:get(., 'selectedOptions.length')) - 1">
<xsl:sequence select="ixsl:get(ixsl:call(ixsl:get($select, 'selectedOptions'), 'item', [ . ]), 'value')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="method" select="'PATCH'" as="xs:string"/>
<xsl:variable name="action" select="ac:absolute-path(ldh:base-uri(.))" as="xs:anyURI"/>
<xsl:variable name="accept" select="'application/rdf+xml'" as="xs:string"/>
<xsl:variable name="etag" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || ac:absolute-path(ldh:base-uri(.)) || '`'), 'etag')" as="xs:string"/>
<!-- not using ldh:base-uri(.) because it goes stale when DOM is replaced -->
<xsl:variable name="doc" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || ac:absolute-path(xs:anyURI(ixsl:location())) || '`'), 'results')" as="document-node()"/>
<xsl:variable name="chart" select="key('resources', $about, $doc)" as="element()"/>
<!-- update the properties on the chart resource -->
<xsl:variable name="chart" as="element()">
<xsl:apply-templates select="$chart" mode="ldh:Identity">
<xsl:with-param name="chart-type" select="$chart-type" tunnel="yes"/>
<xsl:with-param name="series" select="$series" tunnel="yes"/>
<xsl:with-param name="category" select="$category" tunnel="yes"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:variable name="triples" select="ldh:descriptions-to-triples($chart)" as="element()*"/>
<xsl:variable name="update-string" select="ldh:insertdelete-update(ldh:triples-to-bgp(ldh:uri-po-pattern($about)), ldh:triples-to-bgp($triples), ldh:triples-to-bgp(ldh:uri-po-pattern($about)))" as="xs:string"/>
<xsl:variable name="resources" as="document-node()">
<xsl:document>
<rdf:RDF>
<xsl:sequence select="ldh:triples-to-descriptions($triples)"/>
</rdf:RDF>
</xsl:document>
</xsl:variable>
<xsl:variable name="request-uri" select="ldh:href($ldt:base, ac:absolute-path($ldh:requestUri), map{}, $action)" as="xs:anyURI"/>
<!-- If-Match header checks preconditions, i.e. that the graph has not been modified in the meanwhile -->
<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(*)"/>
<xsl:variable name="context" as="map(*)" select="
map{
'request': $request,
'doc-uri': ac:absolute-path(ldh:base-uri(.)),
'block': $block,
'resources': $resources
}"/>
<ixsl:promise select="
ixsl:http-request($context('request')) (: Step 1: send initial request :)
=> ixsl:then(ldh:rethread-response($context, ?)) (: Step 2: attach response to context :)
=> ixsl:then(ldh:handle-response#1) (: Step 3: handle 429s, etc. :)
=> ixsl:then(ldh:row-form-response#1)
"/>
</xsl:template>

<!-- CALLBACKS -->

<!-- chart query response -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,9 @@ exclude-result-prefixes="#all"
<xsl:attribute name="class" select="concat($class, ' ', 'btn-run-query')"/>
</xsl:template>

<!-- identity transform -->

<xsl:template match="@* | node()" mode="ldh:SetQueryString">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>

<!-- set query string -->

<xsl:template match="sp:text/text()" mode="ldh:SetQueryString" priority="1">
<xsl:template match="sp:text/text()" mode="ldh:Identity" priority="1">
<xsl:param name="query-string" as="xs:string" tunnel="yes"/>

<xsl:sequence select="$query-string"/>
Expand Down Expand Up @@ -467,7 +459,7 @@ exclude-result-prefixes="#all"

<!-- replace the query string (sp:text value) on the query resource -->
<xsl:variable name="query" as="element()">
<xsl:apply-templates select="$query" mode="ldh:SetQueryString">
<xsl:apply-templates select="$query" mode="ldh:Identity">
<xsl:with-param name="query-string" select="$query-string" tunnel="yes"/>
</xsl:apply-templates>
</xsl:variable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ WHERE
<xsl:template match="*[rdf:type/@rdf:resource = ('&spin;ConstraintViolation', '&sh;ValidationResult', '&sh;ValidationReport', '&http;Response')]" mode="bs2:Form" priority="3"/>

<!-- suppress the system properties of document resources (they are set automatically by LinkedDataHub) -->
<xsl:template match="*[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:created | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:modified | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/sioc:has_container | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/sioc:has_parent | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:creator | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/acl:owner | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/*[namespace-uri() = '&rdf;'][starts-with(local-name(), '_')]" mode="bs2:FormControl" priority="1"/>
<xsl:template match="*[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:created | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:modified | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/sioc:has_container | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/sioc:has_parent | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/dct:creator | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container', '&dh;Item')]/acl:owner | *[rdf:type/@rdf:resource = ('&def;Root', '&dh;Container')]/*[namespace-uri() = '&rdf;'][starts-with(local-name(), '_')][@rdf:resource] | *[rdf:type/@rdf:resource = '&dh;Item']/*[namespace-uri() = '&rdf;'][starts-with(local-name(), '_')]" mode="bs2:FormControl" priority="1"/>

<!-- canonicalize XML in rdf:XMLLiterals -->
<xsl:template match="json:string[@key = 'object'][ends-with(., '^^&rdf;XMLLiteral')]" mode="ldh:CanonicalizeXML" priority="1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,8 +805,10 @@ LIMIT 100
<xsl:param name="typeof" select="key('resources', ac:absolute-path(ldh:base-uri(.)))/rdf:type/@rdf:resource/xs:anyURI(.)" as="xs:anyURI*"/>
<xsl:param name="doc-types" select="key('resources', ac:absolute-path(ldh:base-uri(.)))/rdf:type/@rdf:resource[ . = ('&def;Root', '&dh;Container', '&dh;Item')]" as="xs:anyURI*"/>
<!-- take care not to load unnecessary documents over HTTP when $doc-types is empty -->
<xsl:param name="block-values" select="if (exists($doc-types)) then (if (doc-available(resolve-uri('ns?query=ASK%20%7B%7D', $ldt:base))) then (ldh:query-result(map{}, resolve-uri('ns', $ldt:base), $template-query || ' VALUES $Type { ' || string-join(for $type in $doc-types return '&lt;' || $type || '&gt;', ' ') || ' }')//srx:binding[@name = 'block']/srx:uri/xs:anyURI(.)) else ()) else ()" as="xs:anyURI*"/>
<xsl:param name="has-content" select="key('resources', key('resources', ac:absolute-path(ldh:base-uri(.)))/rdf:*[starts-with(local-name(), '_')]/@rdf:resource) or exists($block-values)" as="xs:boolean"/>
<xsl:param name="template-block-uris" select="if (exists($doc-types)) then (if (doc-available(resolve-uri('ns?query=ASK%20%7B%7D', $ldt:base))) then (ldh:query-result(map{}, resolve-uri('ns', $ldt:base), $template-query || ' VALUES $Type { ' || string-join(for $type in $doc-types return '&lt;' || $type || '&gt;', ' ') || ' }')//srx:binding[@name = 'block']/srx:uri/xs:anyURI(.)) else ()) else ()" as="xs:anyURI*"/>
<xsl:param name="block-uris" select="key('resources', ac:absolute-path(ldh:base-uri(.)))/rdf:*[starts-with(local-name(), '_')]/@rdf:resource" as="xs:anyURI*"/>
<!-- document has content when either explicitly declared document-level blocks exist or template-declared class-level blocks exist -->
<xsl:param name="has-content" select="exists(for $block-uri in $block-uris return (if (doc-available(ac:document-uri($block-uri))) then key('resources', $block-uri, document(ac:document-uri($block-uri))) else ())) or exists($template-block-uris)" as="xs:boolean"/>

<div>
<xsl:if test="$id">
Expand Down Expand Up @@ -838,7 +840,7 @@ LIMIT 100
</xsl:when>
<!-- check if the current document has content or its class has content -->
<xsl:when test="(empty($ac:mode) and $has-content) or $ac:mode = '&ldh;ContentMode'">
<xsl:for-each select="$block-values">
<xsl:for-each select="$template-block-uris">
<xsl:if test="doc-available(ac:document-uri(.))">
<xsl:apply-templates select="key('resources', ., document(ac:document-uri(.)))" mode="bs2:Row"/>
</xsl:if>
Expand Down