Skip to content

Commit 4822007

Browse files
committed
Avoid duplicate xsl:import statements
Fixed whitespace Added HTTP test
1 parent 137cf06 commit 4822007

2 files changed

Lines changed: 73 additions & 5 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
initialize_dataset "$END_USER_BASE_URL" "$TMP_END_USER_DATASET" "$END_USER_ENDPOINT_URL"
5+
initialize_dataset "$ADMIN_BASE_URL" "$TMP_ADMIN_DATASET" "$ADMIN_ENDPOINT_URL"
6+
purge_cache "$END_USER_VARNISH_SERVICE"
7+
purge_cache "$ADMIN_VARNISH_SERVICE"
8+
purge_cache "$FRONTEND_VARNISH_SERVICE"
9+
10+
# Clean up any leftover package stylesheet files from previous test runs
11+
docker compose exec -T linkeddatahub rm -rf /usr/local/tomcat/webapps/ROOT/static/com/linkeddatahub/packages/skos 2>/dev/null || true
12+
docker compose exec -T linkeddatahub sed -i '/linkeddatahub\/packages\/skos\/layout.xsl/d' /usr/local/tomcat/webapps/ROOT/static/xsl/layout.xsl 2>/dev/null || true
13+
14+
# Tomcat caches static files with default cacheTtl=5000ms (5 seconds)
15+
# See: https://tomcat.apache.org/tomcat-10.1-doc/config/resources.html#Attributes
16+
default_ttl=5
17+
18+
# test package URI (SKOS package)
19+
package_uri="https://packages.linkeddatahub.com/skos/#this"
20+
21+
# first install
22+
install-package.sh \
23+
-b "$END_USER_BASE_URL" \
24+
-f "$OWNER_CERT_FILE" \
25+
-p "$OWNER_CERT_PWD" \
26+
--package "$package_uri"
27+
28+
# Wait for Tomcat's static resource cache to expire
29+
sleep $default_ttl
30+
31+
# verify exactly one import after first install
32+
import_count=$(curl -k -s "${END_USER_BASE_URL}static/xsl/layout.xsl" \
33+
| grep -c "com/linkeddatahub/packages/skos/layout.xsl" || true)
34+
if [ "$import_count" -ne 1 ]; then
35+
exit 1
36+
fi
37+
38+
# second install (same package)
39+
install-package.sh \
40+
-b "$END_USER_BASE_URL" \
41+
-f "$OWNER_CERT_FILE" \
42+
-p "$OWNER_CERT_PWD" \
43+
--package "$package_uri"
44+
45+
# Wait for Tomcat's static resource cache to expire
46+
sleep $default_ttl
47+
48+
# verify still exactly one import after second install (deduplication guard)
49+
import_count=$(curl -k -s "${END_USER_BASE_URL}static/xsl/layout.xsl" \
50+
| grep -c "com/linkeddatahub/packages/skos/layout.xsl" || true)
51+
if [ "$import_count" -ne 1 ]; then
52+
exit 1
53+
fi
54+
55+
# cleanup
56+
uninstall-package.sh \
57+
-b "$END_USER_BASE_URL" \
58+
-f "$OWNER_CERT_FILE" \
59+
-p "$OWNER_CERT_PWD" \
60+
--package "$package_uri"

src/main/java/com/atomgraph/linkeddatahub/server/util/XSLTMasterUpdater.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void addPackageImport(Path masterFile, String packagePath) throws IOExcep
8989
Element stylesheet = doc.getDocumentElement();
9090
String href = "../" + packagePath + "/layout.xsl";
9191

92-
// Find the last xsl:import child element as insertion anchor
92+
// Find the last xsl:import child element as insertion anchor, checking for duplicates
9393
Node lastImport = null;
9494
NodeList children = stylesheet.getChildNodes();
9595
for (int i = 0; i < children.getLength(); i++)
@@ -98,24 +98,32 @@ public void addPackageImport(Path masterFile, String packagePath) throws IOExcep
9898
if (child.getNodeType() == Node.ELEMENT_NODE
9999
&& XSL_NS.equals(child.getNamespaceURI())
100100
&& "import".equals(child.getLocalName()))
101+
{
102+
if (href.equals(((Element) child).getAttribute("href")))
103+
{
104+
if (log.isWarnEnabled()) log.warn("xsl:import href=\"{}\" already present in master stylesheet, skipping", href);
105+
return;
106+
}
101107
lastImport = child;
108+
}
102109
}
103110

104111
Element newImport = doc.createElementNS(XSL_NS, "xsl:import");
105112
newImport.setAttribute("href", href);
106113

107114
if (lastImport != null)
108115
{
109-
// Insert after the last import (before its next sibling)
110-
stylesheet.insertBefore(doc.createTextNode("\n "), lastImport.getNextSibling());
111-
stylesheet.insertBefore(newImport, lastImport.getNextSibling());
116+
// Capture anchor before any insertion — getNextSibling() shifts after insertBefore
117+
Node anchor = lastImport.getNextSibling();
118+
stylesheet.insertBefore(newImport, anchor);
119+
stylesheet.insertBefore(doc.createTextNode("\n "), newImport);
112120
}
113121
else
114122
{
115123
// No existing imports — prepend at start of stylesheet
116124
Node firstChild = stylesheet.getFirstChild();
117125
stylesheet.insertBefore(newImport, firstChild);
118-
stylesheet.insertBefore(doc.createTextNode("\n "), newImport.getNextSibling());
126+
stylesheet.insertBefore(doc.createTextNode("\n "), newImport);
119127
}
120128

121129
serializeDocument(doc, masterFile);

0 commit comments

Comments
 (0)