Skip to content

Commit

Permalink
XSD 1.1 working
Browse files Browse the repository at this point in the history
Fix #363

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jul 18, 2019
1 parent 67b93ac commit 0adf69c
Show file tree
Hide file tree
Showing 18 changed files with 395 additions and 53 deletions.
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
5 changes: 3 additions & 2 deletions org.eclipse.lsp4xml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,11 @@
<artifactId>org.eclipse.lsp4j.jsonrpc</artifactId>
</dependency>
<dependency>
<groupId>xerces</groupId>
<groupId>org.exist-db.thirdparty.xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.12.0</version>
</dependency>
<classifier>xml-schema-1.1</classifier>
</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

0 comments on commit 0adf69c

Please sign in to comment.