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

XSD 1.1 working #515

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Features
* [textDocument/hover](https://microsoft.github.io/language-server-protocol/specification#textDocument_hover).
* [textDocument/rangeFormatting](https://microsoft.github.io/language-server-protocol/specification#textDocument_rangeFormatting)
* [textDocument/rename](https://microsoft.github.io/language-server-protocol/specification#textDocument_rename).
* XML Schema `1.0` and `1.1` support.t

See screenshots in the [wiki](https://github.com/angelozerr/lsp4xml/wiki/Features).

Expand Down
15 changes: 13 additions & 2 deletions org.eclipse.lsp4xml/pom.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.lsp4xml</groupId>
Expand Down Expand Up @@ -96,11 +98,20 @@
<groupId>org.eclipse.lsp4j</groupId>
<artifactId>org.eclipse.lsp4j.jsonrpc</artifactId>
</dependency>

<!-- Xerces 1.1 -->
<dependency>
<groupId>xerces</groupId>
<groupId>org.exist-db.thirdparty.xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.12.0</version>
<classifier>xml-schema-1.1</classifier>
</dependency>
<dependency>
<groupId>com.rackspace.eclipse.webtools.sourceediting</groupId>
<artifactId>org.eclipse.wst.xml.xpath2.processor</artifactId>
<version>2.1.100</version>
</dependency>

<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ContentModelPlugin implements IXMLExtension {

private final IHoverParticipant hoverParticipant;

private final IDiagnosticsParticipant diagnosticsParticipant;
private IDiagnosticsParticipant diagnosticsParticipant;

private final ICodeActionParticipant codeActionParticipant;

Expand All @@ -47,12 +47,9 @@ public class ContentModelPlugin implements IXMLExtension {

ContentModelManager contentModelManager;

private ContentModelSettings cmSettings;

public ContentModelPlugin() {
completionParticipant = new ContentModelCompletionParticipant();
hoverParticipant = new ContentModelHoverParticipant();
diagnosticsParticipant = new ContentModelDiagnosticsParticipant(this);
codeActionParticipant = new ContentModelCodeActionParticipant();
documentLinkParticipant = new ContentModelDocumentLinkParticipant();
typeDefinitionParticipant = new ContentModelTypeDefinitionParticipant();
Expand Down Expand Up @@ -83,10 +80,12 @@ public void doSave(ISaveContext context) {

private void updateSettings(ISaveContext saveContext) {
Object initializationOptionsSettings = saveContext.getSettings();
cmSettings = ContentModelSettings.getContentModelXMLSettings(initializationOptionsSettings);
ContentModelSettings cmSettings = ContentModelSettings
.getContentModelXMLSettings(initializationOptionsSettings);
if (cmSettings != null) {
updateSettings(cmSettings, saveContext);
}
contentModelManager.setSettings(cmSettings);
}

private void updateSettings(ContentModelSettings settings, ISaveContext context) {
Expand Down Expand Up @@ -126,6 +125,7 @@ private void updateSettings(ContentModelSettings settings, ISaveContext context)

@Override
public void start(InitializeParams params, XMLExtensionsRegistry registry) {
diagnosticsParticipant = new ContentModelDiagnosticsParticipant(registry);
URIResolverExtensionManager resolverManager = registry.getComponent(URIResolverExtensionManager.class);
contentModelManager = new ContentModelManager(resolverManager);
registry.registerComponent(contentModelManager);
Expand All @@ -149,8 +149,4 @@ public void stop(XMLExtensionsRegistry registry) {
registry.unregisterDocumentLinkParticipant(documentLinkParticipant);
registry.unregisterTypeDefinitionParticipant(typeDefinitionParticipant);
}

public ContentModelSettings getContentModelSettings() {
return cmSettings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.dom.DOMElement;
import org.eclipse.lsp4xml.extensions.contentmodel.settings.ContentModelSettings;
import org.eclipse.lsp4xml.extensions.contentmodel.settings.XMLFileAssociation;
import org.eclipse.lsp4xml.extensions.contentmodel.uriresolver.XMLCacheResolverExtension;
import org.eclipse.lsp4xml.extensions.contentmodel.uriresolver.XMLCatalogResolverExtension;
Expand All @@ -43,6 +44,8 @@ public class ContentModelManager {
private final XMLCatalogResolverExtension catalogResolverExtension;
private final XMLFileAssociationResolverExtension fileAssociationResolver;

private ContentModelSettings settings;

public ContentModelManager(URIResolverExtensionManager resolverManager) {
this.resolverManager = resolverManager;
modelProviders = new ArrayList<>();
Expand All @@ -57,6 +60,14 @@ public ContentModelManager(URIResolverExtensionManager resolverManager) {
setUseCache(true);
}

public void setSettings(ContentModelSettings settings) {
this.settings = settings;
}

public ContentModelSettings getSettings() {
return settings;
}

public CMElementDeclaration findCMElement(DOMElement element) throws Exception {
return findCMElement(element, element.getNamespaceURI());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4xml.dom.DOMDocument;
import org.eclipse.lsp4xml.extensions.contentmodel.ContentModelPlugin;
import org.eclipse.lsp4xml.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lsp4xml.services.extensions.diagnostics.IDiagnosticsParticipant;
import org.eclipse.lsp4xml.utils.DOMUtils;

Expand All @@ -26,11 +27,10 @@
*
*/
public class ContentModelDiagnosticsParticipant implements IDiagnosticsParticipant {
private final XMLExtensionsRegistry registry;

private final ContentModelPlugin contentModelPlugin;

public ContentModelDiagnosticsParticipant(ContentModelPlugin contentModelPlugin) {
this.contentModelPlugin = contentModelPlugin;
public ContentModelDiagnosticsParticipant(XMLExtensionsRegistry registry) {
this.registry = registry;
}

@Override
Expand All @@ -43,8 +43,8 @@ public void doDiagnostics(DOMDocument xmlDocument, List<Diagnostic> diagnostics,
// associations settings., ...)
XMLEntityResolver entityResolver = xmlDocument.getResolverExtensionManager();
// Process validation
XMLValidator.doDiagnostics(xmlDocument, entityResolver, diagnostics,
contentModelPlugin.getContentModelSettings(), monitor);
ContentModelManager manager = registry.getComponent(ContentModelManager.class);
XMLValidator.doDiagnostics(xmlDocument, entityResolver, diagnostics, manager.getSettings(), monitor);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
*******************************************************************************/
package org.eclipse.lsp4xml.extensions.contentmodel.participants.diagnostics;

import org.apache.xerces.impl.Constants;
import org.apache.xerces.impl.dtd.XMLDTDValidator;
import org.apache.xerces.impl.xs.XMLSchemaValidator;
import org.apache.xerces.parsers.XIncludeAwareParserConfiguration;
import org.apache.xerces.xni.XNIException;
import org.apache.xerces.xni.parser.XMLComponentManager;
Expand All @@ -25,12 +27,42 @@
*/
class LSPXMLParserConfiguration extends XIncludeAwareParserConfiguration {

private static final String XML_SCHEMA_VERSION = Constants.XERCES_PROPERTY_PREFIX
+ Constants.XML_SCHEMA_VERSION_PROPERTY;

private static final String SCHEMA_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX
+ Constants.SCHEMA_VALIDATOR_PROPERTY;

private final String namespaceSchemaVersion;

private final boolean disableDTDValidation;

public LSPXMLParserConfiguration(boolean disableDTDValidation) {
public LSPXMLParserConfiguration(String namespaceSchemaVersion, boolean disableDTDValidation) {
this.namespaceSchemaVersion = namespaceSchemaVersion;
this.disableDTDValidation = disableDTDValidation;
}

@Override
protected void configurePipeline() {
super.configurePipeline();
configureSchemaVersion();
}

@Override
protected void configureXML11Pipeline() {
super.configureXML11Pipeline();
configureSchemaVersion();
}

private void configureSchemaVersion() {
if (namespaceSchemaVersion != null) {
XMLSchemaValidator validator = (XMLSchemaValidator) super.getProperty(SCHEMA_VALIDATOR);
if (validator != null) {
validator.setProperty(XML_SCHEMA_VERSION, namespaceSchemaVersion);
}
}
}

@Override
protected void reset() throws XNIException {
super.reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,17 @@ public class XMLValidator {
private static final String DTD_NOT_FOUND = "Cannot find DTD ''{0}''.\nCreate the DTD file or configure an XML catalog for this DTD.";

public static void doDiagnostics(DOMDocument document, XMLEntityResolver entityResolver,
List<Diagnostic> diagnostics, ContentModelSettings contentModelSettings, CancelChecker monitor) {
List<Diagnostic> diagnostics, ContentModelSettings settings, CancelChecker monitor) {
try {
// It should be better to cache XML Schema with XMLGrammarCachingConfiguration,
// but we cannot use
// XMLGrammarCachingConfiguration because cache is done with target namespaces.
// There are conflicts when
// 2 XML Schemas don't define target namespaces.
LSPXMLParserConfiguration configuration = new LSPXMLParserConfiguration(

// Configure the XSD schema version
String namespaceSchemaVersion = XMLValidationSettings.getNamespaceSchemaVersion(settings);
LSPXMLParserConfiguration configuration = new LSPXMLParserConfiguration(namespaceSchemaVersion,
isDisableOnlyDTDValidation(document));

if (entityResolver != null) {
Expand All @@ -74,6 +77,7 @@ public static void doDiagnostics(DOMDocument document, XMLEntityResolver entityR

final LSPErrorReporterForXML reporter = new LSPErrorReporterForXML(document, diagnostics);
boolean externalDTDValid = checkExternalDTD(document, reporter, configuration);

SAXParser parser = new SAXParser(configuration);
// Add LSP error reporter to fill LSP diagnostics from Xerces errors
parser.setProperty("http://apache.org/xml/properties/internal/error-reporter", reporter);
Expand All @@ -87,17 +91,15 @@ public static void doDiagnostics(DOMDocument document, XMLEntityResolver entityR
boolean hasGrammar = document.hasGrammar();

// If diagnostics for Schema preference is enabled
XMLValidationSettings validationSettings = contentModelSettings != null
? contentModelSettings.getValidation()
: null;
XMLValidationSettings validationSettings = settings != null ? settings.getValidation() : null;
if ((validationSettings == null) || validationSettings.isSchema()) {

checkExternalSchema(document.getExternalSchemaLocation(), parser);

parser.setFeature("http://apache.org/xml/features/validation/schema", hasGrammar); //$NON-NLS-1$

// warn if XML document is not bound to a grammar according the settings
warnNoGrammar(document, diagnostics, contentModelSettings);
warnNoGrammar(document, diagnostics, settings);
} else {
hasGrammar = false; // validation for Schema was disabled
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,47 @@

package org.eclipse.lsp4xml.extensions.contentmodel.settings;

import org.apache.xerces.impl.Constants;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4xml.utils.StringUtils;

/**
* XMLValidationSettings
*/
public class XMLValidationSettings {

/**
* Schema version.
*
* <p>
* Supported version by Xerces are 1.0, 1.1 and 1.0EX.
* </p>
*
* @see https://github.com/apache/xerces2-j/blob/xml-schema-1.1-dev/src/org/apache/xerces/impl/Constants.java#L42
*
*/
public enum SchemaVersion {

V10("1.0"), V11("1.1"), V10EX("1.0EX");

private final String version;

private SchemaVersion(String version) {
this.version = version;
}

public String getVersion() {
return version;
}

}

private Boolean schema;

private Boolean enabled;

private String schemaVersion;

/**
* This severity preference to mark the root element of XML document which is
* not bound to a XML Schema/DTD.
Expand All @@ -31,7 +61,7 @@ public class XMLValidationSettings {
private String noGrammar;

public XMLValidationSettings() {
//set defaults
// set defaults
schema = true;
enabled = true;
}
Expand Down Expand Up @@ -64,6 +94,30 @@ public void setSchema(boolean schema) {
this.schema = schema;
}

/**
* Returns the schema version.
*
* <p>
* Supported version by Xerces are 1.0, 1.1 and 1.0EX.
* </p>
*
* @see https://github.com/apache/xerces2-j/blob/xml-schema-1.1-dev/src/org/apache/xerces/impl/Constants.java#L42
*
* @return the schema version
*/
public String getSchemaVersion() {
return schemaVersion;
}

/**
* Set the schema version
*
* @param schemaVersion the schema version
*/
public void setSchemaVersion(String schemaVersion) {
this.schemaVersion = schemaVersion;
}

public void setNoGrammar(String noGrammar) {
this.noGrammar = noGrammar;
}
Expand Down Expand Up @@ -100,12 +154,35 @@ public static DiagnosticSeverity getNoGrammarSeverity(ContentModelSettings setti
return defaultSeverity;
}

/**
* Returns the Xerces namespace of the schema version to use and 1.0 otherwise.
*
* @param settings the settings
* @return the Xerces namespace of the schema version to use and 1.0 otherwise.
*/
public static String getNamespaceSchemaVersion(ContentModelSettings settings) {
if (settings == null || settings.getValidation() == null) {
return Constants.W3C_XML_SCHEMA10_NS_URI;
}
String schemaVersion = settings.getValidation().getSchemaVersion();
if (StringUtils.isEmpty(schemaVersion)) {
return Constants.W3C_XML_SCHEMA10_NS_URI;
}
if (SchemaVersion.V11.getVersion().equals(schemaVersion)) {
return Constants.W3C_XML_SCHEMA11_NS_URI;
}
if (SchemaVersion.V10EX.getVersion().equals(schemaVersion)) {
return Constants.W3C_XML_SCHEMA10EX_NS_URI;
}
return Constants.W3C_XML_SCHEMA10_NS_URI;
}

public XMLValidationSettings merge(XMLValidationSettings settings) {
if(settings != null) {
if (settings != null) {
this.schema = settings.schema;
this.enabled = settings.enabled;
}
return this;
}

}
Loading