Skip to content

Commit

Permalink
Re-adjusted error range for bad schema location, need to filter it ou…
Browse files Browse the repository at this point in the history
…t duplicates

Fixes eclipse-lemminx#336, eclipse-lemminx#343

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen committed Apr 26, 2019
1 parent 3168b2c commit 2226771
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,11 @@ public boolean hasProlog() {
}

private SchemaLocation createSchemaLocation(DOMNode root, String schemaInstancePrefix) {
String value = root.getAttribute(getPrefixedName(schemaInstancePrefix, "schemaLocation"));
if (value == null) {
DOMAttr attr = root.getAttributeNode(getPrefixedName(schemaInstancePrefix, "schemaLocation"));
if (attr == null) {
return null;
}
return new SchemaLocation(root.getOwnerDocument().getDocumentURI(), value);
return new SchemaLocation(root.getOwnerDocument().getDocumentURI(), attr);
}

private NoNamespaceSchemaLocation createNoNamespaceSchemaLocation(DOMNode root, String schemaInstancePrefix) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ public class SchemaLocation {

private final Map<String, String> schemaLocationValuePairs;

public SchemaLocation(String base, String value) {
private final DOMAttr attr;

public SchemaLocation(String base, DOMAttr attr) {
this.attr = attr;
this.schemaLocationValuePairs = new HashMap<>();
String value = attr.getValue();
StringTokenizer st = new StringTokenizer(value);
do {
String namespaceURI = st.hasMoreTokens() ? st.nextToken() : null;
Expand Down Expand Up @@ -66,4 +70,8 @@ public boolean usesSchema(Path rootPath, Path xsdPath) {
return false;
}

public DOMAttr getAttr() {
return attr;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@
import java.util.HashMap;
import java.util.Map;

import javax.xml.validation.Schema;

import org.apache.xerces.xni.XMLLocator;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4xml.commons.BadLocationException;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMNode;
import org.eclipse.lsp4xml.dom.NoNamespaceSchemaLocation;
import org.eclipse.lsp4xml.dom.SchemaLocation;
import org.eclipse.lsp4xml.extensions.contentmodel.participants.codeactions.cvc_attribute_3CodeAction;
import org.eclipse.lsp4xml.extensions.contentmodel.participants.codeactions.cvc_complex_type_2_1CodeAction;
import org.eclipse.lsp4xml.extensions.contentmodel.participants.codeactions.cvc_complex_type_2_3CodeAction;
Expand Down Expand Up @@ -46,7 +53,7 @@ public enum XMLSchemaErrorCode implements IXMLErrorCode {
cvc_datatype_valid_1_2_1("cvc-datatype-valid.1.2.1"), // https://wiki.xmldation.com/Support/Validator/cvc-datatype-valid-1-2-1
cvc_elt_1_a("cvc-elt.1.a"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-1
cvc_elt_3_1("cvc-elt.3.1"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-3-1
cvc_elt_3_2_1("cvc-elt.3.2.1"), //https://wiki.xmldation.com/Support/Validator/cvc-elt-3-2-1
cvc_elt_3_2_1("cvc-elt.3.2.1"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-3-2-1
cvc_elt_4_2("cvc-elt.4.2"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-4-2
cvc_type_3_1_1("cvc-type.3.1.1"), // https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-1
cvc_type_3_1_2("cvc-type.3.1.2"), // https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-2
Expand All @@ -59,8 +66,9 @@ public enum XMLSchemaErrorCode implements IXMLErrorCode {
cvc_maxInclusive_valid("cvc-maxInclusive-valid"), // https://wiki.xmldation.com/Support/validator/cvc-maxinclusive-valid
cvc_minExclusive_valid("cvc-minExclusive-valid"), // https://wiki.xmldation.com/Support/validator/cvc-minexclusive-valid
cvc_minInclusive_valid("cvc-minInclusive-valid"), // https://wiki.xmldation.com/Support/validator/cvc-mininclusive-valid
TargetNamespace_2("TargetNamespace.2"),
schema_reference_4("schema_reference.4"); //
TargetNamespace_2("TargetNamespace.2"),
SchemaLocation("SchemaLocation"),
schema_reference_4("schema_reference.4"); //

private final String code;

Expand Down Expand Up @@ -104,7 +112,7 @@ public static XMLSchemaErrorCode get(String name) {
* @param location
* @param key
* @param arguments
* @param document.ge
* @param document
* @return the LSP range from the SAX error.
*/
public static Range toLSPRange(XMLLocator location, XMLSchemaErrorCode code, Object[] arguments,
Expand All @@ -127,7 +135,7 @@ public static Range toLSPRange(XMLLocator location, XMLSchemaErrorCode code, Obj
return XMLPositionUtility.selectAttributeNameFromGivenNameAt(attrName, offset, document);
}
case cvc_elt_3_1: {
String namespaceAntAttrName = (String) arguments[1]; // http://www.w3.org/2001/XMLSchema-instance,nil
String namespaceAntAttrName = (String) arguments[1]; // http://www.w3.org/2001/XMLSchema-instance,nil
String attrName = namespaceAntAttrName;
int index = namespaceAntAttrName.indexOf(",");
if (index != -1) {
Expand All @@ -140,6 +148,32 @@ public static Range toLSPRange(XMLLocator location, XMLSchemaErrorCode code, Obj
}
return XMLPositionUtility.selectAttributeFromGivenNameAt(attrName, offset, document);
}
case SchemaLocation:
case schema_reference_4: {
DOMNode attrValueNode;
if(code.equals(SchemaLocation)) {
SchemaLocation schemaLocation = document.getSchemaLocation();
attrValueNode = schemaLocation.getAttr().getNodeAttrValue();
}
else {
NoNamespaceSchemaLocation noNamespaceSchemaLocation = document.getNoNamespaceSchemaLocation();
attrValueNode = noNamespaceSchemaLocation.getAttr().getNodeAttrValue();
}

if (attrValueNode != null) {
int startOffset = attrValueNode.getStart();
int endOffset = attrValueNode.getEnd();
try {
Position startPosition = document.positionAt(startOffset);
Position endPosition = document.positionAt(endOffset);
return new Range(startPosition, endPosition);

} catch (BadLocationException e) {
return null;
}
}
return null;
}
case cvc_attribute_3:
case cvc_complex_type_3_1:
case cvc_elt_4_2: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import static org.eclipse.lsp4xml.utils.XMLPositionUtility.toLSPPosition;

import java.util.HashSet;
import java.util.List;

import org.apache.xerces.impl.XMLErrorReporter;
Expand Down Expand Up @@ -39,13 +40,15 @@ public abstract class AbstractLSPErrorReporter extends XMLErrorReporter {

private final DOMDocument xmlDocument;
private final List<Diagnostic> diagnostics;
private final HashSet<Diagnostic> diagnosticSet;

private final String source;

public AbstractLSPErrorReporter(String source, DOMDocument xmlDocument, List<Diagnostic> diagnostics) {
this.source = source;
this.xmlDocument = xmlDocument;
this.diagnostics = diagnostics;
this.diagnosticSet = new HashSet<Diagnostic>();
XMLMessageFormatter xmft = new XMLMessageFormatter();
super.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
super.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
Expand Down Expand Up @@ -82,9 +85,14 @@ public String reportError(XMLLocator location, String domain, String key, Object
if(adjustedRange == null) {
return null;
}

Diagnostic d = new Diagnostic(adjustedRange, message, toLSPSeverity(severity), source, key);
if(diagnosticSet.contains(d)) {
return null;
}
diagnosticSet.add(d);
// Fill diagnostic
diagnostics.add(new Diagnostic(adjustedRange, message,
toLSPSeverity(severity), source, key));
diagnostics.add(d);

if (severity == SEVERITY_FATAL_ERROR && !fContinueAfterFatalError) {
XMLParseException parseException = (exception != null) ? new XMLParseException(location, message, exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,72 @@ public void schemaWithUrlWithoutCache() throws Exception {
"</invoice> \r\n" + //
"";
XMLAssert.testPublishDiagnosticsFor(xml, fileURI, configuration, pd(fileURI, //
new Diagnostic(r(2, 52, 2, 52),
new Diagnostic(r(2, 31, 2, 51),
"schema_reference.4: Failed to read schema document 'http://invoice.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.",
DiagnosticSeverity.Warning, "xml", "schema_reference.4"), //
new Diagnostic(r(1, 1, 1, 8), "cvc-elt.1.a: Cannot find the declaration of element 'invoice'.",
DiagnosticSeverity.Error, "xml", "cvc-elt.1.a")));
}

@Test
public void schemaWithUrlWithoutCacheNoDuplicateWarning() throws Exception {
// Here we test the following context:
// - XML which have xsi:noNamespaceSchemaLocation="http://invoice.xsd"
// - XMLCacheResolverExtension which is disabled
// Result of test is to have one published diagnostics with several Xerces
// errors (schema)

Consumer<XMLLanguageService> configuration = ls -> {
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
// Use cache on file system
contentModelManager.setUseCache(false);
};

String fileURI = "test.xml";
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<invoice xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" + //
" xsi:noNamespaceSchemaLocation=\"http://invoice.xsd\">\r\n" + //
" <a></a>\r\n" + //
" <b></b>\r\n" + //
" <c></c>\r\n" + //
"</invoice> \r\n" + //
"";
XMLAssert.testPublishDiagnosticsFor(xml, fileURI, configuration, pd(fileURI, //
new Diagnostic(r(2, 31, 2, 51),
"schema_reference.4: Failed to read schema document 'http://invoice.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.",
DiagnosticSeverity.Warning, "xml", "schema_reference.4"), //
new Diagnostic(r(1, 1, 1, 8), "cvc-elt.1.a: Cannot find the declaration of element 'invoice'.",
DiagnosticSeverity.Error, "xml", "cvc-elt.1.a")));
}

@Test
public void schemaWithUrlInvalidPathWithNamespace() throws Exception {
// Here we test the following context:
// - XML which have xsi:noNamespaceSchemaLocation="http://invoice.xsd"
// - XMLCacheResolverExtension which is disabled
// Result of test is to have one published diagnostics with several Xerces
// errors (schema)

Consumer<XMLLanguageService> configuration = ls -> {
ContentModelManager contentModelManager = ls.getComponent(ContentModelManager.class);
// Use cache on file system
contentModelManager.setUseCache(false);
};

String fileURI = "test.xml";
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + //
"<invoice xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" + //
" xsi:schemaLocation=\"http://invoice.xsd\">\r\n" + //
"</invoice> \r\n" + //
"";
XMLAssert.testPublishDiagnosticsFor(xml, fileURI, configuration, pd(fileURI, //
new Diagnostic(r(2, 20, 2, 40),
"SchemaLocation: schemaLocation value = 'http://invoice.xsd' must have even number of URI's.",
DiagnosticSeverity.Warning, "xml", "SchemaLocation"), //
new Diagnostic(r(1, 1, 1, 8), "cvc-elt.1.a: Cannot find the declaration of element 'invoice'.",
DiagnosticSeverity.Error, "xml", "cvc-elt.1.a")));
}

@Test
public void schemaWithUrlWithCache() throws Exception {
// Here we test the following context:
Expand Down

0 comments on commit 2226771

Please sign in to comment.