diff --git a/html/relnotes.html b/html/relnotes.html index 9345eaf98f8e37d144a53bad557b44d6f43ede1a..baaa6cc82f90cc86f2987e21b7c364a138880585 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -84,8 +84,9 @@ with a warning: <li>Added a command-line utility for query translation (cli)</li> <li>Added a guard forbiding to create a <tt>BasicCell</tt> with null objects (impl)</li> <li>Added httpcore library necessary for tutorial4 (tutorial/lib)</li> -<li>Added extensions to BasicOntologyNetwork (impl)</li> -<li>Genericised storage <tt>Cache</tt> and implemented <tt>VolatilCache</tt> (serv)</li> +<li>Added extensions to <tt>BasicOntologyNetwork</tt> (impl)</li> +<li>Added read/write to <tt>BasicOntologyNetwork</tt> (impl)</li> +<li>Genericised storage <tt>Cache</tt> and implemented <tt>VolatilCache</tt> which contains a full Cache implementation without storage (serv)</li> </ul></p> <h2>Version 4.6 (1875): 22/01/2014 - Da lec'h all</h2> diff --git a/src/fr/inrialpes/exmo/align/impl/BasicOntologyNetwork.java b/src/fr/inrialpes/exmo/align/impl/BasicOntologyNetwork.java index b1c8cfc34957235a9ff8a2a40d42ffa470f3b439..39942ce70f423932849b09b974c70f88e5a85840 100644 --- a/src/fr/inrialpes/exmo/align/impl/BasicOntologyNetwork.java +++ b/src/fr/inrialpes/exmo/align/impl/BasicOntologyNetwork.java @@ -32,9 +32,29 @@ import java.util.Set; import java.util.HashSet; import java.util.Hashtable; import java.net.URI; +import java.net.URISyntaxException; + +import java.io.PrintWriter; +import java.io.InputStream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.ModelFactory; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.rdf.model.StmtIterator; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Property; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.vocabulary.RDF; import fr.inrialpes.exmo.ontowrap.Ontology; +import fr.inrialpes.exmo.align.parser.SyntaxElement; +import fr.inrialpes.exmo.align.parser.AlignmentParser; +import fr.inrialpes.exmo.align.impl.Namespace; + import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.OntologyNetwork; @@ -45,6 +65,7 @@ import org.semanticweb.owl.align.OntologyNetwork; */ public class BasicOntologyNetwork implements OntologyNetwork { + final static Logger logger = LoggerFactory.getLogger( BasicOntologyNetwork.class ); protected Hashtable<URI,OntologyTriple> ontologies; protected HashSet<Alignment> alignments; @@ -127,6 +148,12 @@ public class BasicOntologyNetwork implements OntologyNetwork { for ( Alignment al : newal ) addAlignment( al ); } + /** + * Add alignments only if there is no existing alignments + public void match( Class<? extends AlignmentProcess> method, boolean reflexive ) throws AlignmentException { + } + */ + public Set<Alignment> getAlignments(URI srcOnto, URI dstOnto) { Map<URI,Set<Alignment>> m = onto2Align.get(srcOnto); if (m!=null) { @@ -148,6 +175,129 @@ public class BasicOntologyNetwork implements OntologyNetwork { return extensions.getExtension( uri, label ); }; + /** + * Printing + * here we do not use renderers; may be later + */ + + protected String NL = System.getProperty("line.separator"); + protected String INDENT = " "; + private static Namespace DEF = Namespace.ALIGNMENT; + public void setIndentString( String ind ) { INDENT = ind; } + public void setNewLineString( String nl ) { NL = nl; } + + public void write( PrintWriter writer ) throws AlignmentException { + writer.print("<?xml version='1.0' encoding='utf-8"); + writer.print("' standalone='no'?>"+NL+NL); + writer.print("<"+SyntaxElement.RDF.print(DEF)+" xmlns='"+Namespace.ALIGNMENT.prefix+"'"); + writer.print(NL+INDENT+INDENT+" xml:base='"+Namespace.ALIGNMENT.prefix+"'"); + writer.print(NL+INDENT+INDENT+" xmlns:"+Namespace.RDF.shortCut+"='"+Namespace.RDF.prefix+"'"); + writer.print(NL+INDENT+INDENT+" xmlns:"+Namespace.ALIGNMENT.shortCut+"='"+Namespace.ALIGNMENT.prefix+"'"); + writer.print(NL+INDENT+INDENT+" xmlns:"+Namespace.XSD.shortCut+"='"+Namespace.XSD.prefix+"'"); + String idext = getExtension( Namespace.ALIGNMENT.uri, Annotations.ID ); + writer.print(">"+NL+INDENT+"<"+SyntaxElement.ONTOLOGYNETWORK.print(DEF)); + if ( idext != null ) { + writer.print(" "+SyntaxElement.RDF_ABOUT.print(DEF)+"='"+idext+"'"); + } + writer.print(">"+NL); + for( URI u : ontologies.keySet() ) { + writer.print(INDENT+INDENT+"<"+SyntaxElement.ONONTOLOGY.print(DEF)+" rdf:resource=\'"+u+"'/>"+NL); + } + for( Alignment al : alignments ) { + String aluri = al.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID ); + if ( aluri != null ) { + writer.print(INDENT+INDENT+"<"+SyntaxElement.ONALIGNMENT.print(DEF)+" rdf:resource='"+aluri+"'/>"+NL); + } else { + throw new AlignmentException( "Cannot print alignment without URI : "+al ); + } + } + writer.print(INDENT+"</"+SyntaxElement.ONTOLOGYNETWORK.print(DEF)+">"+NL); + writer.print("</"+SyntaxElement.RDF.print(DEF)+">"+NL); + } + + /** + * Parsing + * here we use Jena + */ + + // Certainly not only URIs for testing reasons + public static OntologyNetwork read( String uri ) throws AlignmentException { + // Initialize the syntax description (could be restricted) + Model rdfModel = ModelFactory.createDefaultModel(); + for ( SyntaxElement el : SyntaxElement.values() ) { + if ( el.isProperty == true ) { + el.resource = rdfModel.createProperty( el.id() ); + } else { + el.resource = rdfModel.createResource( el.id() ); + } + } + // Parse with JENA + rdfModel.read( uri ); + // Collect data + return parse( rdfModel ); + } + + public static OntologyNetwork read( InputStream is ) throws AlignmentException { + if (is == null) throw new AlignmentException("The inputstream must not be null"); + // Initialize the syntax description (could be restricted) + Model rdfModel = ModelFactory.createDefaultModel(); + for ( SyntaxElement el : SyntaxElement.values() ) { + if ( el.isProperty == true ) { + el.resource = rdfModel.createProperty( el.id() ); + } else { + el.resource = rdfModel.createResource( el.id() ); + } + } + // Parse with JENA + rdfModel.read( is, null ); + // Collect data + return parse( rdfModel ); + } + + public static OntologyNetwork parse( final Model rdfModel ) throws AlignmentException { + BasicOntologyNetwork on = null; + // Get the statement including alignment resource as rdf:type + StmtIterator stmtIt = rdfModel.listStatements(null, RDF.type,(Resource)SyntaxElement.getResource("OntologyNetwork")); + // Take the first one if it exists + if ( !stmtIt.hasNext() ) throw new AlignmentException("There is no ontology network in the RDF document"); + Statement node = stmtIt.nextStatement(); + if (node == null) throw new NullPointerException("OntologyNetwork must not be null"); + Resource res = node.getSubject(); + + try { + on = new BasicOntologyNetwork(); + // getting the id of the document + final String id = res.getURI(); + if ( id != null ) on.setExtension( Namespace.ALIGNMENT.uri, Annotations.ID, id ); + + stmtIt = res.listProperties((Property)SyntaxElement.ONONTOLOGY.resource ); + while ( stmtIt.hasNext() ) { + RDFNode onto = stmtIt.nextStatement().getObject(); + if ( onto.isURIResource() ) { + on.addOntology( new URI( onto.asResource().getURI() ) ); + } else { + throw new AlignmentException( "Ontologies must be identified by URIs" ); + } + } + AlignmentParser aparser = new AlignmentParser(); + stmtIt = res.listProperties((Property)SyntaxElement.ONALIGNMENT.resource ); + while ( stmtIt.hasNext() ) { + RDFNode al = stmtIt.nextStatement().getObject(); + if ( al.isURIResource() ) { + on.addAlignment( aparser.parse( al.asResource().getURI() ) ); + } else { + logger.debug( "IGNORED Exception : Alignments must be identified by URIs" ); + } + } + } catch ( AlignmentException alex ) { + throw alex; + } catch ( URISyntaxException urisex ) { + throw new AlignmentException("There is some error in parsing alignment: " + res.getLocalName(), urisex); + } finally { // Clean up memory + rdfModel.close(); + } + return on; + } } class OntologyTriple { diff --git a/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java b/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java index 7c7698e197c25affe96f4c6f024e5ab50faeaa47..1b8d1face9148bb2fbfc978a654a73431472f1c5 100644 --- a/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java +++ b/src/fr/inrialpes/exmo/align/parser/SyntaxElement.java @@ -59,6 +59,10 @@ public enum SyntaxElement { IDENTIFIER( Namespace.DUBLIN_CORE, "identifier"), // ALIGNMENT NAMESPACE + ONTOLOGYNETWORK(Namespace.ALIGNMENT, "OntologyNetwork", true), + ONID( Namespace.ALIGNMENT, "id"), + ONONTOLOGY( Namespace.ALIGNMENT, "ontology"), + ONALIGNMENT( Namespace.ALIGNMENT, "alignment"), ALIGNMENT( Namespace.ALIGNMENT, "Alignment", true), ALID( Namespace.ALIGNMENT, "id"), CELL( Namespace.ALIGNMENT, "Cell", true), diff --git a/src/org/semanticweb/owl/align/OntologyNetwork.java b/src/org/semanticweb/owl/align/OntologyNetwork.java index 30a18955b98167575287c4d4988a454569184756..05d625a8f8cf6cbab9705b0da634ae7ee9977cb9 100644 --- a/src/org/semanticweb/owl/align/OntologyNetwork.java +++ b/src/org/semanticweb/owl/align/OntologyNetwork.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2010 + * Copyright (C) INRIA, 2009-2010, 2014 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -32,8 +32,6 @@ import fr.inrialpes.exmo.ontowrap.Ontology; /** * Represents a distributed system of aligned ontologies or network of ontologies. * - * @author J�r�me Euzenat - * @version $Id$ */ public interface OntologyNetwork extends Cloneable { diff --git a/test/src/OntologyNetworkTest.java b/test/src/OntologyNetworkTest.java index 143af60adf2e489ad9c3db7e452fdead8be377d8..37aec473e6a6bdf5bfdfb3a44b18a58c07189ac6 100644 --- a/test/src/OntologyNetworkTest.java +++ b/test/src/OntologyNetworkTest.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2008-2011, 2013 + * Copyright (C) INRIA, 2008-2011, 2013-2014 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -30,19 +30,35 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Set; import java.util.Properties; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.PrintWriter; +import java.io.BufferedWriter; +import java.io.OutputStreamWriter; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; + import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; +import fr.inrialpes.exmo.align.impl.Namespace; +import fr.inrialpes.exmo.align.impl.Annotations; import fr.inrialpes.exmo.align.impl.BasicOntologyNetwork; import fr.inrialpes.exmo.align.impl.URIAlignment; +import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor; + import fr.inrialpes.exmo.align.parser.AlignmentParser; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.OntologyNetwork; + import fr.inrialpes.exmo.ontowrap.Ontology; import fr.inrialpes.exmo.ontowrap.OntologyFactory; + import fr.inrialpes.exmo.align.gen.OntologyNetworkWeakener; import fr.inrialpes.exmo.align.gen.NetworkAlignmentDropper; import fr.inrialpes.exmo.align.gen.NetworkCorrespondenceDropper; @@ -386,4 +402,92 @@ public class OntologyNetworkTest { public void weakenNDExceptionTest12() throws URISyntaxException, AlignmentException { new NetworkDeconnector().weaken( noo, -.2, (Properties)null ); } + + /** + * HERE WE SHOULD ADD TESTS FOR PRINTER/WRITER + * - print on + * - read it + * - do it with an empty OntologyNetwork first + */ + @Test(groups = { "full", "raw" }, dependsOnMethods = {"expandTest"}) + public void printEmptyNetworkTest() throws URISyntaxException, AlignmentException, UnsupportedEncodingException { + BasicOntologyNetwork newnoo = new BasicOntologyNetwork(); + newnoo.setIndentString( "" ); + newnoo.setNewLineString( "" ); + // Print it in a string + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + try { + newnoo.write( writer ); + } finally { + writer.flush(); + writer.close(); + } + String str1 = stream.toString(); + assertEquals( str1, "<?xml version='1.0' encoding='utf-8' standalone='no'?><rdf:RDF xmlns='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xml:base='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:align='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xmlns:xsd='http://www.w3.org/2001/XMLSchema#'><OntologyNetwork></OntologyNetwork></rdf:RDF>" ); + } + + @Test(groups = { "full", "raw" }, dependsOnMethods = {"expandTest"},expectedExceptions = AlignmentException.class) + public void printNoURINetworkTest() throws URISyntaxException, AlignmentException, UnsupportedEncodingException { + BasicOntologyNetwork newnoo = (BasicOntologyNetwork)noo; + newnoo.setIndentString( "" ); + newnoo.setNewLineString( "" ); + // Print it in a string + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + try { + newnoo.write( writer ); + } finally { + writer.flush(); + writer.close(); + } + } + + @Test(groups = { "full", "raw" }, dependsOnMethods = {"printNoURINetworkTest"}) + public void printNetworkTest() throws FileNotFoundException, URISyntaxException, AlignmentException, UnsupportedEncodingException { + BasicOntologyNetwork newnoo = (BasicOntologyNetwork)noo; + newnoo.setIndentString( "" ); + newnoo.setNewLineString( "" ); + int i = 0; + String prefix = "test/output/align"; + for( Alignment al : newnoo.getAlignments() ) { + i++; + al.setExtension( Namespace.ALIGNMENT.uri, Annotations.ID, "file:"+prefix+i+".rdf" ); + // I should also save these alignments... + FileOutputStream stream = new FileOutputStream( prefix+i+".rdf" ); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + try { + al.render( new RDFRendererVisitor( writer ) ); + } finally { + writer.flush(); + writer.close(); + } + } + // Print it in a string + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter ( + new BufferedWriter( + new OutputStreamWriter( stream, "UTF-8" )), true); + try { + newnoo.write( writer ); + } finally { + writer.flush(); + writer.close(); + } + String str1 = stream.toString(); + //System.err.println(str1); + assertEquals( str1, "<?xml version='1.0' encoding='utf-8' standalone='no'?><rdf:RDF xmlns='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xml:base='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:align='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#' xmlns:xsd='http://www.w3.org/2001/XMLSchema#'><OntologyNetwork><ontology rdf:resource='http://www.example.org/ontology2'/><ontology rdf:resource='http://www.example.org/ontology1'/><ontology rdf:resource='file:examples/rdf/edu.mit.visus.bibtex.owl'/><ontology rdf:resource='file:examples/rdf/edu.umbc.ebiquity.publication.owl'/><alignment rdf:resource='file:test/output/align1.rdf'/><alignment rdf:resource='file:test/output/align2.rdf'/><alignment rdf:resource='file:test/output/align3.rdf'/><alignment rdf:resource='file:test/output/align4.rdf'/><alignment rdf:resource='file:test/output/align5.rdf'/><alignment rdf:resource='file:test/output/align6.rdf'/></OntologyNetwork></rdf:RDF>" ); + // Read it from the string + OntologyNetwork bon = BasicOntologyNetwork.read( new ByteArrayInputStream( str1.getBytes() ) ); + // Check the topology + assertEquals( bon.getAlignments().size(), 6 ); + assertEquals( bon.getOntologies().size(), 4 ); + } + }