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

Initialize RelaxNG support. #841

Merged
merged 1 commit into from
Oct 13, 2022
Merged

Initialize RelaxNG support. #841

merged 1 commit into from
Oct 13, 2022

Conversation

angelozerr
Copy link
Contributor

@angelozerr angelozerr commented Aug 10, 2020

Initialize RelaxNG support (XML and compact syntax) with:

  • XML validation with RelaxNG
  • XML completion based on RelaxNG
  • Find Type definition from XML to RelaxNG
  • RelaxNG snippet support for XML and RelaxNG *.rng files

Copy link
Contributor

@BalduinLandolt BalduinLandolt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have a closer look as soon as I find time. One thing that struck me right away: You used the same maven dependency as I did in my PR. However, since then I found a more recent one:

<dependency>
    <groupId>org.relaxng</groupId>
    <artifactId>jing</artifactId>
    <version>20181222</version>
</dependency>

I don't think there has been really any development on Jing between 2009 and 2018, but it might stil be better to use the more current one.

@adunning
Copy link

It would be an immense help to have this. Is there anything preventing it from being merged?

@angelozerr
Copy link
Contributor Author

@adunning thanks for your feedback.

At first please wote at redhat-developer/vscode-xml#450

The main problem is that RelaxNG is not our priority and it requires a lot of work (to support validation with error range and completion,hover, definition based on relaxng). Our current goal is to support robust support for XML, XSD and DTD.But if we see that we have more and more people(liek you) who are interested we could work.

This PR is based on Jing, but I know @svanteschubert wanted to provide a relaxng support based on MSV. See redhat-developer/vscode-xml#451 (comment)

@svanteschubert what is the status of your work?

Comment on lines 250 to 252
<groupId>org.relaxng</groupId>
<artifactId>jing</artifactId>
<version>20220510</version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After talking to @datho7561 , I noticed that https://repo1.maven.org/maven2/org/relaxng/jing/20220510/jing-20220510.pom depends on :

xerces:xercesImpl:2.9.1 & xml-apis:xml-apis:1.0.b2

while lemminx itself depends on :

xerces:xercesImpl:2.12.2 & xml-apis:xml-apis:1.4.01

We can't have multiple versions in the uber jar so would be good to ensure the latest versions are also supported by jing, and maybe contribute back upstream.

@datho7561
Copy link
Contributor

We will need to do a bit of work in order to get the binary to work

@rgrunber
Copy link
Contributor

For org.relaxng:jing, I couldn't find any recent entry on ClearlyDefined. https://clearlydefined.io/definitions/maven/mavencentral/org.relaxng/jing/20181222 doesn't have the necessary score.

$ mvn clean verify -DskipTests -Pverify-iplog
...
...
$ cat target/dash/summary | grep -v approved
maven/mavencentral/isorelax/isorelax/20030108, , restricted, clearlydefined
maven/mavencentral/org.relaxng/jing/20220510, , restricted, clearlydefined

So these libraries would need to be approved via. https://gitlab.eclipse.org/eclipsefdn/emo-team/iplab .
You can use Create a request to vet Third-party content in order to do it manually. There's also an automated process that requires you to create at GitLab api token.

@datho7561
Copy link
Contributor

@angelozerr angelozerr force-pushed the relaxng branch 3 times, most recently from 6c81de3 to 9c5ba42 Compare October 5, 2022 10:20
@datho7561
Copy link
Contributor

Here's what's needed to get the binary working:

diff --git a/org.eclipse.lemminx/src/main/resources/META-INF/native-image/resource-config.json b/org.eclipse.lemminx/src/main/resources/META-INF/native-image/resource-config.json
index 12a4fcdb..18d3640d 100644
--- a/org.eclipse.lemminx/src/main/resources/META-INF/native-image/resource-config.json
+++ b/org.eclipse.lemminx/src/main/resources/META-INF/native-image/resource-config.json
@@ -50,6 +50,12 @@
                {
                        "name": "org.apache.xerces.impl.msg.XMLMessages"
                },
+               {
+                       "name": "com.thaiopensource.datatype.xsd.resources.Messages"
+               },
+               {
+                       "name": "com.thaiopensource.relaxng.pattern.resources.Messages"
+               },
                {
                        "name": "org.eclipse.lemminx.extensions.xerces.xmlmodel.msg.XMLMessages"
                },

@angelozerr
Copy link
Contributor Author

Here's what's needed to get the binary working:

Thanksso much for your feedback. I'm surprised that there is just this fix to do. I think completion doesn't work with binary because I'm using Java reflection (for the moment).

@angelozerr angelozerr force-pushed the relaxng branch 2 times, most recently from a9c8e67 to 01d1ef5 Compare October 12, 2022 15:33
Copy link
Contributor

@datho7561 datho7561 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got an NPE. Not sure what caused it, but I'll try to figure out steps to reproduce it:

java.lang.NullPointerException
	at org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.LSPSAXParser.startDocument(LSPSAXParser.java:87)
	at org.eclipse.lemminx.extensions.relaxng.xml.validator.ExternalRelaxNGValidator.startDocument(ExternalRelaxNGValidator.java:68)
	at org.apache.xerces.impl.dtd.XMLDTDValidator.startDocument(Unknown Source)
	at org.eclipse.lemminx.extensions.xerces.ExternalXMLDTDValidator.startDocument(ExternalXMLDTDValidator.java:73)
	at org.eclipse.lemminx.extensions.xerces.xmlmodel.XMLModelHandler.startDocument(XMLModelHandler.java:170)
	at org.apache.xerces.impl.dtd.XMLDTDValidator.startDocument(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentScannerImpl.startEntity(Unknown Source)
	at org.apache.xerces.impl.XMLVersionDetector.startDocumentParsing(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
	at org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.XMLValidator.parseXML(XMLValidator.java:318)
	at org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.XMLValidator.doDiagnostics(XMLValidator.java:132)
	at org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.ContentModelDiagnosticsParticipant.doDiagnostics(ContentModelDiagnosticsParticipant.java:58)
	at org.eclipse.lemminx.services.XMLDiagnostics.doExtensionsDiagnostics(XMLDiagnostics.java:67)
	at org.eclipse.lemminx.services.XMLDiagnostics.doDiagnostics(XMLDiagnostics.java:49)
	at org.eclipse.lemminx.services.XMLLanguageService.doDiagnostics(XMLLanguageService.java:173)
	at org.eclipse.lemminx.services.XMLLanguageService.publishDiagnostics(XMLLanguageService.java:187)
	at org.eclipse.lemminx.XMLTextDocumentService.validate(XMLTextDocumentService.java:662)
	at org.eclipse.lemminx.XMLTextDocumentService.lambda$validate$32(XMLTextDocumentService.java:637)
	at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
	at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
	at com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:704)
	at com.oracle.svm.core.posix.thread.PosixPlatformThreads.pthreadStartRoutine(PosixPlatformThreads.java:202)

@datho7561
Copy link
Contributor

Given:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="asdf.rnc"?>
<addressBook>
  <card>
    <name>David</name>
    <email></email>
  </card>
</addressBook>

and an empty asdf.rnc, the "schema invalid" error is placed on the first line of the file (it's not adjusted properly), and 2 NPE appear in the console.

@datho7561
Copy link
Contributor

datho7561 commented Oct 12, 2022

If you reference an empty .rng file, then the error message that appears is ::::-1:-1:-1:Premature end of file.xml(RelaxNGNotFound). It would be nice if we could remove the ::::-1:-1:-1: part

@datho7561
Copy link
Contributor

It would be nice to associate all .rng files with the relaxng.rng or relaxng.xsd schema. Do you want to do this in a future PR?

* @author Angelo ZERR
*
*/
public class RelaxNGErrorHandler implements XMLErrorHandler {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the SAX interface not enough to get good diagnostics?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it is not enough because we need the error code key.


static {
MODEL_VALIDATOR_FACTORIES = new ArrayList<>();
Iterator<XMLModelValidatorFactory> factories = ServiceLoader.load(XMLModelValidatorFactory.class).iterator();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some places, the different validators are loaded dynamically, but in others, like LSPErrorReporterForXML, they are hard coded. I think we should eventually get a clean separation between the different validators. This would let us do things like add a new validator that uses the lemminx grammar cache using the extension point mechanism, or compile a version of LemMinX with only specific validators in order to reduce the size.

However, I think maybe it makes more sense to do this in a future PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, I think maybe it makes more sense to do this in a future PR?

I agree it is not perfect but XSD and DTD validator does that too. Please do that in an another PR.

@angelozerr
Copy link
Contributor Author

angelozerr commented Oct 12, 2022

and an empty asdf.rnc, the "schema invalid" error is placed on the first line of the file (it's not adjusted properly), and 2 NPE appear in the console.

If you reference an empty .rng file, then the error message that appears is ::::-1:-1:-1:Premature end of file.xml(RelaxNGNotFound). It would be nice if we could remove the ::::-1:-1:-1: part

It should be fixed now and you should see the error as referenced diagnostic because the error comes from the schema and not from the XML:

image

@angelozerr
Copy link
Contributor Author

It would be nice to associate all .rng files with the relaxng.rng or relaxng.xsd schema. Do you want to do this in a future PR?

done, now you should have validation and completion for relaxng grammar:

RelaxNGGrammarSupport

@angelozerr angelozerr force-pushed the relaxng branch 2 times, most recently from cc4ee18 to 3ebe288 Compare October 12, 2022 22:29
@fbricon
Copy link
Contributor

fbricon commented Oct 13, 2022

Don't say "This class is a copy paste of", say "This class is a copy of "

@angelozerr angelozerr force-pushed the relaxng branch 2 times, most recently from fcc2f3c to a6ac347 Compare October 13, 2022 12:07
@angelozerr
Copy link
Contributor Author

Don't say "This class is a copy paste of", say "This class is a copy of "

fixed

@angelozerr
Copy link
Contributor Author

I add 2 snippets support for RelaxNG:

  • one to create an XML file bound with RelaxNG
  • one to create a RelaxNG *.rng grammar file

Here a demo which show how it is easy to create an XML bound with a RelaxNG grammar created by snippets:

RelaxNGSnippetSupport

@datho7561
Copy link
Contributor

If you reference an empty .rng file, the SAXParseException appears in the logs.

 * XML validation with RelaxNG
 * XML completion based on RelaxNG
 * Find Type definition from XML to RelaxNG
 * RelaxNG snippet support for XML and RelaxNG *.rng files

Signed-off-by: azerr <azerr@redhat.com>
@angelozerr
Copy link
Contributor Author

If you reference an empty .rng file, the SAXParseException appears in the logs.

It should be fixed.

Copy link
Contributor

@datho7561 datho7561 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works very well. Thank you, Angelo!

@datho7561 datho7561 added this to the 0.22.0 milestone Oct 13, 2022
@datho7561 datho7561 linked an issue Oct 13, 2022 that may be closed by this pull request
6 tasks
@datho7561 datho7561 removed this from the 0.22.0 milestone Oct 13, 2022
@datho7561 datho7561 merged commit 61599b5 into eclipse:main Oct 13, 2022
@angelozerr angelozerr mentioned this pull request Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Initialize RelaxNG support with validation/completion/hover
6 participants