diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMDocument.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMDocument.java
index 2dafad2b2..3e57f3942 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMDocument.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DOMDocument.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2018 Angelo ZERR.
+ * Copyright (c) 2018-2020 Angelo ZERR.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -305,7 +305,7 @@ private NoNamespaceSchemaLocation createNoNamespaceSchemaLocation(DOMNode root,
if (attr == null || attr.getValue() == null) {
return null;
}
- return new NoNamespaceSchemaLocation(root.getOwnerDocument().getDocumentURI(), attr);
+ return new NoNamespaceSchemaLocation(attr);
}
// -------------------------- Grammar with DTD
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java
index 490837b4e..ee89b0d7d 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java
@@ -12,21 +12,15 @@
*/
package org.eclipse.lemminx.dom;
-import org.apache.xerces.impl.XMLEntityManager;
-import org.apache.xerces.util.URI.MalformedURIException;
-
/**
*
* The declared "xsi:noNamespaceSchemaLocation"
*/
public class NoNamespaceSchemaLocation {
- private final String documentURI;
-
private final DOMAttr attr;
- public NoNamespaceSchemaLocation(String documentURI, DOMAttr attr) {
- this.documentURI = documentURI;
+ public NoNamespaceSchemaLocation(DOMAttr attr) {
this.attr = attr;
}
@@ -45,21 +39,4 @@ public String getLocation() {
return attr.getValue();
}
- /**
- * Returns the expanded system location
- *
- * @return the expanded system location
- */
- public String getResolvedLocation() {
- return getResolvedLocation(documentURI, getLocation());
- }
-
- private String getResolvedLocation(String documentURI, String location) {
- try {
- return XMLEntityManager.expandSystemId(location, documentURI, false);
- } catch (MalformedURIException e) {
- return location;
- }
- }
-
}
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 87d3f92d3..5993a8918 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
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2018 Angelo ZERR
+ * Copyright (c) 2018-2020 Angelo ZERR
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -14,31 +14,81 @@
import java.util.List;
+import org.apache.xerces.impl.XMLEntityManager;
+import org.apache.xerces.util.URI.MalformedURIException;
import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.dom.DOMDocument;
+import org.eclipse.lemminx.dom.DOMDocumentType;
import org.eclipse.lemminx.dom.DOMNode;
+import org.eclipse.lemminx.dom.DOMRange;
import org.eclipse.lemminx.dom.NoNamespaceSchemaLocation;
import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
import org.eclipse.lsp4j.DocumentLink;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
+/**
+ * Document link for :
+ *
+ *
+ * - XML Schema xsi:noNamespaceSchemaLocation
+ * - DTD SYSTEM (ex :
+ *
+ *
+ * @author Angelo ZERR
+ *
+ */
public class ContentModelDocumentLinkParticipant implements IDocumentLinkParticipant {
@Override
public void findDocumentLinks(DOMDocument document, List links) {
+ // Document link for xsi:noNamespaceSchemaLocation
NoNamespaceSchemaLocation noNamespaceSchemaLocation = document.getNoNamespaceSchemaLocation();
if (noNamespaceSchemaLocation != null) {
try {
- String location = noNamespaceSchemaLocation.getResolvedLocation();
- DOMNode attrValue = noNamespaceSchemaLocation.getAttr().getNodeAttrValue();
- Position start = document.positionAt(attrValue.getStart() + 1);
- Position end = document.positionAt(attrValue.getEnd() - 1);
- links.add(new DocumentLink(new Range(start, end), location));
+ String location = getResolvedLocation(document.getDocumentURI(),
+ noNamespaceSchemaLocation.getLocation());
+ if (location != null) {
+ DOMNode attrValue = noNamespaceSchemaLocation.getAttr().getNodeAttrValue();
+ Position start = document.positionAt(attrValue.getStart() + 1);
+ Position end = document.positionAt(attrValue.getEnd() - 1);
+ links.add(new DocumentLink(new Range(start, end), location));
+ }
} catch (BadLocationException e) {
// Do nothing
}
}
+ // Document link for DTD
+ DOMDocumentType docType = document.getDoctype();
+ if (docType != null) {
+ String location = getResolvedLocation(document.getDocumentURI(), docType.getSystemIdWithoutQuotes());
+ if (location != null) {
+ try {
+ DOMRange sytemIdRange = docType.getSystemIdNode();
+ Position start = document.positionAt(sytemIdRange.getStart() + 1);
+ Position end = document.positionAt(sytemIdRange.getEnd() - 1);
+ links.add(new DocumentLink(new Range(start, end), location));
+ } catch (BadLocationException e) {
+ // Do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the expanded system location
+ *
+ * @return the expanded system location
+ */
+ private static String getResolvedLocation(String documentURI, String location) {
+ if (location == null) {
+ return null;
+ }
+ try {
+ return XMLEntityManager.expandSystemId(location, documentURI, false);
+ } catch (MalformedURIException e) {
+ return location;
+ }
}
}
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
new file mode 100644
index 000000000..ae95d9b01
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/DTDDocumentLinkTest.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright (c) 2020 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.contentmodel;
+
+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 document links tests
+ *
+ */
+public class DTDDocumentLinkTest {
+
+ @Test
+ public void docTypeSYSTEM() throws BadLocationException {
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "";
+ XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml",
+ dl(r(1, 31, 1, 46), "src/test/resources/dtd/base.dtd"));
+ }
+
+ @Test
+ public void docTypePUBLIC() throws BadLocationException {
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "";
+ XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml",
+ dl(r(1, 38, 1, 53), "src/test/resources/dtd/base.dtd"));
+ }
+
+ @Test
+ public void noLinks() throws BadLocationException {
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "";
+ XMLAssert.testDocumentLinkFor(xml, "src/test/resources/xml/base.xml");
+ }
+}
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/base.dtd b/org.eclipse.lemminx/src/test/resources/dtd/base.dtd
new file mode 100644
index 000000000..7f12a37b1
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/resources/dtd/base.dtd
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/org.eclipse.lemminx/src/test/resources/xml/base-public.xml b/org.eclipse.lemminx/src/test/resources/xml/base-public.xml
new file mode 100644
index 000000000..fb5161365
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/resources/xml/base-public.xml
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/org.eclipse.lemminx/src/test/resources/xml/base.xml b/org.eclipse.lemminx/src/test/resources/xml/base.xml
new file mode 100644
index 000000000..2ce75a3f9
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/resources/xml/base.xml
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file