Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Manage namespaces / prefix validation with a settings #106

Merged
merged 1 commit into from
Jan 19, 2021
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 @@ -36,7 +36,9 @@
import org.eclipse.lemminx.dom.SchemaLocationHint;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSyntaxErrorCode;
import org.eclipse.lemminx.extensions.contentmodel.settings.NamespacesEnabled;
import org.eclipse.lemminx.extensions.contentmodel.settings.SchemaEnabled;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLNamespacesSettings;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLSchemaSettings;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings;
import org.eclipse.lemminx.services.extensions.diagnostics.LSPContentHandler;
Expand Down Expand Up @@ -111,6 +113,10 @@ && isSchemaValidationEnabled(document, validationSettings)
}
parser.setFeature("http://xml.org/sax/features/validation", hasGrammar); //$NON-NLS-1$

boolean namespacesValidationEnabled = isNamespacesValidationEnabled(document, validationSettings);
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", namespacesValidationEnabled); //$NON-NLS-1$
parser.setFeature("http://xml.org/sax/features/namespaces", namespacesValidationEnabled); //$NON-NLS-1$

// Parse XML
String content = document.getText();
String uri = document.getDocumentURI();
Expand All @@ -127,6 +133,28 @@ && isSchemaValidationEnabled(document, validationSettings)
}
}

private static boolean isNamespacesValidationEnabled(DOMDocument document,
XMLValidationSettings validationSettings) {
if (validationSettings == null) {
return true;
}
NamespacesEnabled enabled = NamespacesEnabled.always;
XMLNamespacesSettings namespacesSettings = validationSettings.getNamespaces();
if (namespacesSettings != null && namespacesSettings.getEnabled() != null) {
enabled = namespacesSettings.getEnabled();
}
switch (enabled) {
case always:
return true;
case never:
return false;
case onNamespaceEncountered:
return document.hasNamespaces();
default:
return true;
}
}

private static boolean isSchemaValidationEnabled(DOMDocument document, XMLValidationSettings validationSettings) {
if (validationSettings == null) {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2021 Red Hat Inc. and others.
* 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
* 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.settings;

public enum NamespacesEnabled {
always, never, onNamespaceEncountered;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2021 Red Hat Inc. and others.
* 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
* 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.settings;

/**
* XML Namespaces settings.
*
*/
public class XMLNamespacesSettings {

public XMLNamespacesSettings() {
setEnabled(NamespacesEnabled.always);
}

private NamespacesEnabled enabled;

public void setEnabled(NamespacesEnabled enabled) {
this.enabled = enabled;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((enabled == null) ? 0 : enabled.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
XMLNamespacesSettings other = (XMLNamespacesSettings) obj;
if (enabled != other.enabled)
return false;
return true;
}

public NamespacesEnabled getEnabled() {
return enabled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
*/
public class XMLValidationSettings {

private XMLSchemaSettings schema;

private Boolean enabled;

private XMLNamespacesSettings namespaces;

private XMLSchemaSettings schema;

private boolean disallowDocTypeDecl;

private boolean resolveExternalEntities;
Expand All @@ -46,19 +48,41 @@ public XMLValidationSettings() {
}

/**
* @return the syntax
* Returns true if the validation is enabled and false otherwise.
*
* @return true if the validation is enabled and false otherwise.
*/
public boolean isEnabled() {
return enabled;
}

/**
* @param syntax the syntax to set
* Set true if the validation is enabled and false otherwise.
*
* @param enabled true if the validation is enabled and false otherwise.
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

/**
* Returns the XML Namespaces validation settings.
*
* @return the XML Namespaces validation settings.
*/
public XMLNamespacesSettings getNamespaces() {
return namespaces;
}

/**
* Set the XML Namespaces validation settings.
*
* @param namespaces the XML Namespaces validation settings.
*/
public void setNamespaces(XMLNamespacesSettings namespaces) {
this.namespaces = namespaces;
}

/**
* Returns the XML Schema validation settings.
*
Expand All @@ -69,7 +93,9 @@ public XMLSchemaSettings getSchema() {
}

/**
* @param schema the schema to set
* Set the XML Schema validation settings.
*
* @param schema the XML Schema validation settings.
*/
public void setSchema(XMLSchemaSettings schema) {
this.schema = schema;
Expand Down Expand Up @@ -151,6 +177,7 @@ public static DiagnosticSeverity getNoGrammarSeverity(XMLValidationSettings vali

public XMLValidationSettings merge(XMLValidationSettings settings) {
if (settings != null) {
this.namespaces = settings.namespaces;
this.schema = settings.schema;
this.enabled = settings.enabled;
this.disallowDocTypeDecl = settings.disallowDocTypeDecl;
Expand All @@ -174,6 +201,7 @@ public int hashCode() {
int result = 1;
result = prime * result + (disallowDocTypeDecl ? 1231 : 1237);
result = prime * result + ((enabled == null) ? 0 : enabled.hashCode());
result = prime * result + ((namespaces == null) ? 0 : namespaces.hashCode());
result = prime * result + ((noGrammar == null) ? 0 : noGrammar.hashCode());
result = prime * result + (resolveExternalEntities ? 1231 : 1237);
result = prime * result + ((schema == null) ? 0 : schema.hashCode());
Expand All @@ -196,6 +224,11 @@ public boolean equals(Object obj) {
return false;
} else if (!enabled.equals(other.enabled))
return false;
if (namespaces == null) {
if (other.namespaces != null)
return false;
} else if (!namespaces.equals(other.namespaces))
return false;
if (noGrammar == null) {
if (other.noGrammar != null)
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,21 @@
"parameterTypes": []
}]
},
{
"name": "org.eclipse.lemminx.extensions.contentmodel.settings.XMLNamespacesSettings",
"allDeclaredFields": true,
"methods": [{
"name": "<init>",
"parameterTypes": []
}]
},
{
"name": "org.eclipse.lemminx.extensions.contentmodel.settings.NamespacesEnabled",
"allDeclaredFields": true
},
{
"name": "org.eclipse.lemminx.extensions.contentmodel.settings.XMLSchemaSettings",
"allDeclaredFields": true,
"methods": [{
"name": "<init>",
"parameterTypes": []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@

import org.eclipse.lemminx.XMLAssert;
import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSyntaxErrorCode;
import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
import org.eclipse.lemminx.extensions.contentmodel.settings.NamespacesEnabled;
import org.eclipse.lemminx.extensions.contentmodel.settings.SchemaEnabled;
import org.eclipse.lemminx.extensions.contentmodel.settings.XMLNamespacesSettings;
import org.eclipse.lemminx.settings.EnforceQuoteStyle;
import org.eclipse.lemminx.settings.QuoteStyle;
import org.eclipse.lemminx.settings.SharedSettings;
Expand Down Expand Up @@ -632,8 +635,8 @@ public void testMissingQuotesForAttributeSingleQuotes() throws Exception {
public void testOpenQuoteExpectedDisabledPreference() throws Exception {
String xml = " <InstdAmt Ccy==\"JPY\">10000000</InstdAmt>";
testDiagnosticsFor(xml, null, null, null, true, XMLAssert.getContentModelSettings(false, SchemaEnabled.always)); // validation
// is
// disabled
// is
// disabled
}

@Test
Expand Down Expand Up @@ -781,4 +784,70 @@ public void closeTag() throws Exception {
testDiagnosticsFor(xml, d);
testCodeActionsFor(xml, d, ca(d, te(0, 5, 0, 5, "a>")));
}

@Test
public void namespacesSettingsWithoutXMLNS() throws Exception {
String xml = "<foo>\r\n" + //
" <p:bar />\r\n" + //
"</foo>";
// always
ContentModelSettings settings = getSettingsForNamespaces(NamespacesEnabled.always);
testDiagnosticsFor(xml, null, null, null, true, settings, //
d(1, 2, 1, 7, XMLSyntaxErrorCode.ElementPrefixUnbound));

// never
settings = getSettingsForNamespaces(NamespacesEnabled.never);
testDiagnosticsFor(xml, null, null, null, true, settings);

// onNamespaceEncountered
settings = getSettingsForNamespaces(NamespacesEnabled.onNamespaceEncountered);
testDiagnosticsFor(xml, null, null, null, true, settings);
}

@Test
public void namespacesSettingsWithUnvalidXMLNS() throws Exception {
String xml = "<foo xmlns=\"http:foo\" >\r\n" + //
" <p:bar />\r\n" + //
"</foo>";
// always
ContentModelSettings settings = getSettingsForNamespaces(NamespacesEnabled.always);
testDiagnosticsFor(xml, null, null, null, true, settings, //
d(1, 2, 1, 7, XMLSyntaxErrorCode.ElementPrefixUnbound));

// never
settings = getSettingsForNamespaces(NamespacesEnabled.never);
testDiagnosticsFor(xml, null, null, null, true, settings);

// onNamespaceEncountered
settings = getSettingsForNamespaces(NamespacesEnabled.onNamespaceEncountered);
testDiagnosticsFor(xml, null, null, null, true, settings, //
d(1, 2, 1, 7, XMLSyntaxErrorCode.ElementPrefixUnbound));
}

@Test
public void namespacesSettingsWithValidXMLNS() throws Exception {
String xml = "<foo xmlns:p=\"http:foo\" >\r\n" + //
" <p:bar />\r\n" + //
"</foo>";
// always
ContentModelSettings settings = getSettingsForNamespaces(NamespacesEnabled.always);
testDiagnosticsFor(xml, null, null, null, true, settings);

// never
settings = getSettingsForNamespaces(NamespacesEnabled.never);
testDiagnosticsFor(xml, null, null, null, true, settings);

// onNamespaceEncountered
settings = getSettingsForNamespaces(NamespacesEnabled.onNamespaceEncountered);
testDiagnosticsFor(xml, null, null, null, true, settings);
}

private static ContentModelSettings getSettingsForNamespaces(NamespacesEnabled namespacesEnabled) {
ContentModelSettings settings = XMLAssert.getContentModelSettings(true, SchemaEnabled.never);
settings.getValidation().setNoGrammar("ignore");
XMLNamespacesSettings namespaces = new XMLNamespacesSettings();
namespaces.setEnabled(namespacesEnabled);
settings.getValidation().setNamespaces(namespaces);
return settings;
}
}