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 ff2eec25c..6541cc44b 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
@@ -114,7 +114,7 @@ public String getNotationName() {
*/
@Override
public String getPublicId() {
- return publicId != null ? publicId.getParameter() : null;
+ return publicId != null ? publicId.getParameterWithoutFirstAndLastChar() : null;
}
public void setPublicId(int start, int end) {
@@ -128,7 +128,7 @@ public void setPublicId(int start, int end) {
*/
@Override
public String getSystemId() {
- return systemId != null ? systemId.getParameter() : null;
+ return systemId != null ? systemId.getParameterWithoutFirstAndLastChar() : null;
}
public void setSystemId(int start, int end) {
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java
index 869910e59..36131e152 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java
@@ -54,7 +54,7 @@ void setPublicId(int start, int end) {
}
public String getPublicId() {
- return publicId != null ? publicId.getParameter() : null;
+ return publicId != null ? publicId.getParameterWithoutFirstAndLastChar() : null;
}
void setSystemId(int start, int end) {
@@ -62,7 +62,7 @@ void setSystemId(int start, int end) {
}
public String getSystemId() {
- return systemId != null ? systemId.getParameter() : null;
+ return systemId != null ? systemId.getParameterWithoutFirstAndLastChar() : null;
}
@Override
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/contentmodel/CMDTDDocument.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/contentmodel/CMDTDDocument.java
index 9da84dd67..4175415e8 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/contentmodel/CMDTDDocument.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/dtd/contentmodel/CMDTDDocument.java
@@ -28,6 +28,7 @@
import org.apache.xerces.impl.dtd.DTDGrammar;
import org.apache.xerces.impl.dtd.XMLDTDLoader;
import org.apache.xerces.xni.Augmentations;
+import org.apache.xerces.xni.XMLResourceIdentifier;
import org.apache.xerces.xni.XMLString;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.grammars.Grammar;
@@ -101,12 +102,28 @@ private static class ScannedDTDEntityDecl extends DTDEntityDecl {
private final String entityName;
private final String value;
+
private final DTDDeclParameter nameParameter;
+ private final String publicId;
+
+ private final String systemId;
+
public ScannedDTDEntityDecl(String entityName, String value, ScannedEntity scannedEntity) {
+ this(entityName, value, null, scannedEntity);
+ }
+
+ public ScannedDTDEntityDecl(String name, XMLResourceIdentifier identifier, ScannedEntity scannedEntity) {
+ this(name, null, identifier, scannedEntity);
+ }
+
+ private ScannedDTDEntityDecl(String entityName, String value, XMLResourceIdentifier identifier,
+ ScannedEntity scannedEntity) {
super(-1, -1);
this.entityName = entityName;
this.value = value;
+ this.publicId = identifier != null ? identifier.getPublicId() : null;
+ this.systemId = identifier != null ? identifier.getLiteralSystemId() : null;
this.nameParameter = createNameParameter(entityName, scannedEntity);
}
@@ -130,6 +147,16 @@ public String getNotationName() {
return value;
}
+ @Override
+ public String getSystemId() {
+ return systemId;
+ }
+
+ @Override
+ public String getPublicId() {
+ return publicId;
+ }
+
private static DTDDeclParameter createNameParameter(String name, ScannedEntity scannedEntity) {
String systemId = scannedEntity.entityLocation.getExpandedSystemId();
int lineNumber = scannedEntity.lineNumber - 1;
@@ -170,7 +197,8 @@ private static int getEntityNameStartColumnNumber(String entityName, ScannedEnti
char[] ch = scannedEntity.ch;
int wordIndex = entityName.length(); //
int startEntityNameIndex = -1;
- // Loop for characters from the end of the entity (>) to search the entity name start offset
+ // Loop for characters from the end of the entity (>) to search the entity name
+ // start offset
// |
for (int i = endEntityIndex; i >= 0; i--) {
char c = ch[i];
@@ -292,6 +320,17 @@ public void internalEntityDecl(String name, XMLString text, XMLString nonNormali
}
}
+ @Override
+ public void externalEntityDecl(String name, XMLResourceIdentifier identifier, Augmentations augs)
+ throws XNIException {
+ super.externalEntityDecl(name, identifier, augs);
+ try {
+ entities.add(new ScannedDTDEntityDecl(name, identifier, fEntityManager.getCurrentEntity()));
+ } catch (Exception e) {
+ LOGGER.log(Level.SEVERE, "Error while extracting information for the external entity '" + name + "'", e);
+ }
+ }
+
@Override
public void startContentModel(String elementName, Augmentations augs) throws XNIException {
if (hierarchiesMap == null) {
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/EntitiesDocumentationUtils.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/EntitiesDocumentationUtils.java
index ba1d022db..8f3e88b78 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/EntitiesDocumentationUtils.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/EntitiesDocumentationUtils.java
@@ -12,6 +12,7 @@
*/
package org.eclipse.lemminx.extensions.entities;
+import org.eclipse.lemminx.dom.DTDEntityDecl;
import org.eclipse.lsp4j.MarkupContent;
import org.eclipse.lsp4j.MarkupKind;
@@ -64,6 +65,19 @@ public String getValue() {
private EntitiesDocumentationUtils() {
}
+ public static MarkupContent getDocumentation(String entityName, String entityValue, EntityOriginType type,
+ boolean markdown) {
+ return getDocumentation(entityName, entityValue, null, null, null, type, markdown);
+ }
+
+ public static MarkupContent getDocumentation(DTDEntityDecl entity, EntityOriginType type, boolean markdown) {
+ String systemID = entity.getSystemId();
+ String publicID = entity.getPublicId();
+ String targetURI = entity.getNameParameter().getTargetURI();
+ return getDocumentation(entity.getName(), entity.getNotationName(), systemID, publicID, targetURI, type,
+ markdown);
+ }
+
/**
* Returns the entity documentation.
*
@@ -74,8 +88,8 @@ private EntitiesDocumentationUtils() {
* false otherwise.
* @return the entity documentation.
*/
- public static MarkupContent getDocumentation(String entityName, String entityValue, EntityOriginType type,
- boolean markdown) {
+ public static MarkupContent getDocumentation(String entityName, String entityValue, String systemID,
+ String publicID, String targetURI, EntityOriginType type, boolean markdown) {
StringBuilder documentation = new StringBuilder();
// Title
@@ -88,15 +102,32 @@ public static MarkupContent getDocumentation(String entityName, String entityVal
documentation.append("**");
}
- if (entityValue != null && !entityValue.isEmpty()) {
- addParameter("Value", entityValue, documentation, markdown);
- }
+ addParameter("Value", entityValue, documentation, markdown);
addParameter("Type", type.getLabel(), documentation, markdown);
+ addParameter("Public ID", publicID, documentation, markdown);
+ addParameter("System ID", systemID, documentation, markdown);
+ if (targetURI != null) {
+ documentation.append(System.lineSeparator());
+ if (markdown) {
+ documentation.append(" * ");
+ }
+ documentation.append("Source: ");
+ if (markdown) {
+ documentation.append("[");
+ documentation.append(getFileName(targetURI));
+ documentation.append("]");
+ documentation.append("(");
+ }
+ documentation.append(targetURI);
+ if (markdown) {
+ documentation.append(")");
+ }
+ }
return new MarkupContent(markdown ? MarkupKind.MARKDOWN : MarkupKind.PLAINTEXT, documentation.toString());
}
private static void addParameter(String name, String value, StringBuilder documentation, boolean markdown) {
- if (value != null) {
+ if (value != null && !value.isEmpty()) {
documentation.append(System.lineSeparator());
if (markdown) {
documentation.append(" * ");
@@ -113,4 +144,20 @@ private static void addParameter(String name, String value, StringBuilder docume
}
}
+ /**
+ * Returns the file name from the given schema URI
+ *
+ * @param schemaURI the schema URI
+ * @return the file name from the given schema URI
+ */
+ private static String getFileName(String schemaURI) {
+ int index = schemaURI.lastIndexOf('/');
+ if (index == -1) {
+ index = schemaURI.lastIndexOf('\\');
+ }
+ if (index == -1) {
+ return schemaURI;
+ }
+ return schemaURI.substring(index + 1, schemaURI.length());
+ }
}
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesCompletionParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesCompletionParticipant.java
index 9826a37d6..360906f21 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesCompletionParticipant.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesCompletionParticipant.java
@@ -17,6 +17,7 @@
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMDocumentType;
+import org.eclipse.lemminx.dom.DTDEntityDecl;
import org.eclipse.lemminx.extensions.contentmodel.model.CMDocument;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.entities.EntitiesDocumentationUtils;
@@ -30,6 +31,7 @@
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;
+import org.eclipse.lsp4j.MarkupContent;
import org.eclipse.lsp4j.MarkupKind;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
@@ -78,8 +80,9 @@ private static void collectLocalEntityProposals(DOMDocument document, Range enti
Entity entity = (Entity) entities.item(i);
if (entity.getNodeName() != null) {
// provide completion for the locally declared entity
- fillCompletion(entity.getNodeName(), entity.getNotationName(), EntityOriginType.LOCAL, entityRange,
- markdown, response);
+ MarkupContent documentation = EntitiesDocumentationUtils.getDocumentation((DTDEntityDecl) entity,
+ EntityOriginType.LOCAL, markdown);
+ fillCompletion(entity.getNodeName(), documentation, entityRange, response);
}
}
}
@@ -103,8 +106,9 @@ private static void collectExternalEntityProposals(DOMDocument document, Range e
for (Entity entity : entities) {
if (entity.getNodeName() != null) {
// provide completion for the external declared entity
- fillCompletion(entity.getNodeName(), entity.getNotationName(), EntityOriginType.EXTERNAL,
- entityRange, markdown, response);
+ MarkupContent documentation = EntitiesDocumentationUtils.getDocumentation((DTDEntityDecl) entity,
+ EntityOriginType.EXTERNAL, markdown);
+ fillCompletion(entity.getNodeName(), documentation, entityRange, response);
}
}
}
@@ -123,13 +127,14 @@ private static void collectExternalEntityProposals(DOMDocument document, Range e
private void collectPredefinedEntityProposals(Range entityRange, boolean markdown, ICompletionResponse response) {
PredefinedEntity[] entities = PredefinedEntity.values();
for (PredefinedEntity entity : entities) {
- fillCompletion(entity.getName(), entity.getValue(), EntityOriginType.PREDEFINED, entityRange, markdown,
- response);
+ MarkupContent documentation = EntitiesDocumentationUtils.getDocumentation(entity.getName(),
+ entity.getValue(), EntityOriginType.PREDEFINED, markdown);
+ fillCompletion(entity.getName(), documentation, entityRange, response);
}
}
- private static void fillCompletion(String name, String entityValue, EntityOriginType type, Range entityRange,
- boolean markdown, ICompletionResponse response) {
+ private static void fillCompletion(String name, MarkupContent documentation, Range entityRange,
+ ICompletionResponse response) {
String entityName = "&" + name + ";";
CompletionItem item = new CompletionItem();
item.setLabel(entityName);
@@ -138,7 +143,7 @@ private static void fillCompletion(String name, String entityValue, EntityOrigin
String insertText = entityName;
item.setFilterText(insertText);
item.setTextEdit(new TextEdit(entityRange, insertText));
- item.setDocumentation(EntitiesDocumentationUtils.getDocumentation(name, entityValue, type, markdown));
+ item.setDocumentation(documentation);
response.addCompletionItem(item);
}
diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesHoverParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesHoverParticipant.java
index 33fa67b11..2af1232f1 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesHoverParticipant.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/entities/participants/EntitiesHoverParticipant.java
@@ -136,8 +136,7 @@ private static MarkupContent searchInLocalEntities(String entityName, Range enti
DTDEntityDecl entity = (DTDEntityDecl) entities.item(i);
if (entityName.equals(entity.getName())) {
boolean markdown = request.canSupportMarkupKind(MarkupKind.MARKDOWN);
- return EntitiesDocumentationUtils.getDocumentation(entity.getName(), entity.getNotationName(),
- EntityOriginType.LOCAL, markdown);
+ return EntitiesDocumentationUtils.getDocumentation(entity, EntityOriginType.LOCAL, markdown);
}
}
return null;
@@ -164,8 +163,7 @@ private static MarkupContent searchInExternalEntities(String entityName, Range e
DTDEntityDecl entity = (DTDEntityDecl) ent;
if (entityName.equals(entity.getName())) {
boolean markdown = request.canSupportMarkupKind(MarkupKind.MARKDOWN);
- return EntitiesDocumentationUtils.getDocumentation(entity.getName(), entity.getNotationName(),
- EntityOriginType.EXTERNAL, markdown);
+ return EntitiesDocumentationUtils.getDocumentation(entity, EntityOriginType.EXTERNAL, markdown);
}
}
}
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/dom/DOMParserForInternalDTDTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/dom/DOMParserForInternalDTDTest.java
index b030f5ee4..82c382d38 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/dom/DOMParserForInternalDTDTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/dom/DOMParserForInternalDTDTest.java
@@ -514,8 +514,8 @@ public void entityDeclWithNameClosedAndParameters() {
assertEquals("%", entityDecl.getPercent());
assertEquals("eName", entityDecl.getNodeName());
assertEquals("PUBLIC", entityDecl.getKind());
- assertEquals("\"publicId\"", entityDecl.getPublicId());
- assertEquals("\"systemId\"", entityDecl.getSystemId());
+ assertEquals("publicId", entityDecl.getPublicId());
+ assertEquals("systemId", entityDecl.getSystemId());
// element
assertTrue(actual.getChild(1).isElement());
@@ -544,7 +544,7 @@ public void entityDeclWithNameClosedAndSomeParameters() {
assertEquals("%", entityDecl.getPercent());
assertEquals("eName", entityDecl.getNodeName());
assertEquals("PUBLIC", entityDecl.getKind());
- assertEquals("\"publicId\"", entityDecl.getPublicId());
+ assertEquals("publicId", entityDecl.getPublicId());
assertEquals(null, entityDecl.getSystemId());
// element
@@ -772,8 +772,8 @@ public void dtdNotationComplete() {
assertEquals(65, elementDecl.getEnd());
assertEquals("Name", elementDecl.getName());
assertEquals("PUBLIC", elementDecl.getKind());
- assertEquals("\"PublicID\"", elementDecl.getPublicId());
- assertEquals("\"SystemID\"", elementDecl.getSystemId());
+ assertEquals("PublicID", elementDecl.getPublicId());
+ assertEquals("SystemID", elementDecl.getSystemId());
assertTrue(elementDecl.isClosed());
}
@@ -805,7 +805,7 @@ public void dtdNotationSYSTEMUnrecognizedParameter() {
assertEquals(65, elementDecl.getEnd());
assertEquals("Name", elementDecl.getName());
assertEquals("SYSTEM", elementDecl.getKind());
- assertEquals("\"PublicID\"", elementDecl.getSystemId());
+ assertEquals("PublicID", elementDecl.getSystemId());
assertEquals("\"SystemID\"", elementDecl.getUnrecognized());
assertTrue(elementDecl.isClosed());
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 ae95d9b01..facf11a6d 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
@@ -27,29 +27,29 @@ 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"));
+ dl(r(1, 31, 1, 55), "src/test/resources/dtd/entities/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"));
+ dl(r(1, 38, 1, 62), "src/test/resources/dtd/entities/base.dtd"));
}
@Test
public void noLinks() throws BadLocationException {
String xml = "\r\n" + //
- "\r\n" + //
"";
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesCompletionExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesCompletionExtensionsTest.java
index b7b460c92..844855e0b 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesCompletionExtensionsTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesCompletionExtensionsTest.java
@@ -28,6 +28,21 @@ public class EntitiesCompletionExtensionsTest {
// Test for local entities
+ @Test
+ public void localWithSYSTEM() throws BadLocationException {
+ // &|
+ String xml = "\r\n" + //
+ " \r\n" + //
+ " \r\n" + //
+ " ]>\r\n" + //
+ " &|";
+ testCompletionFor(xml, 1 + //
+ 2 /* CDATA and Comments */ + //
+ PredefinedEntity.values().length /* predefined entities */, //
+ c("&c;", "&c;", r(5, 12, 5, 13), "&c;"));
+ }
+
@Test
public void afterAmp() throws BadLocationException {
// &|
@@ -125,10 +140,11 @@ public void none() throws BadLocationException {
}
// Test for external entities
+
@Test
public void external() throws BadLocationException {
String xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -141,12 +157,24 @@ public void external() throws BadLocationException {
c("&foo;", "&foo;", r(6, 1, 6, 2), "&foo;"));
}
+ @Test
+ public void externalWithSYSTEM() throws BadLocationException {
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "&|";
+ testCompletionFor(xml, null, "test.xml", 2 + //
+ 2 /* CDATA and Comments */ + //
+ PredefinedEntity.values().length /* predefined entities */,
+ c("&writer;", "&writer;", r(2, 8, 2, 9), "&writer;"), //
+ c("©right;", "©right;", r(2, 8, 2, 9), "©right;"));
+ }
+
@Test
public void bug_vscode_xml_262() throws BadLocationException {
// See
// https://github.com/redhat-developer/vscode-xml/issues/262#issuecomment-634716408
String xml = "\r\n" + //
- "\r\n"
+ "\r\n"
+ //
"]>\r\n" + //
"\r\n" + //
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesDefinitionExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesDefinitionExtensionsTest.java
index c05f8d6cf..d9c024f74 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesDefinitionExtensionsTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesDefinitionExtensionsTest.java
@@ -39,6 +39,17 @@ public void local() throws BadLocationException {
testDefinitionFor(xml, "test.xml", ll("test.xml", r(5, 2, 5, 9), r(2, 11, 2, 16)));
}
+ @Test
+ public void localWithSYSTEM() throws BadLocationException {
+ String xml = "\r\n" + //
+ " \r\n" + //
+ " \r\n" + //
+ " ]>\r\n" + //
+ " &|c;";
+ testDefinitionFor(xml, "test.xml", ll("test.xml", r(5, 12, 5, 15), r(3, 12, 3, 13)));
+ }
+
@Test
public void beforeAmp() throws BadLocationException {
String xml = "\r\n" + //
@@ -92,9 +103,9 @@ public void underscoreEntityName() throws BadLocationException {
@Test
public void externalWithIndent() throws BadLocationException, MalformedURIException {
- String dtdFileURI = getDTDFileURI("src/test/resources/dtd/base.dtd");
+ String dtdFileURI = getDTDFileURI("src/test/resources/dtd/entities/base.dtd");
String xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -105,11 +116,11 @@ public void externalWithIndent() throws BadLocationException, MalformedURIExcept
@Test
public void externalWithDTDIndent() throws BadLocationException, MalformedURIException {
- String dtdFileURI = getDTDFileURI("src/test/resources/dtd/base-indent.dtd");
+ String dtdFileURI = getDTDFileURI("src/test/resources/dtd/entities/base-indent.dtd");
// &external3;
String xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -119,7 +130,7 @@ public void externalWithDTDIndent() throws BadLocationException, MalformedURIExc
// &external5;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -129,7 +140,7 @@ public void externalWithDTDIndent() throws BadLocationException, MalformedURIExc
// &external;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -139,7 +150,7 @@ public void externalWithDTDIndent() throws BadLocationException, MalformedURIExc
// &external2;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -150,11 +161,11 @@ public void externalWithDTDIndent() throws BadLocationException, MalformedURIExc
@Test
public void externalWithDTDNoIndent() throws BadLocationException, MalformedURIException {
- String dtdFileURI = getDTDFileURI("src/test/resources/dtd/base-no-indent.dtd");
+ String dtdFileURI = getDTDFileURI("src/test/resources/dtd/entities/base-no-indent.dtd");
// &external3;
String xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -164,7 +175,7 @@ public void externalWithDTDNoIndent() throws BadLocationException, MalformedURIE
// &external5;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -174,7 +185,7 @@ public void externalWithDTDNoIndent() throws BadLocationException, MalformedURIE
// &external;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -184,7 +195,7 @@ public void externalWithDTDNoIndent() throws BadLocationException, MalformedURIE
// &external2;
xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
@@ -193,6 +204,24 @@ public void externalWithDTDNoIndent() throws BadLocationException, MalformedURIE
testDefinitionFor(xml, "test.xml", ll(dtdFileURI, r(6, 1, 6, 12), r(4, 9, 4, 18)));
}
+ @Test
+ public void externalWithSYSTEM() throws BadLocationException, MalformedURIException {
+ String dtdFileURI = getDTDFileURI("src/test/resources/dtd/entities/base-system.dtd");
+
+ // &writer;
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "&wr|iter;©right;";
+ testDefinitionFor(xml, "test.xml", ll(dtdFileURI, r(2, 8, 2, 16), r(1, 9, 1, 15)));
+
+ // ©right;
+ xml = "\r\n" + //
+ "\r\n" + //
+ "&writer;&cop|yright;";
+ testDefinitionFor(xml, "test.xml", ll(dtdFileURI, r(2, 16, 2, 27), r(2, 9, 2, 18)));
+
+ }
+
private static String getDTDFileURI(String dtdURI) throws MalformedURIException {
return XMLEntityManager.expandSystemId(dtdURI, "test.xml", true).replace("///", "/");
}
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesHoverExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesHoverExtensionsTest.java
index 9eb9f3777..df2566b51 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesHoverExtensionsTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/entities/EntitiesHoverExtensionsTest.java
@@ -15,6 +15,8 @@
import static org.eclipse.lemminx.XMLAssert.assertHover;
import static org.eclipse.lemminx.XMLAssert.r;
+import org.apache.xerces.impl.XMLEntityManager;
+import org.apache.xerces.util.URI.MalformedURIException;
import org.eclipse.lemminx.commons.BadLocationException;
import org.junit.jupiter.api.Test;
@@ -35,33 +37,89 @@ public void local() throws BadLocationException {
"\r\n" + //
" &mdas|h;\r\n" + // <- here definition for mdash
"";
- assertHover(xml, "**Entity mdash**" + //
+ assertHover(xml, "src/test/resources/test.xml", "**Entity mdash**" + //
System.lineSeparator() + //
" * Value: `—`" + //
System.lineSeparator() + //
- " * Type: `Local`", //
+ " * Type: `Local`" + //
+ System.lineSeparator() + //
+ " * Source: [test.xml](src/test/resources/test.xml)", //
r(5, 2, 5, 9));
}
+ @Test
+ public void localWithSYSTEM() throws BadLocationException {
+ String xml = "\r\n" + //
+ " \r\n" + //
+ " \r\n" + //
+ " ]>\r\n" + //
+ " &|c;";
+ assertHover(xml, "src/test/resources/test.xml", "**Entity c**" + //
+ System.lineSeparator() + //
+ " * Type: `Local`" + //
+ System.lineSeparator() + //
+ " * System ID: `http://www.xmlwriter.net/copyright.xml`" + //
+ System.lineSeparator() + //
+ " * Source: [test.xml](src/test/resources/test.xml)", //
+ r(5, 12, 5, 15));
+ }
+
// Test for external entities
@Test
- public void external() throws BadLocationException {
+ public void external() throws Exception {
+ String baseDTDURI = getDTDFileURI("base.dtd");
String xml = "\r\n" + //
- "\r\n" + //
"]>\r\n" + //
"\r\n" + //
"\r\n &f|oo;" + //
"";
- assertHover(xml, "test.xml", "**Entity foo**" + //
+ assertHover(xml, "src/test/resources/test.xml", "**Entity foo**" + //
System.lineSeparator() + //
" * Value: `bar`" + //
System.lineSeparator() + //
- " * Type: `External`", //
+ " * Type: `External`" + //
+ System.lineSeparator() + //
+ " * Source: [base.dtd](" + baseDTDURI + ")", //
r(6, 1, 6, 6));
}
+ @Test
+ public void externalWithSYSTEM() throws Exception {
+ String baseDTDURI = getDTDFileURI("base-system.dtd");
+
+ // &writer;
+ String xml = "\r\n" + //
+ "\r\n" + //
+ "&wr|iter;©right;";
+ assertHover(xml, "src/test/resources/test.xml", "**Entity writer**" + //
+ System.lineSeparator() + //
+ " * Type: `External`" + //
+ System.lineSeparator() + //
+ " * Public ID: `public id`" + //
+ System.lineSeparator() + //
+ " * System ID: `entity uri`" + //
+ System.lineSeparator() + //
+ " * Source: [base-system.dtd](" + baseDTDURI + ")", //
+ r(2, 8, 2, 16));
+
+ // ©right;
+ xml = "\r\n" + //
+ "\r\n" + //
+ "&writer;&cop|yright;";
+ assertHover(xml, "src/test/resources/test.xml", "**Entity copyright**" + //
+ System.lineSeparator() + //
+ " * Type: `External`" + //
+ System.lineSeparator() + //
+ " * System ID: `uri`" + //
+ System.lineSeparator() + //
+ " * Source: [base-system.dtd](" + baseDTDURI + ")", //
+ r(2, 16, 2, 27));
+ }
+
// Test for predefined entities
@Test
@@ -76,4 +134,8 @@ public void predefined() throws BadLocationException {
" * Type: `Predefined`", //
r(2, 2, 2, 7));
}
+
+ private static String getDTDFileURI(String dtdURI) throws MalformedURIException {
+ return XMLEntityManager.expandSystemId("dtd/entities/" + dtdURI, "src/test/resources/test.xml", true);
+ }
}
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/base-indent.dtd b/org.eclipse.lemminx/src/test/resources/dtd/entities/base-indent.dtd
similarity index 100%
rename from org.eclipse.lemminx/src/test/resources/dtd/base-indent.dtd
rename to org.eclipse.lemminx/src/test/resources/dtd/entities/base-indent.dtd
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/base-no-indent.dtd b/org.eclipse.lemminx/src/test/resources/dtd/entities/base-no-indent.dtd
similarity index 100%
rename from org.eclipse.lemminx/src/test/resources/dtd/base-no-indent.dtd
rename to org.eclipse.lemminx/src/test/resources/dtd/entities/base-no-indent.dtd
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/entities/base-system.dtd b/org.eclipse.lemminx/src/test/resources/dtd/entities/base-system.dtd
new file mode 100644
index 000000000..7a09dc33c
--- /dev/null
+++ b/org.eclipse.lemminx/src/test/resources/dtd/entities/base-system.dtd
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/base.dtd b/org.eclipse.lemminx/src/test/resources/dtd/entities/base.dtd
similarity index 100%
rename from org.eclipse.lemminx/src/test/resources/dtd/base.dtd
rename to org.eclipse.lemminx/src/test/resources/dtd/entities/base.dtd
diff --git a/org.eclipse.lemminx/src/test/resources/dtd/bug_vscode-xml_262.dtd b/org.eclipse.lemminx/src/test/resources/dtd/entities/bug_vscode-xml_262.dtd
similarity index 100%
rename from org.eclipse.lemminx/src/test/resources/dtd/bug_vscode-xml_262.dtd
rename to org.eclipse.lemminx/src/test/resources/dtd/entities/bug_vscode-xml_262.dtd