opencaesar / owl-adapter

The OML adapter for OWL
Apache License 2.0
0 stars 2 forks source link

[BUG] - NPE #49

Open NicolasRouquette opened 2 years ago

NicolasRouquette commented 2 years ago

Description

A clear and concise description of what the bug is.

with the following in build.gradle:

classpath 'io.opencaesar.adapters:oml2owl-gradle:1.0.+'

in a project caught in the unpleasant OML 1.0 migration, I get:

.\gradlew omlToOwlRdf --stacktrace
> Task :omlToOwlRdf FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':omlToOwlRdf'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':omlToOwlRdf'.
        at io.opencaesar.oml2owl.Oml2OwlTask.run(Oml2OwlTask.java:75)
 ...
Caused by: java.lang.NullPointerException
        at org.eclipse.emf.ecore.util.EcoreUtil.getID(EcoreUtil.java:3715)
        at io.opencaesar.oml.validate.OmlValidator$1.getObjectLabel(OmlValidator.java:41)
        at org.eclipse.emf.ecore.util.Diagnostician.createDefaultDiagnostic(Diagnostician.java:111)
        at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:130)
        at io.opencaesar.oml.validate.OmlValidator.validate(OmlValidator.java:47)
        at io.opencaesar.oml2owl.Oml2OwlApp.run(Oml2OwlApp.java:197)
        at io.opencaesar.oml2owl.Oml2OwlApp.main(Oml2OwlApp.java:158)
        at io.opencaesar.oml2owl.Oml2OwlTask.run(Oml2OwlTask.java:73)

* Get more help at https://help.gradle.org

Steps to Reproduce

Steps to reproduce the behavior:

Expected Behavior

A clear and concise description of what should be the expected behavior.

No NPE!

Additional Context

Enter any other details such as dependencies, environment, examples, etc.

Relevant screenshots

If applicable, add screenshots to help illustrate the issue.

NicolasRouquette commented 2 years ago

There are two issues here:

1) The NPE vulnerability needs to be fixed in the code involved in the stacktrace above.

2) The logic for finding input OML files assumes that the folder where the catalog is located has only oml files.

See below where the assumption is made in the Oml2OwlApp from oml 1.0:

    public void run() throws Exception {
        ...
        OmlStandaloneSetup.doSetup();
        OmlXMIResourceFactory.register();
        final XtextResourceSet inputResourceSet = new XtextResourceSet();
        inputResourceSet.eAdapters().add(new ECrossReferenceAdapter());

        final File inputCatalogFile = new File(inputCatalogPath);
        final File inputFolder = inputCatalogFile.getParentFile();
        final OmlCatalog inputCatalog = OmlCatalog.create(URI.createFileURI(inputCatalogFile.toString()));

        // load the OML ontologies
        List<Ontology> inputOntologies = new ArrayList<>(); 
        if (rootOntologyIri != null) {
            URI rootUri = resolveRootOntologyIri(rootOntologyIri, inputCatalog);
            LOGGER.info(("Reading: " + rootUri));
            Ontology rootOntology = OmlRead.getOntology(inputResourceSet.getResource(rootUri, true));
            inputOntologies.addAll(OmlRead.getAllImportedOntologies(rootOntology, true));
        } else {
            final Collection<File> inputFiles = collectOMLFiles(inputFolder); // assumption here.
            for (File inputFile : inputFiles) {
                final URI ontologyUri = URI.createFileURI(inputFile.getAbsolutePath());
                LOGGER.info(("Reading: " + ontologyUri));
                Ontology ontology = OmlRead.getOntology(inputResourceSet.getResource(ontologyUri, true));
                inputOntologies.add(ontology);  
            }
        }

The function collectOMLFiles scans for all OML files in a given folder.

The problem stems from the fact that this code fails to verify that the files found would correspond to a catalog-mapped IRI to that file.

For example, consider the simple catalog:

<?xml version='1.0'?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="public">
    <rewriteURI uriStartString="http://" rewritePrefix="src/oml/" />
</catalog>

Suppose the file layout looks like this:

./
./.history
./catalog.xml
./src
./doc

Suppose further that in the doc folder, there are some snippets of OML files intended for documentation purposes but these files may not be valid OML syntax because they are snippets.

A similar use case happens with a folder like .history for the popular VS Code extension git history where the .history folder will have timestamped files corresponding to local edits of OML files made in VS Code.

In both cases, the logic in Oml2OwlApp will include all *.oml files found in ./.history and ./doc even though these files are outside the intended scope of the files that should correspond to a catalog-mapped IRI.

To fix this, it is necessary to filter the results of collectOMLFiles to accept only those files whose location correspond to a catalog rewrite URI prefix.

The Scala-based OML tooling did this here:

dwagmuse commented 2 years ago

In all other projects I'm aware of we always specify a target bundle using the rootOntologyIri parameter for the converter to use as input rather than having it find any oml files in the whole project. Have you tried that? It might be simpler to simply make the app REQUIRE that parameter be specified because, as you note, searching through the entire project it could find all sorts of nonsense.

NicolasRouquette commented 2 years ago

Turns out that it is not difficult to adapt the Scala strategy I used in the original oml to this code base. See: https://github.com/opencaesar/owl-adapter/pull/50

This fix is better because it uses the catalog rewrite rules to look for all possible folders where there can be catalog-mapped oml files.