Skip to content

Commit

Permalink
Validate DTD file with a dedicated DTD validator (see #223)
Browse files Browse the repository at this point in the history
  • Loading branch information
angelozerr committed Nov 15, 2018
1 parent b3b16e8 commit 41efab4
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.eclipse.lsp4xml.dom.XMLDocument;
import org.eclipse.lsp4xml.extensions.contentmodel.ContentModelPlugin;
import org.eclipse.lsp4xml.services.extensions.diagnostics.IDiagnosticsParticipant;
import org.eclipse.lsp4xml.utils.DOMUtils;

/**
* Validate XML file with Xerces for syntax validation and XML Schema, DTD.
Expand All @@ -33,6 +34,10 @@ public ContentModelDiagnosticsParticipant(ContentModelPlugin contentModelPlugin)

@Override
public void doDiagnostics(XMLDocument xmlDocument, List<Diagnostic> diagnostics, CancelChecker monitor) {
if (DOMUtils.isDTD(xmlDocument)) {
// Don't validate DTD with XML validator
return;
}
// Get entity resolver (XML catalog resolver, XML schema from the file
// associations settings., ...)
XMLEntityResolver entityResolver = xmlDocument.getResolverExtensionManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
import org.eclipse.lsp4xml.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lsp4xml.extensions.contentmodel.model.ContentModelProvider;
import org.eclipse.lsp4xml.extensions.dtd.contentmodel.DTDContentModelProvider;
import org.eclipse.lsp4xml.extensions.dtd.diagnostics.DTDDiagnosticsParticipant;
import org.eclipse.lsp4xml.services.extensions.IXMLExtension;
import org.eclipse.lsp4xml.services.extensions.XMLExtensionsRegistry;
import org.eclipse.lsp4xml.services.extensions.diagnostics.IDiagnosticsParticipant;
import org.eclipse.lsp4xml.services.extensions.save.ISaveContext;

/**
* DTD plugin.
*/
public class DTDPlugin implements IXMLExtension {

private final IDiagnosticsParticipant diagnosticsParticipant;

public DTDPlugin() {
diagnosticsParticipant = new DTDDiagnosticsParticipant();
}

@Override
Expand All @@ -37,9 +42,13 @@ public void start(InitializeParams params, XMLExtensionsRegistry registry) {
ContentModelProvider modelProvider = new DTDContentModelProvider(registry.getResolverExtensionManager());
ContentModelManager modelManager = registry.getComponent(ContentModelManager.class);
modelManager.registerModelProvider(modelProvider);
// register diagnostic participant
registry.registerDiagnosticsParticipant(diagnosticsParticipant);
}

@Override
public void stop(XMLExtensionsRegistry registry) {
// unregister diagnostic participant
registry.unregisterDiagnosticsParticipant(diagnosticsParticipant);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Copyright (c) 2018 Angelo ZERR
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <[email protected]> - initial API and implementation
*/
package org.eclipse.lsp4xml.extensions.dtd.diagnostics;

import java.util.List;

import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4xml.dom.XMLDocument;
import org.eclipse.lsp4xml.services.extensions.diagnostics.IDiagnosticsParticipant;
import org.eclipse.lsp4xml.utils.DOMUtils;

/**
* Validate XSD file with Xerces.
*
*/
public class DTDDiagnosticsParticipant implements IDiagnosticsParticipant {

@Override
public void doDiagnostics(XMLDocument xmlDocument, List<Diagnostic> diagnostics, CancelChecker monitor) {
if (!DOMUtils.isDTD(xmlDocument)) {
// Don't use the DTD validator, if it's a DTD
return;
}
// Get entity resolver (XML catalog resolver, XML schema from the file
// associations settings., ...)
XMLEntityResolver entityResolver = xmlDocument.getResolverExtensionManager();
// Process validation
DTDValidator.doDiagnostics(xmlDocument, entityResolver, diagnostics, monitor);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2018 Angelo ZERR.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <[email protected]> - initial API and implementation
*/
package org.eclipse.lsp4xml.extensions.dtd.diagnostics;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.xerces.impl.dtd.XMLDTDLoader;
import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
import org.eclipse.lsp4xml.dom.XMLDocument;
import org.eclipse.lsp4xml.extensions.contentmodel.participants.diagnostics.LSPErrorReporterForXML;

/**
* DTD validator
*
*/
public class DTDValidator {

public static void doDiagnostics(XMLDocument document, XMLEntityResolver entityResolver,
List<Diagnostic> diagnostics, CancelChecker monitor) {
try {
XMLDTDLoader loader = new XMLDTDLoader();
loader.setProperty("http://apache.org/xml/properties/internal/error-reporter",
new LSPErrorReporterForXML(document, diagnostics));

if (entityResolver != null) {
loader.setEntityResolver(entityResolver);
}

String content = document.getText();
String uri = document.getDocumentURI();
InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
XMLInputSource source = new XMLInputSource(null, uri, uri, inputStream, null);
loader.loadGrammar(source);
} catch (Exception e) {

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,6 @@ public static boolean isXSD(String uri) {
return uri != null && uri.endsWith(XSD_EXTENSION);
}

/**
* Returns true if the given URI is a DTD and false otherwise.
*
* @param uri the URI to check
* @return true if the given URI is a DTD and false otherwise.
*/
public static boolean isDTD(String uri) {
return uri != null && uri.endsWith(DTD_EXTENSION);
}

/**
* Returns true if the XML document is a XML Catalog and false otherwise.
*
Expand All @@ -80,4 +70,27 @@ private static boolean checkRootNamespace(XMLDocument document, String namespace
Element documentElement = document.getDocumentElement();
return documentElement != null && namespace.equals(documentElement.getNamespaceURI());
}

/**
* Returns true if the XML document is a DTD and false otherwise.
*
* @return true if the XML document is a DTD and false otherwise.
*/
public static boolean isDTD(XMLDocument document) {
String uri = document.getDocumentURI();
if (isDTD(uri)) {
return true;
}
return false;
}

/**
* Returns true if the given URI is a DTD and false otherwise.
*
* @param uri the URI to check
* @return true if the given URI is a DTD and false otherwise.
*/
public static boolean isDTD(String uri) {
return uri != null && uri.endsWith(DTD_EXTENSION);
}
}

0 comments on commit 41efab4

Please sign in to comment.