diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java
index 6541cc44b..749c10d7e 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java
@@ -131,6 +131,15 @@ public String getSystemId() {
return systemId != null ? systemId.getParameterWithoutFirstAndLastChar() : null;
}
+ /**
+ * Returns the system if node and null otherwise.
+ *
+ * @return the system if node and null otherwise.
+ */
+ public DTDDeclParameter getSystemIdNode() {
+ return systemId;
+ }
+
public void setSystemId(int start, int end) {
systemId = addNewParameter(start, end);
}
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java
index 0ce9f069c..444a4522a 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java
@@ -21,6 +21,7 @@
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMDocumentType;
import org.eclipse.lemminx.dom.DOMRange;
+import org.eclipse.lemminx.dom.DTDEntityDecl;
import org.eclipse.lemminx.dom.NoNamespaceSchemaLocation;
import org.eclipse.lemminx.dom.SchemaLocation;
import org.eclipse.lemminx.dom.SchemaLocationHint;
@@ -28,6 +29,7 @@
import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
import org.eclipse.lsp4j.DocumentLink;
+import org.w3c.dom.NamedNodeMap;
/**
* Document link for :
@@ -35,6 +37,8 @@
*
* - XML Schema xsi:noNamespaceSchemaLocation
* - DTD SYSTEM (ex :
+ *
- Entity SYSTEM (ex : )
* - XML Schema xsi:schemaLocation
*
*
@@ -51,25 +55,10 @@ public ContentModelDocumentLinkParticipant(URIResolverExtensionManager resolverM
@Override
public void findDocumentLinks(DOMDocument document, List links) {
- // Document link for xsi:noNamespaceSchemaLocation
- NoNamespaceSchemaLocation noNamespaceSchemaLocation = document.getNoNamespaceSchemaLocation();
- if (noNamespaceSchemaLocation != null) {
- try {
- String location = resolverManager.resolve(document.getDocumentURI(), null,
- noNamespaceSchemaLocation.getLocation());
- if (location != null) {
- DOMRange attrValue = noNamespaceSchemaLocation.getAttr().getNodeAttrValue();
- if (attrValue != null) {
- links.add(createDocumentLink(attrValue, location, true));
- }
- }
- } catch (BadLocationException e) {
- // Do nothing
- }
- }
// Document link for DTD
DOMDocumentType docType = document.getDoctype();
if (docType != null) {
+ // links) {
// Do nothing
}
}
+
+ //
+ NamedNodeMap entities = docType.getEntities();
+ for (int i = 0; i < entities.getLength(); i++) {
+ DTDEntityDecl entity = (DTDEntityDecl) entities.item(i);
+ location = resolverManager.resolve(document.getDocumentURI(), entity.getPublicId(),
+ entity.getSystemId());
+ if (location != null) {
+ try {
+ DOMRange systemIdRange = entity.getSystemIdNode();
+ if (systemIdRange != null) {
+ links.add(createDocumentLink(systemIdRange, location, true));
+ }
+ } catch (BadLocationException e) {
+ // Do nothing
+ }
+ }
+ }
}
+
// Document link for xml-model/href
List xmlModels = document.getXMLModels();
for (XMLModel xmlModel : xmlModels) {
@@ -98,6 +106,24 @@ public void findDocumentLinks(DOMDocument document, List links) {
}
}
}
+
+ // Document link for xsi:noNamespaceSchemaLocation
+ NoNamespaceSchemaLocation noNamespaceSchemaLocation = document.getNoNamespaceSchemaLocation();
+ if (noNamespaceSchemaLocation != null) {
+ try {
+ String location = resolverManager.resolve(document.getDocumentURI(), null,
+ noNamespaceSchemaLocation.getLocation());
+ if (location != null) {
+ DOMRange attrValue = noNamespaceSchemaLocation.getAttr().getNodeAttrValue();
+ if (attrValue != null) {
+ links.add(createDocumentLink(attrValue, location, true));
+ }
+ }
+ } catch (BadLocationException e) {
+ // Do nothing
+ }
+ }
+
// Doc link for xsi:schemaLocation
SchemaLocation schemaLocation = document.getSchemaLocation();
if (schemaLocation != null) {
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/DTDPlugin.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/DTDPlugin.java
index a70c1a26f..2537c0a27 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/DTDPlugin.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/DTDPlugin.java
@@ -17,6 +17,7 @@
import org.eclipse.lemminx.extensions.dtd.contentmodel.CMDTDContentModelProvider;
import org.eclipse.lemminx.extensions.dtd.participants.DTDCodeLensParticipant;
import org.eclipse.lemminx.extensions.dtd.participants.DTDDefinitionParticipant;
+import org.eclipse.lemminx.extensions.dtd.participants.DTDDocumentLinkParticipant;
import org.eclipse.lemminx.extensions.dtd.participants.DTDHighlightingParticipant;
import org.eclipse.lemminx.extensions.dtd.participants.DTDReferenceParticipant;
import org.eclipse.lemminx.extensions.dtd.participants.diagnostics.DTDDiagnosticsParticipant;
@@ -27,6 +28,7 @@
import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lemminx.services.extensions.codelens.ICodeLensParticipant;
import org.eclipse.lemminx.services.extensions.diagnostics.IDiagnosticsParticipant;
+import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
import org.eclipse.lsp4j.InitializeParams;
/**
@@ -39,6 +41,7 @@ public class DTDPlugin implements IXMLExtension {
private final IHighlightingParticipant highlightingParticipant;
private final IReferenceParticipant referenceParticipant;
private final ICodeLensParticipant codeLensParticipant;
+ private DTDDocumentLinkParticipant documentLinkParticipant;
public DTDPlugin() {
definitionParticipant = new DTDDefinitionParticipant();
@@ -64,6 +67,9 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
registry.registerReferenceParticipant(referenceParticipant);
// register codelens participant
registry.registerCodeLensParticipant(codeLensParticipant);
+ // register document link participant
+ URIResolverExtensionManager resolverManager = registry.getComponent(URIResolverExtensionManager.class);
+ documentLinkParticipant = new DTDDocumentLinkParticipant(resolverManager);
}
@Override
@@ -78,5 +84,7 @@ public void stop(XMLExtensionsRegistry registry) {
registry.unregisterReferenceParticipant(referenceParticipant);
// unregister codelens participant
registry.unregisterCodeLensParticipant(codeLensParticipant);
+ // unregister document link participant
+ registry.unregisterDocumentLinkParticipant(documentLinkParticipant);
}
-}
+}
\ No newline at end of file
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/participants/DTDDocumentLinkParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/participants/DTDDocumentLinkParticipant.java
new file mode 100644
index 000000000..cf36ba643
--- /dev/null
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/participants/DTDDocumentLinkParticipant.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+* Copyright (c) 2022 Red Hat Inc. and others.
+* All rights reserved. This program and the accompanying materials
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v20.html
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* Contributors:
+* Red Hat Inc. - initial API and implementation
+*******************************************************************************/
+package org.eclipse.lemminx.extensions.dtd.participants;
+
+import static org.eclipse.lemminx.utils.XMLPositionUtility.createDocumentLink;
+
+import java.util.List;
+
+import org.eclipse.lemminx.commons.BadLocationException;
+import org.eclipse.lemminx.dom.DOMDocument;
+import org.eclipse.lemminx.dom.DOMDocumentType;
+import org.eclipse.lemminx.dom.DOMRange;
+import org.eclipse.lemminx.dom.DTDEntityDecl;
+import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
+import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
+import org.eclipse.lsp4j.DocumentLink;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * Document link for DTD entities system inside a DTD:
+ *
+ *
+ *
+ *
+ *
+ * @author Angelo ZERR
+ *
+ */
+public class DTDDocumentLinkParticipant implements IDocumentLinkParticipant {
+
+ private final URIResolverExtensionManager resolverManager;
+
+ public DTDDocumentLinkParticipant(URIResolverExtensionManager resolverManager) {
+ this.resolverManager = resolverManager;
+ }
+
+ @Override
+ public void findDocumentLinks(DOMDocument document, List links) {
+ // Document link for DTD
+ DOMDocumentType docType = document.getDoctype();
+ if (docType != null) {
+ // Loop for each entities declaration
+ NamedNodeMap entities = docType.getEntities();
+ for (int i = 0; i < entities.getLength(); i++) {
+ DTDEntityDecl entity = (DTDEntityDecl) entities.item(i);
+ String location = resolverManager.resolve(document.getDocumentURI(), entity.getPublicId(),
+ entity.getSystemId());
+ if (location != null) {
+ try {
+ // The entity declares a SYSTEM like
+ //
+ DOMRange systemIdRange = entity.getSystemIdNode();
+ if (systemIdRange != null) {
+ links.add(createDocumentLink(systemIdRange, location, true));
+ }
+ } catch (BadLocationException e) {
+ // Do nothing
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/DTDDocumentLinkTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/DTDDocumentLinkTest.java
index 171d5655d..8f3a8e9f3 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/DTDDocumentLinkTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/DTDDocumentLinkTest.java
@@ -56,6 +56,19 @@ public void noLinks() throws BadLocationException {
XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml");
}
+ @Test
+ public void entity() throws BadLocationException {
+ String xml = "\r\n" + //
+ " %document;\r\n" + //
+ " ]> \r\n" + //
+ " \r\n" + //
+ " ";
+ XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml",
+ dl(r(0, 63, 0, 78), "src/test/resources/docbookx.dtd"), //
+ dl(r(1, 29, 1, 44), "src/test/resources/document.ent"));
+ }
+
@Test
public void linkWithCatalogAndPublic() throws Exception {
// This test uses the local DTD with catalog-public.xml by using the PUBLIC ID
@@ -70,6 +83,6 @@ public void linkWithCatalogAndPublic() throws Exception {
"";
XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml",
"src/test/resources/catalogs/catalog-public.xml",
- dl(r(3,4,3,12), "src/test/resources/dtd/web-app_2_3.dtd"));
+ dl(r(3, 4, 3, 12), "src/test/resources/dtd/web-app_2_3.dtd"));
}
}
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/dtd/DTDDocumentLinkTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/dtd/DTDDocumentLinkTest.java
new file mode 100644
index 000000000..f8db29224
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/dtd/DTDDocumentLinkTest.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright (c) 2022 Red Hat Inc. and others.
+* All rights reserved. This program and the accompanying materials
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v20.html
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* Contributors:
+* Red Hat Inc. - initial API and implementation
+*******************************************************************************/
+package org.eclipse.lemminx.extensions.dtd;
+
+import static org.eclipse.lemminx.XMLAssert.dl;
+import static org.eclipse.lemminx.XMLAssert.r;
+
+import org.eclipse.lemminx.XMLAssert;
+import org.eclipse.lemminx.commons.BadLocationException;
+import org.junit.jupiter.api.Test;
+
+/**
+ * DTD entities document links tests inside a DTD.
+ *
+ */
+public class DTDDocumentLinkTest {
+
+ @Test
+ public void entity() throws BadLocationException {
+ String xml = "";
+ XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.dtd",
+ dl(r(0, 28, 0, 43), "src/test/resources/document.ent"));
+ }
+}