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

Import ontology from jar #621

Closed
donmendelson opened this issue Feb 8, 2017 · 14 comments
Closed

Import ontology from jar #621

donmendelson opened this issue Feb 8, 2017 · 14 comments

Comments

@donmendelson
Copy link

I would like to distribute an application to create or edit ontologies that would import an ontology that I supply. I expect that the base ontology would be provided as a resource in a distributed jar file. My application works if the imported ontology resides as a flat file, but I am unable to load it from the jar. I've tried providing a file:// protocol on the document IRI in SimpleIRIMapper, but that doesn't work. Usually such resources are accessed by

InputStream ClassLoader.getResourceAsStream(String name)

I can't find a way to adapt that to the API. Any suggestions?

@ignazio1977
Copy link
Contributor

There is no ready made utility for this but you should be able to load this kind of ontology subclassing a StreamDocumentSource.

Currently it's not possible to achieve this with an IRI mapper - jar paths are not understood as resolvable IRIs.

@donmendelson
Copy link
Author

IRI mapper returns null if it cannot resolve the document IRI. I created a workaround that seems to work. It allows the document to be resolved whether it is in the file system or as a resource in the application jar. It uses URLClassLoader, which can access members of a jar.

URLClassLoader jarClassLoader = new URLClassLoader(new URL [] {new URL("file://")});

    URL documentURL = this.getClass().getClassLoader().getResource("orchestra2016.ttl");
    if (documentURL == null) {
      // Retrieve from the jar
      documentURL = jarClassLoader.getResource("orchestra2016.ttl");
    }

    PriorityCollection<OWLOntologyIRIMapper> iriMappers = ontologyManager.getIRIMappers();
    iriMappers.add(new SimpleIRIMapper(orchestraIRI, IRI.create(documentURL)));

@ignazio1977 ignazio1977 added this to Brain Storming in OWLAPI 6 Project Mar 18, 2017
ignazio1977 added a commit that referenced this issue Nov 28, 2017
Allow the content of a zip file to be mapped to ontology IRIs
as an IRI mapper for use in an ontology manager.
Also extend AutoIRIMapper to do the same.

owlzip.properties and catalog*.xml supported to find ontology 
IRIs without parsing the actual files. Lacking these index files,
same logic as AutoIRIMapper applies.

Also implements Import ontology from jar #621 where 
AutoIRIMapper can now map the contents of a jar or zip file.
@ignazio1977
Copy link
Contributor

AutoIRIMapper can now do this.

@ykazakov
Copy link

ykazakov commented Jan 29, 2018

@ignazio1977 could you provide a bit more detail how to do it using AutoIRIMapper.
Should this be enough?

 ontologyManager.getIRIMappers().add(new AutoIRIMapper(new File("ontologies.jar"), true));

This does not seem to work for me. I get (with OWL API v 5.1.4):

org.semanticweb.owlapi.model.UnloadableImportException: Could not load imported ontology: <http://www.example.com#impA> Cause: Problem parsing http://www.example.com#impA
Could not parse ontology. 

And below:

--------------------------------------------------------------------------------
Parser: org.semanticweb.owlapi.functional.parser.OWLFunctionalSyntaxOWLParser@29a60c27
    Stack trace:
Encountered unexpected token: "<!doctype html>" <FULLIRI>
    at line 1, column 1.

Was expecting one of:

    "Ontology"
    "Prefix"

My jar contains an ontology in functional-style syntax with the required IRI.

If necessary I can create a complete test, but I wanted to double check if this is a proper way to load imports from jar.

@ykazakov
Copy link

I also tried to give the AutoIRIMapper as an argument the directory in which the jar is located with the same result. The documentation of AutoIRIMapper also does not seem to mention jar files.

@ignazio1977
Copy link
Contributor

Can you attach the jar you're using?

The error message shows a fragment of HTML page - I suspect there might be an unresolvable import.

@ykazakov
Copy link

Here you go: owlapi5-tryout.zip

@ykazakov
Copy link

Interesting, if I replace the ontology IRIs from

<http://www.example.com#impA>

to

<http://www.example.com/A>

Then I get a different error message:

java.io.FileNotFoundException: http://www.example.com/A

Here is the update project: owlapi5-tryout.zip

@ykazakov
Copy link

The @donmendelson solution does not seem to work for me either.
If instead of adding AutoIRIMapper I do:

man.getIRIMappers().add(new SimpleIRIMapper(IRI.create("http://www.example.com/A"),
					IRI.create(jarClassLoader.getResource("impA.owl"))));

I get:

Could not find an appropriate factory to load ontology from ontology document: <jar:file:/path/to/target/owlapi5-tryout-0.0.1-SNAPSHOT-ontologies.jar!/impA.owl>

@ykazakov
Copy link

OK, I checked the source code and I think the changes to AutoIRIMapper have not been released yet.
@ignazio1977, is there a snapshot repository for OWL API?
Is there a workarounds to load imports from a jar file for the released OWL API?

@ykazakov
Copy link

OK, one workaround would be to create a custom OWLOntologyFactory which would load ontologies from the jar file using their IRIs. Here is an example:

	man.getOntologyFactories().add(new OWLOntologyFactory() {

		private static final long serialVersionUID = 1L;

		public OWLOntology createOWLOntology(OWLOntologyManager manager,
				OWLOntologyID ontologyID, IRI documentIRI,
				OWLOntologyCreationHandler handler)
				throws OWLOntologyCreationException {
			return null;
		}

		public OWLOntology loadOWLOntology(OWLOntologyManager manager,
				OWLOntologyDocumentSource documentSource,
				OWLOntologyCreationHandler handler,
				OWLOntologyLoaderConfiguration configuration)
				throws OWLOntologyCreationException {
			// Get the name of the ontology file inside the jar
			String name = documentSource.getDocumentIRI().getFragment()
					+ ".owl";
			return manager.loadOntologyFromOntologyDocument(
					jarClassLoader.getResourceAsStream(name));
		}

		public boolean canCreateFromDocumentIRI(IRI documentIRI) {
			return false;
		}

		public boolean canAttemptLoading(
				OWLOntologyDocumentSource documentSource) {
			return (documentSource instanceof IRIDocumentSource);
		}

	});

Here is the example project which now works: owlapi5-tryout.zip

@ignazio1977
Copy link
Contributor

Another way would be to cherry pick the changes to AutoIRIMapper, factory and zip mapper from the commits for #375. It is not finished yet as there are a few other requirements on the YAML format, but I wasn't planning on backporting those - people sneer at extra dependencies.

@ykazakov
Copy link

ykazakov commented Feb 6, 2018

@ignazio1977 It would be nice if it were documented how to use AutoIRIMapper to load ontologies from JAR files:

 /**
     * Creates an auto-mapper which examines ontologies that reside in the specified root folder
     * (and possibly sub-folders).
     *
     * @param rootDirectory The root directory which should be searched for ontologies.
     * @param recursive Sub directories will be searched recursively if {@code true}.
     */
    public AutoIRIMapper(File rootDirectory, boolean recursive)

Does it now look for ontologies also in the jar/zip files in the provided rootDirectory? Or the rootDirectory must be a jar/zip file?

@ignazio1977
Copy link
Contributor

It works pointed directly at a zip/jar file or to a folder containing zip/jar files. I'll update the javadoc.

@ignazio1977 ignazio1977 moved this from Brain Storming to Done in OWLAPI 6 Project Feb 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

3 participants