- Fixed dragging within a map
- Fixed Docker build issue caused by an old Node.js version
- Fixed Login with Google caused by Varnish configuration stripping HTTP cookies
- Dependency on
com.atomgraph.server
(new module) instead ofcom.atomgraph.processor
- JAX-RS application now registers the
NotAcceptableExceptionMapper
so that the406 Not Acceptable
responses are mapped correctly - Ontologies are now cached by default
- Bumped Jena version in Dockerfile from 4.3.2 to 4.7.0 in order to avoid the Log4Shell CVE warning
- (X)HTML writer for SPARQL XML Results
- New Varnish proxy cache between nginx and LinkedDataHub (
varnish-frontend
service) in order to improve performance - New
lapp:frontendProxy
andlapp:backendProxy
properties in the LAPP ontology HEALTHCHECK
configuration in Dockerfile (relies on public access to the namespace document)
- Fixed content drag and drop logic to only work in content mode and not affect dragging in map and graph modes
- Content drag and drop is only enabled when the authenticated agent has an
acl:Write
authorization for the document - Improved extensibility of client-side XSLT templates for faceted search and parallax navigation
- When
ENABLE_LINKED_DATA_PROXY=false
,?uri=
proxy requests will return405 Method Not Allowed
unless the URI is already cached or mapped to file - Replaced the
atomgraph/varnish:6.0.11
Docker image with the officialvarnish:7.3.0
image - Replaced the
atomgraph/nginx:1.23.3
Docker image with the officialnginx:1.23.3
image
- Moved
Cache-Control
header settings from webapp'sweb.xml
to nginx's config template
- Option to re-arrange content blocks by drag & drop in content mode (enabled only when the agent has write access)
- Instead of writing JSON-LD directly,
schema:BreadCrumbList
mode returns RDF/XML which is then transformed to JSON-LD usingac:JSON-LD
- XML sitemap generation when env param
GENERATE_SITEMAP=true
is specified (enabled by default) - JSON-LD output in the
<script>
tag containingschema:BreadCrumbList
structured data
- Content blocks use
@about
attributes as identifiers instead of@data-content-uri
- Backlink navigation on XHTML content
- Navigation bar is now fully rendered server-side, i.e. the whole visible HTML body is replaced via AJAX
- Generalized client-side navigation templates using XPath maps
- Fixed default
@id
value inbs2:RowContent
mode
- Upgraded dependencies to use Jersey 3.x and the Servlet 5 API. That required replacing
javax.*
dependencies withjakarta.*
- Upgraded
atomgraph/nginx
,atomgraph/letsencrypt-tomcat
andatomgraph/varnish
base images docker-compose.yml
now uses image versions instead of hashes- Refactored
RDFXML2JSON-LD.xsl
converter uses the XSLT 3.0 JSON instructions instead of string concatenation - New
<acl/authorizations/public-namespace/#this>
authorization, separate from<acl/authorizations/public/#this>
- Fixed editing mode for resources that do not have any
rdf:type
properties - Replaced all SPARQLBuilder usages for query building with XSLT 3.0 transformations (SPARQLBuilder still used for query serialization)
- A separate HTTP client used only by the Linked Data client, to avoid sharing the connection pool with the main system client
- Linked Data client now sends a
User-Agent
request header impersonating the Firefox browser
@id
attributes are rewritten and@href
attributes are resolved against base URI when XHTML content is being transcluded
- Fixed HTTP connection leak in the
ldh:send-request
function - Fixed blank node labels and typeaheads in instance creation forms
- Fixed response caching in the container generation logic to make sure fresh content with the new containers is loaded after redirect
- If content resource cannot be loaded from Linked Data, fallback to a
DESCRIBE
query over the local endpoint
- Disabled SPARQL updates on the namespace ontology endpoint
/ns
- Better aligned document's timestamp and breadcrumbs in the navbar
- Constraint violation responses return
422 Unprocessable Entity
instead of400 Bad Request
(same change in Processor) PUT
/DELETE
restrictions on root/owner/secretary documents return405 Method Not Allowed
instead of400 Bad Request
- Improved error handling in the modal "Add data" form
- Resources in containers with remote endpoints get
DESCRIBE
query links instead of plain resource URI which would be attempted to load as Linked Data - Improved
rdf:type
controls in editing mode to enable adding/removing types on instances (except document instances where types are required)
- Public
acl:Append
access to the namespace ontology which is required because theldh:send-request
function sends unauthenticated SPARQL ProtocolPOST
requests
ldh:send-request
XSLT extension function which allows stylesheets to execute HTTPPOST
requests (e.g. if the query string is too long forGET
).
- Fixed datetime literal conversion from RDF/XML and SPARQL Results XML to Google Chart's
DataTable
- Fixed encoding of URIs with special characters in HTTP client requests
- Optimized resource-level XSLT modes by consolidating HTTP requests for type/property/constructor/constraint/shape metadata using SPARQL
VALUES
- Fallback to a
DESCRIBE
request inProxyResourceBase
$ldh:localGraph
/$ldh:original
XSLT parameters. XSLT stylesheet now loads the same data over HTTP without the need for special parameters.
- New "Generate containers" feature that loads a schema from a SPARQL service and then generates a container for each class
- Fixed regression of multiple RDF types in the typeahead component
- Fixed container result count widget to support remote SPARQL endpoints
- Fixed regression of created/modified timestaps not rendered on documents
- Result count widget for container content
- Fixed map initialization regression
- An onboarding message show the first time LinkedDataHub starts
- ACL agent URI is passed to the client-side stylesheet as an
$acl:agent
param
- Fixed minor signup and request-access UI issues
- Disabling "Save as" and "Delete" action buttons when the agent does not have a write permission
- Support for recursive content blocks
- Loading class and property descriptions from the namespace ontology before falling back to Linked Data
- Fixed shapes support for resources with multiple RDF types
- SHACL node shape and property shape creation in the admin app
- Basic support for instance construction from SHACL node shapes
- Improved validation of "Add data" and inline content editing forms
- SaxonJS upgraded to v2.5. Client-side XSLT code updated to take advantage of the latest bugfixes.
- Basic support for HTTP range requests when serving uploded files (
uploads/{sha1sum}
)
- Fixed infinite XSLT loop in the WebID signup flow
- Container UI code only hydrates server-side HTML elements, does not create them if they don't exist
- Parameterized CSS classes in
bs2:RowContent
mode ProxyResourceBase
guards against queries to the backend SPARQL service by requiring that agent is authorized
- Fixed order by dropdown population for container content
- Fixed and optimized container sorting
- Usage of group-sort-triples.xsl because Jena RDF/XML writer takes care of grouping triples and they're sorted during container rendering anyway
- WKT geometry support in map layout mode
- Fixed query builder behind faceted search to generate a correct query that loads facet values
- Moved RDFXML2DataTable.xsl and SPARQLXMLResults2DataTable.xsl converters from Web-Client
- Refactored RDFXML2DataTable.xsl and SPARQLXMLResults2DataTable.xsl using XSLT 3.0 JSON/XML instructions and fixed support for repeating columns
- Fixed the
[Actions]
button in edit mode to update the constructor list when new types are added to the edited instance - The ontology import query now adds explicit
rdfs:isDefinedBy
triples that connect classes to the ontology
- Web-Client upgrade fixes the RDF/XML to DataTable converter
- Map view is fit to the extent of loaded features
- Fixed blank node resources rendered as empty elements in
bs2:Row
mode
- Fixed calculation of center coordinates correctly for all map usages
- Google Maps and SPARQLMap dependencies replaced with OpenLayers 7.0. All functionality ported except bounding box-based feature loader.
- Fixed instance creation with multiple
rdf:type
s
- "Actions" button in edit mode allows adding and editing constructors of ontology classes without switching to the admin app
xsd:dateTime
literals are rendered asdatetime-local
inputs in edit mode
- Fixed
refresh_token
cache to store a token per client ID - Improved edit mode support for instances that have multiple
rdf:type
properties
- Usages of
OntModelReadOnly
which broke RDF/XML writing in Jena: apache/jena#1450
- The persistent storage of
refresh_token
s allows long-lived sessions when authenticated with Google login
- Fixed the back button (the history states were being mismanaged)
- Inline creation and editing of container and XHTML content in content layout mode
- ACL access modes sent as
Link
response headers and accessible in the client-side XSLT stylesheets using theacl:mode
function - Results of queries that use
forClass
type after a new instance was created are banned from Varnish cache endpoint
URL param can be used to override the SPARQL endpoint that the fallbackDESCRIBE
query gets executed against- XML literals in SPARQL updates get canonicalized before reaching the SPARQL endpoint
- Content model uses
rdf:Seq
andrdf:_1
,rdf:_2
... properties instead ofrdf:List
andrdf:first
/rdf:rest
- SPARQL updates submitted to the Graph Store via the
PATCH
method now have to use the default graph context, theGRAPH
keyword is disallowed - Fixed caching of delegated WebID agents, eliminating an unnecessary request with each authentication
- Multiple
Link
headers combined into a single one with concatenated values
--fragment
parameter to CLI scripts that can be used to specify the fragment ID of the resource paired with the document (defaults to UUID)ENABLE_LINKED_DATA_PROXY
env parameter that allows disabling the Linked Data proxy/browser (enabled by default)
- Fixed double
On-Behalf-Of
header value when both WebID and OIDC agent contexts were delegated - Fixed Linked Data proxy fallback to a local
DESCRIBE
query when the external URL does not dereference - Fixed IP address check in the setup script
- Jena upgraded to 4.5.0
- Fuseki Docker image upgraded to 4.5.0
- Saxon-JS upgraded to 2.4
key()
lookups enabled in client-side XSLT as HTML page mutations do not break indexes anymore (fixed in 5036)
- Spanish UI localization
- Reconciliation of OIDC accounts with existing agents by email address
- Document tree widget
- New
/clear
endpoint which is used to clear ontologies from memory - Second nginx port which has WebID client certificate authentication always enabled
--proxy
parameter to CLI scripts
- Variables in SPARQL query and update strings whose values are injected now start with
$
instead of?
, for example$this
- CSV and RDF imports write data directly to the backend Graph Store
- Only namespace, signup, OAuth2 login, WebID profiles and public keys can be public in admin apps, nothing else (hardcoded in the admin authorization query)
- When graph URI not explicitly specified, the Graph Store always returns
201 Created
(even if the graph existed) - Fuseki image upgraded to 4.3.2
- Interactivity to the graph SVG layout
- Notifications to the requesting agent when its access request is granted (requires email server)
- JSON-LD export option for documents
append-content
CLI script that appends content resources to documentcreate-file
CLI script automatically recognizes the MIME type of the file being uploaded- Linked Data browser functionality in graph layout mode
- Javadoc comments
- The setup script requirements relaxed to make it easier to run on MacOS
- Fixed CSV imports
- Linked Data browser now supports relative URIs
- Upgraded Java from 11 to 17
- A built-in HTTP API constraint does not allow
PUT
on documents without the document description in request body - A built-in HTTP API constraint does not allow to
DELETE
the root document - A built-in HTTP API constraint does not allow to
DELETE
orPUT
the the app owner's and secretary's WebID documents - Shell script interpreter line
- Dydra-specific code
- Ability to copy (fork) RDF data into the local dataspace
- Block-based content layout (
ldh:ContentList
mode) and editor - Login with Google (OpenID Connect)
- Ability to load JSON-LD data from
<script>
elements in HTML - Namespace endpoint, which is an in-memory SPARQL endpoint over the app's ontology
- The HTTP CRUD API is now Graph Store Protocol, not Linked Data Templates
- HTML documents are hydrated HTML fragments over AJAX
- XSLT stylesheets now load constraints and constructors using SPARQL over the namespace endpoint
- The URIs of ontology terms are not relative to the app's base URI anymore
- Additional assertions added to external ontology terms instead of subclassing them
- Every UI state generates a distinct URL which is loaded consistently on both server- and client-side
- Upgraded Jena to 4.3.2
- Upgraded Saxon-JS to 2.3
- Upgraded Fuseki, Varnish and nginx Docker images
- Linked Data Templates support (still supported by Processor)
- HTTP smoke tests for SPARQL endpoint and Graph Store
- HTTP test for RDF import without mapping query
add-data.sh
CLI script which POSTs RDF data to URLExceptionMapper
constructors with injection in order to align with Processor- An option to override request URI using the
?uri=
URL param, implemented inApplicationFilter
Dispatcher
as the new "entrypoint" JAX-RS resource which routes betweenResourceBase
(if app is not empty) andProxyResourceBase
(if app is empty)- Missing XML namespace definitions to client-side XSLT stylesheets
$output-json-ld
parameter inxhtml:Script
template which outputs the RDF document as JSON-LD in the<script>
element
select-labelled
query in the end-user dataset to include a default graph patternspin:query
property is now optional forapl:RDFImport
- Entrypoint script logic to load agent metadata only when
$LOAD_DATASETS
is true - Injecting
Optional<Application>
,Optional<Service>
,Optional<Ontology>
instead ofApplication
,Service
,Ontology
- Using
javax.inject.Provider<>
for injection into providers that are not in the request scope - If no application matches request URI,
NotFoundException
is not thrown anymore --Optional.empty()
is used as application instead - Auth filters skipped if the matched application is not an instance of
lapp:EndUserApplication
orlapp:AdminApplication
- Simplified
ResourceBase::describe
by removing the?uri=
indirection logic
- Proxy injections from injection factory binders
- varnish-admin service that proxy-caches the fuseki-admin triplestore
purge_backend_cache
function to the HTTP test runner script run.shpurge_backend_cache
calls to clear proxy caches before each HTTP scriptBackendInvalidationFilter
response filter with backend proxy cache invalidation heuristics- Basic environment variable documentation to README
- Upgraded Processor and Web-Client to the latest versions
- Upgraded Saxon-JS to 2.1
- End-user and admin Services passed to import
Executor
instead ofDatasetAccessor
- Defined HTTP method -> ACL mode mapping as the
AuthorizationFilter.ACCESS_MODES
map
- Unused Docker mounts from linkeddatahub service
ban()
calls fromResourceBase
-- now handled by theBackendInvalidationFilter
apl:baseUri
as a static XSLT stylesheet param
bs2:PropertyControl
XSLT mode can handle multiple RDF types on a resource- Replaced error alerts with inline HTML warning blocks
- Refactored
bs2:SignUp
template to make it more extensible
ORDER BY
inapl:ResultCounts
mode in client.xsl
$request_base
parameter support in scripts allows to use a base URI for HTTP requests which is different from the RDF dataset base URI. Useful when multiple LDH instances on different domains or port numbers are backed by the same dataset. E.g. one with WebID-TLS auth enabled and the other without.- Dydra-specific
QuadStoreClient
andGraphStoreClient
with support for asynchonous GSP requests
- Ontology classes that used to be in the
ns:
namespace (${base}ns#
) moved tonsds:
(${base}ns/domain/system#
) - Ontology classes that used to be in the
def:
namespace (${base}def#
) moved tonsdd:
(${base}ns/domain/default#
) python
usages replaced withpython2
in CLI scripts- Mounting only
ssl/owner/public.pem
instead of the wholessl/owner
folder which includes the private key
- Expensive join with the provenance graph from the
laclt:ConstructAgentItem
query. As a result,dct:created
value is not included in agent's description. - Unnecessary methods from the
Import
Java interface. Passing arguments directly toImportListener
instead