Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-adjusted error range for bad schema location, need to filter it out duplicates #361

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -82,9 +82,13 @@ 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(diagnostics.contains(d)) {
return null;
}
// 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