From 2dea2a28a0aefe246dd08a513372c73aa0d7c64b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Wed, 20 Apr 2011 07:12:36 +0000
Subject: [PATCH] - replaced EDOALRelation by BasicRelation - implemented
 Relation cache in BasicRelation

---
 html/relnotes.html                            |   6 +-
 .../exmo/align/impl/BasicRelation.java        | 158 +++++++---
 .../exmo/align/impl/rel/EquivRelation.java    |  20 +-
 .../align/impl/rel/HasInstanceRelation.java   |  68 +++++
 .../exmo/align/impl/rel/IncompatRelation.java |  24 +-
 .../align/impl/rel/InstanceOfRelation.java    |  68 +++++
 .../rel/NonTransitiveImplicationRelation.java |  18 +-
 .../exmo/align/impl/rel/SubsumeRelation.java  |  29 +-
 .../exmo/align/impl/rel/SubsumedRelation.java |  26 +-
 .../renderer/OWLAxiomsRendererVisitor.java    | 287 ++++++++++--------
 .../exmo/align/parser/RDFParser.java          |   7 +-
 .../align/parser/TypeCheckingVisitor.java     |  15 +-
 test/src/EDOALTest.java                       |  13 +-
 13 files changed, 503 insertions(+), 236 deletions(-)
 create mode 100644 src/fr/inrialpes/exmo/align/impl/rel/HasInstanceRelation.java
 create mode 100644 src/fr/inrialpes/exmo/align/impl/rel/InstanceOfRelation.java

diff --git a/html/relnotes.html b/html/relnotes.html
index 5aaad6c7..b7bbe9dd 100644
--- a/html/relnotes.html
+++ b/html/relnotes.html
@@ -58,14 +58,18 @@ The development of 4 versions continues.
 <h2>Current SVN trunk version</h2>
 
 <!--h2>Version 4.3 (): xx/xx/xxxx - Zimt</h2-->
-<!--h2>Version 4.2 (): xx/xx/2011 - Tring</h2-->
+<!--h2>Version 4.2 (): xx/05/2011 - Tring</h2-->
 
 <p><ul compact="1">
 <li>Added type checking to EDOAL parser (parser)</li>
 <li>Added <tt>WeightedPRecEvaluator</tt> weighting confidences (eval)</li>
 <li>Added <tt>toURIAlignment</tt> and <tt>toEDOALAlignment</tt> for <tt>EDOALAlignment</tt> (edoal)</li>
+<li>Added matching test generator facility (gen)</li>
+<li>Suppressed <tt>EDOALRelation</tt>: EDOAL uses <tt>BasicRelation</tt> (edoal)</li>
+<li>EDOAL default printout now uses pretty relations, i.e., &lt;, &gt;, =, % (edoal)</li>
 <li>Changed order of display to precision/F-measure/recall (util)</li>
 <li><span style="color: red;">Suppressed</span> incorrect computation of fallout (eval)</li>
+<li>Upgraded to <span style="color: green">OntoSim 2.1??</span> (lib)</li>
 <li>Minor display changes in HTML display (server)</li>
 </ul></p>
 
diff --git a/src/fr/inrialpes/exmo/align/impl/BasicRelation.java b/src/fr/inrialpes/exmo/align/impl/BasicRelation.java
index 80574c31..2cb06d95 100644
--- a/src/fr/inrialpes/exmo/align/impl/BasicRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/BasicRelation.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2005, 2007, 2009-2010
+ * Copyright (C) INRIA, 2003-2005, 2007, 2009-2011
  *
  * 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
@@ -20,20 +20,20 @@
 
 package fr.inrialpes.exmo.align.impl;
 
-import fr.inrialpes.exmo.align.impl.rel.EquivRelation;
-import fr.inrialpes.exmo.align.impl.rel.SubsumeRelation;
-import fr.inrialpes.exmo.align.impl.rel.SubsumedRelation;
-import fr.inrialpes.exmo.align.impl.rel.IncompatRelation;
-import fr.inrialpes.exmo.align.impl.rel.NonTransitiveImplicationRelation;
+import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.Relation;
 
+import org.xml.sax.ContentHandler;
+
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.ClassNotFoundException;
 import java.io.PrintWriter;
-
-import org.xml.sax.ContentHandler;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Represents an ontology alignment relation.
@@ -42,52 +42,118 @@ import org.xml.sax.ContentHandler;
  * @version $Id$
  */
 
-public class BasicRelation implements Relation
-{
+public class BasicRelation implements Relation {
+
+    private static Map<String, Class<?>> classIndex = null;
+
+    static Class<?> getClass( String label ) {
+	if ( label == null ) 
+	    throw new NullPointerException("The string to search must not be null");
+	if ( classIndex == null ){
+	    classIndex = new HashMap<String, Class<?>>();
+	    try {
+		Class<?> eq = Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation");
+		Class<?> sub = Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation");
+		Class<?> sup = Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation");
+		Class<?> dis = Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation");
+		Class<?> ins = Class.forName("fr.inrialpes.exmo.align.impl.rel.InstanceOfRelation");
+		Class<?> has = Class.forName("fr.inrialpes.exmo.align.impl.rel.HasInstanceRelation");
+		Class<?> nti = Class.forName("fr.inrialpes.exmo.align.impl.rel.NonTransitiveImplicationRelation");
+		
+		classIndex.put( "Equivalence", eq );
+		classIndex.put( "=", eq );
+		classIndex.put( "equivalence", eq );
+		classIndex.put( "ClassMapping", eq );
+		
+		classIndex.put( "Subsumes", sup );
+		classIndex.put( ">", sup );
+		classIndex.put( "&gt;", sup );
+		
+		classIndex.put( "SubsumedBy", sub );
+		classIndex.put( "<", sub );
+		classIndex.put( "&lt;", sub );
+		
+		classIndex.put("><", dis );
+		classIndex.put("%", dis );
+		classIndex.put("DisjointFrom",dis);
+		classIndex.put("Disjoint",dis);
+		classIndex.put("disjointFrom",dis);
+		classIndex.put("disjoint",dis);
+	    
+		classIndex.put( "InstanceOf", ins );
+	    
+		classIndex.put( "HasInstance", has );
+
+		classIndex.put( "~>", nti );
+		classIndex.put( "~&gt;", nti );
+	    } catch ( ClassNotFoundException cnfe ) {
+		cnfe.printStackTrace(); // should never occur
+	    }
+	}
+	return classIndex.get(label);
+    }
+
+    public void accept( TypeCheckingVisitor visitor ) throws AlignmentException {
+	visitor.visit(this);
+    }
+
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
+
     /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
+     * The initial relation given by the user (through parser for instance)
+     * This is never used in subclass relations (because they share one relation)
      */
     protected String relation = null;
 
-    /** Creation **/
-    public BasicRelation( String rel ){
-	relation = rel;
-    }
-
     /** printable format **/
     public String getRelation() {
 	return relation;
     }
 
+    /**
+     * The pretty relation attached to the relation type
+     * This is overriden as static in subclasses
+     */
+    protected String prettyLabel = null;
+
+    public String getPrettyLabel() {
+	return prettyLabel;
+    }
+
+    /**
+     * The name to use if no other information is available
+     */
+    public String getClassName() {
+	return getClass().toString();
+    }
+
+    /** Creation **/
+    public BasicRelation( String rel ){
+	relation = rel;
+    }
+
+    /**
+     * The constructor to use
+     */
     public static Relation createRelation( String rel ) {
-	Relation relation = null;
-	if ( rel.equals("=") ) {
-	    relation = new EquivRelation();
-	} else if ( rel.equals("<") || rel.equals("&lt;") ) {
-	    relation = new SubsumedRelation();
-	} else if ( rel.equals(">") || rel.equals("&gt;") ) {
-	    relation = new SubsumeRelation();
-	} else if ( rel.equals("%") ) {
-	    relation = new IncompatRelation();
-	} else if ( rel.equals("~>") || rel.equals("~&gt;") ) {
-	    relation = new NonTransitiveImplicationRelation();
-	} else {
-	    try {
-		// Create a relation from classname
-		Class<?> relationClass = Class.forName(rel);
-		Constructor relationConstructor = relationClass.getConstructor((Class[])null);
-		relation = (Relation)relationConstructor.newInstance((Object[])null);
-	    } catch ( Exception ex ) {
-		//ex.printStackTrace();
-		//Otherwise, just create a Basic relation
-		relation = (Relation)new BasicRelation( rel );
-	    }
-	};
-	return relation;
+	Class<?> relationClass = getClass( rel );
+	if ( relationClass != null ) {
+	    try { // Get existing relation... 
+		Method m = relationClass.getMethod("getInstance");
+		return (Relation)m.invoke(null);
+	    } catch ( Exception ex ) {}; // should not happen
+	}
+	try { // Create a relation from classname
+	    relationClass = Class.forName(rel);
+	    Constructor relationConstructor = relationClass.getConstructor((Class[])null);
+	    return (Relation)relationConstructor.newInstance((Object[])null);
+	} catch ( Exception ex ) {
+	    //ex.printStackTrace();
+	    //Otherwise, just create a Basic relation
+	    return new BasicRelation( rel );
+	}
     }
 
     /** By default the inverse is the relation itself **/
@@ -95,7 +161,7 @@ public class BasicRelation implements Relation
 	return this;
     }
 
-    /** By default...**/
+    /** By default... no composition possible **/
     public Relation compose( Relation r ) {
     	return null;
     }
@@ -117,7 +183,13 @@ public class BasicRelation implements Relation
 
     /** This is kept for displayig more correctly the result **/
     public void write( PrintWriter writer ) {
-	writer.print(relation);
+	if ( relation != null ) {
+	    writer.print( relation );
+	} else if ( getPrettyLabel() != null ) {
+	    writer.print( getPrettyLabel() );
+	} else {
+	    writer.print( getClassName() );
+	}
     }
 }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
index 1ad25d26..6fd79a97 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
@@ -1,6 +1,7 @@
 /*
  * $Id$
- * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * Copyright (C) INRIA, 2004, 2008, 2011
  *
  * 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
@@ -37,18 +38,23 @@ public class EquivRelation extends BasicRelation
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
 	visitor.visit( this );
     }
-    /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
-     */
+
+    static final String prettyLabel = "=";
 
     /** Creation **/
     public EquivRelation(){
-	super("=");
+	super(prettyLabel);
+    }
+
+    private static EquivRelation instance = null;
+
+    public static EquivRelation getInstance() {
+	if ( instance == null ) instance = new EquivRelation();
+	return instance;
     }
 
     public Relation compose(Relation r) {
-		return r;
+	return r;
     }
 
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/HasInstanceRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/HasInstanceRelation.java
new file mode 100644
index 00000000..2b909790
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/rel/HasInstanceRelation.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA, 2004, 2008, 2011
+ *
+ * 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
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl.rel;
+
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.Relation;
+
+import fr.inrialpes.exmo.align.impl.BasicRelation;
+
+/**
+ * Represents an OWL equivalence relation.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$
+ */
+
+public class HasInstanceRelation extends BasicRelation
+{
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+	visitor.visit( this );
+    }
+
+    static final String prettyLabel = "HasInstance";
+
+    /** Creation **/
+    public HasInstanceRelation(){
+	super(prettyLabel);
+    }
+
+    private static HasInstanceRelation instance = null;
+
+    public static HasInstanceRelation getInstance() {
+	if ( instance == null ) instance = new HasInstanceRelation();
+	return instance;
+    }
+
+    public Relation compose(Relation r) {
+    	if ( r instanceof EquivRelation )
+	    return this;
+    	return null;
+    }
+
+    public Relation inverse() {
+	return InstanceOfRelation.getInstance();
+    }
+
+}
+
+
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java
index 77a19817..a017d066 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/IncompatRelation.java
@@ -1,6 +1,7 @@
 /*
  * $Id$
- * Copyright (C) INRIA Rhône-Alpes, 2004
+ *
+ * Copyright (C) INRIA, 2004, 2008, 2011
  *
  * 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
@@ -37,19 +38,24 @@ public class IncompatRelation extends BasicRelation
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
-    /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
-     */
+
+    static final String prettyLabel = "%";
 
     /** Creation **/
     public IncompatRelation(){
-	super("%");
+	super(prettyLabel);
+    }
+
+    private static IncompatRelation instance = null;
+
+    public static IncompatRelation getInstance() {
+	if ( instance == null ) instance = new IncompatRelation();
+	return instance;
     }
 
-    public Relation compose(Relation r) {
-    	if (r instanceof EquivRelation || r instanceof SubsumeRelation)
-    		return this;
+    public Relation compose( Relation r ) {
+    	if ( r instanceof EquivRelation || r instanceof SubsumeRelation )
+	    return this;
     	return null;
     }
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/InstanceOfRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/InstanceOfRelation.java
new file mode 100644
index 00000000..6a4256b3
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/rel/InstanceOfRelation.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA, 2011
+ *
+ * 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
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+package fr.inrialpes.exmo.align.impl.rel;
+
+import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.AlignmentVisitor;
+import org.semanticweb.owl.align.Relation;
+
+import fr.inrialpes.exmo.align.impl.BasicRelation;
+
+/**
+ * Represents a relation between an instance and its class.
+ *
+ * @author Jérôme Euzenat
+ * @version $Id$
+ */
+
+public class InstanceOfRelation extends BasicRelation
+{
+    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+	visitor.visit( this );
+    }
+
+    static final String prettyLabel = "InstanceOf";
+
+    /** Creation **/
+    public InstanceOfRelation(){
+	super(prettyLabel);
+    }
+
+    private static InstanceOfRelation instance = null;
+
+    public static InstanceOfRelation getInstance() {
+	if ( instance == null ) instance = new InstanceOfRelation();
+	return instance;
+    }
+
+    public Relation compose(Relation r) {
+    	if ( r instanceof EquivRelation || r instanceof SubsumedRelation )
+	    return this;
+    	return null;
+    }
+
+    public Relation inverse() {
+	return HasInstanceRelation.getInstance();
+    }
+
+}
+
+
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/NonTransitiveImplicationRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/NonTransitiveImplicationRelation.java
index 7bfb1066..8fd81388 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/NonTransitiveImplicationRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/NonTransitiveImplicationRelation.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
 ¨*
- * Copyright (C) INRIA Rhône-Alpes, 2004-2005
+ * Copyright (C) INRIA, 2004-2005, 2008, 2011
  *
  * 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
@@ -38,17 +38,21 @@ public class NonTransitiveImplicationRelation extends BasicRelation
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
-    /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
-     */
+
+    static final String prettyLabel = "~>";
 
     /** Creation **/
     public NonTransitiveImplicationRelation(){
-	super("~>");
+	super(prettyLabel);
     }
     
-    
+    private static NonTransitiveImplicationRelation instance = null;
+
+    public static NonTransitiveImplicationRelation getInstance() {
+	if ( instance == null ) instance = new NonTransitiveImplicationRelation();
+	return instance;
+    }
+
 }
 
 
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java
index b97267a7..bd89729d 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/SubsumeRelation.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA Rhône-Alpes, 2004, 2008
+ * Copyright (C) INRIA, 2004, 2008, 2011
  *
  * 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
@@ -39,22 +39,33 @@ public class SubsumeRelation extends BasicRelation
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
-    /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
-     */
+
+    static final String prettyLabel = ">";
 
     /** Creation **/
     public SubsumeRelation(){
-	super(">");
+	super(prettyLabel);
+    }
+
+    private static SubsumeRelation instance = null;
+
+    public static SubsumeRelation getInstance() {
+	if ( instance == null ) instance = new SubsumeRelation();
+	return instance;
     }
 
-    public Relation compose(Relation r) {
-    	if (r.equals(this) || r instanceof EquivRelation)
-    		return this;
+    public Relation compose( Relation r ) {
+    	if ( r instanceof SubsumeRelation || r instanceof EquivRelation )
+	    return this;
+	else if ( r instanceof HasInstanceRelation )
+	    return HasInstanceRelation.getInstance();
     	return null;
     }
 
+    public Relation inverse() {
+	return SubsumedRelation.getInstance();
+    }
+
 }
 
 
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/SubsumedRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/SubsumedRelation.java
index c7111960..5217fca1 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/SubsumedRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/SubsumedRelation.java
@@ -1,6 +1,7 @@
 /*
  * $Id$
- * Copyright (C) INRIA Rhône-Alpes, 2004-2005
+ *
+ * Copyright (C) INRIA, 2004-2005, 2008, 2011
  *
  * 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
@@ -39,24 +40,33 @@ public class SubsumedRelation extends BasicRelation
     public void accept( AlignmentVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
-    /**
-     * It is intended that the value of the relation is =, < or >.
-     * But this can be any string in other applications.
-     */
+
+    static final String prettyLabel = "<";
 
     /** Creation **/
     public SubsumedRelation(){
-	super("<");
+	super(prettyLabel);
+    }
+
+    private static SubsumedRelation instance = null;
+
+    public static SubsumedRelation getInstance() {
+	if ( instance == null ) instance = new SubsumedRelation();
+	return instance;
     }
 
     public Relation compose(Relation r) {
-    	if (r.equals(this) || r instanceof EquivRelation)
+    	if ( r.equals(this) || r instanceof EquivRelation )
     		return this;
-    	else if (r instanceof IncompatRelation)
+    	else if ( r instanceof IncompatRelation )
     		return r;
     	return null;
     }
 
+    public Relation inverse() {
+	return SubsumeRelation.getInstance();
+    }
+
     public void write( PrintWriter writer ) {
         writer.print("&lt;");
     }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
index 02042218..0b0f0d1c 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2004, 2007-2010
+ * Copyright (C) INRIA, 2003-2004, 2007-2011
  *
  * 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
@@ -80,7 +80,6 @@ import fr.inrialpes.exmo.align.impl.edoal.Value;
 import fr.inrialpes.exmo.align.impl.edoal.Apply;
 import fr.inrialpes.exmo.align.impl.edoal.Datatype;
 import fr.inrialpes.exmo.align.impl.edoal.Comparator;
-import fr.inrialpes.exmo.align.impl.edoal.EDOALRelation;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
 
@@ -203,7 +202,103 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 	}
     }
 
-    public String getRelationName( LoadedOntology onto, Object ob, Relation rel ) {
+    public void visit( EDOALCell cell ) throws AlignmentException {
+	this.cell = cell;
+	toProcess = cell.getRelation();
+	if ( toProcess instanceof SubsumeRelation || toProcess instanceof HasInstanceRelation ) {
+	    ((Expression)cell.getObject2()).accept( this );
+	} else {
+	    ((Expression)cell.getObject1()).accept( this );
+	}
+	writer.print(NL);
+    }
+
+    // Classical dispatch
+    // This is the previous code... which is the one which was used.
+    // It should be reintroduced in the dispatch!
+    public void visit( Relation rel ) throws AlignmentException {
+	Object ob2 = cell.getObject2();
+	if ( edoal ) {
+	    String owlrel = getRelationName( rel, ob2 );
+	    if ( owlrel == null ) throw new AlignmentException( "Relation "+rel+" cannot apply to "+ob2 );
+	    writer.print("  <"+owlrel+">"+NL);
+	    increaseIndent();
+	    if ( rel instanceof HasInstanceRelation || rel instanceof SubsumeRelation ) {
+		((Expression)cell.getObject1()).accept( this );
+	    } else {
+		((Expression)ob2).accept( this );
+	    }
+	    decreaseIndent();
+	    writer.print(NL+"  </"+owlrel+">");
+	} else {
+	    String owlrel = getRelationName( onto2, rel, ob2 );
+	    if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
+	    }
+	}
+	/* This dispatch may be used for more customization
+	if ( rel instanceof EquivRelation ) visit( (EquivRelation)rel );
+	else if ( rel instanceof SubsumeRelation ) visit( (SubsumeRelation)rel );
+	else if ( rel instanceof SubsumedRelation ) visit( (SubsumedRelation)rel );
+	else if ( rel instanceof IncompatRelation ) visit( (IncompatRelation)rel );
+	else if ( rel instanceof InstanceOfRelation ) visit( (InstanceOfRelation)rel );
+	else if ( rel instanceof HasInstanceRelation ) visit( (HasInstanceRelation)rel );
+	*/
+    }
+
+
+    /**
+     * For EDOAL relation name depends on type of expressions
+     */
+    // The two getRelationName may be put as relation methods (this would be more customisable)
+    public String getRelationName( Relation rel, Object ob ) {
+	if ( rel instanceof EquivRelation ) {
+	    if ( ob instanceof ClassExpression ) {
+		return "owl:equivalentClass";
+	    } else if ( ob instanceof PropertyExpression || ob instanceof RelationExpression ) {
+		return "owl:equivalentProperty";
+	    } else if ( ob instanceof InstanceExpression ) {
+		return "owl:sameAs";
+	    }
+	} else if ( rel instanceof IncompatRelation ) {
+	    if ( ob instanceof ClassExpression ) {
+		return "owl:disjointFrom";
+	    } else if ( ob instanceof InstanceExpression ) {
+		return "owl:differentFrom";
+	    }
+	} else if ( rel instanceof SubsumeRelation ) {
+	    //reversed = true;
+	    if ( ob instanceof ClassExpression ) {
+		return "owl:subClassOf";
+	    } else if ( ob instanceof PropertyExpression || ob instanceof RelationExpression ) {
+		return "owl:subPropertyOf";
+	    }
+	} else if ( rel instanceof SubsumedRelation ) {
+	    if ( ob instanceof ClassExpression ) {
+		return "owl:subClassOf";
+	    } else if ( ob instanceof PropertyExpression || ob instanceof RelationExpression ) {
+		return "owl:subPropertyOf";
+	    }
+	} else if ( rel instanceof InstanceOfRelation ) {
+	    if ( ob instanceof InstanceExpression ) {
+		return "rdf:type";
+	    }
+	} else if ( rel instanceof HasInstanceRelation ) {
+	    //reversed = true;
+	    if ( ob instanceof InstanceExpression ) {
+		return "rdf:type";
+	    }
+	}
+	return null;
+    }
+
+    /**
+     * Regular: relation name depends on loaded ontology
+     */
+    public String getRelationName( LoadedOntology onto, Relation rel, Object ob ) {
 	try {
 	    if ( rel instanceof EquivRelation ) {
 		if ( onto.isClass( ob ) ) {
@@ -231,14 +326,28 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 		} else if ( onto.isIndividual( ob ) ) {
 		    return "owl:differentFrom";
 		}
+	    } else if ( rel instanceof InstanceOfRelation ) {
+		if ( onto.isClass( ob ) ) {
+		    return "rdf:type";
+		}
+	    } else if ( rel instanceof HasInstanceRelation ) {
+		// JE2011: this should be wrong (should be on the other side)
+		if ( onto.isClass( ob ) ) {
+		    return "rdf:type";
+		}
 	    }
 	} catch ( OntowrapException owex ) {}; // return null anyway
 	return null;
     }
 
+    /* This may be genericised
+       These methods are not used at the moment
+       However they are roughly correct and may be used for more customisation
+     */
+
     public void visit( EquivRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	String owlrel = getRelationName( onto2, ob2, rel );
+	String owlrel = getRelationName( onto2, rel, ob2 );
 	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
 	if ( !edoal ) {
 	    try {
@@ -259,14 +368,14 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 
     public void visit( SubsumeRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	String owlrel = getRelationName( onto2, ob2, rel );
+	String owlrel = getRelationName( onto2, rel, ob2 );
 	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
 	if ( !edoal ) {
-	try {
-	    writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
-	} catch ( OntowrapException owex ) {
-	    throw new AlignmentException( "Error accessing ontology", owex );
-	}
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
+	    }
 	} else {
 	    writer.println("    <"+owlrel+">");
 	    ((Expression)ob2).accept( this );
@@ -276,14 +385,14 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 
     public void visit( SubsumedRelation rel ) throws AlignmentException {
 	Object ob1 = cell.getObject1();
-	String owlrel = getRelationName( onto1, ob1, rel );
+	String owlrel = getRelationName( onto1, rel, ob1 );
 	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
 	if ( !edoal ) {
-	try {
-	    writer.print("    <"+owlrel+" rdf:resource=\""+onto1.getEntityURI( ob1 )+"\"/>"+NL);
-	} catch ( OntowrapException owex ) {
-	    throw new AlignmentException( "Error accessing ontology", owex );
-	}
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto1.getEntityURI( ob1 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
+	    }
 	} else {
 	    writer.println("    <"+owlrel+">");
 	    ((Expression)ob1).accept( this );
@@ -293,14 +402,14 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 
     public void visit( IncompatRelation rel ) throws AlignmentException {
 	Object ob2 = cell.getObject2();
-	String owlrel = getRelationName( onto2, ob2, rel );
+	String owlrel = getRelationName( onto2, rel, ob2 );
 	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
 	if ( !edoal ) {
-	try {
-	    writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
-	} catch ( OntowrapException owex ) {
-	    throw new AlignmentException( "Cannot find entity URI", owex );
-	}
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Cannot find entity URI", owex );
+	    }
 	} else {
 	    writer.println("    <"+owlrel+">");
 	    ((Expression)ob2).accept( this );
@@ -308,124 +417,38 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 	}
     }
 
-    public void visit( Relation rel ) throws AlignmentException {
-	if ( rel instanceof EDOALRelation ) visit( (EDOALRelation)rel );
-	else {
-	    // JE: I do not understand why I need this,
-	    // but this seems to be the case...
+    public void visit( InstanceOfRelation rel ) throws AlignmentException {
+	Object ob2 = cell.getObject2();
+	String owlrel = getRelationName( onto2, rel, ob2 );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
 	    try {
-		Method mm = null;
-		if ( Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation").isInstance(rel) ){
-		    mm = this.getClass().getMethod("visit",
-						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.EquivRelation")});
-		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation").isInstance(rel) ) {
-		    mm = this.getClass().getMethod("visit",
-						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumeRelation")});
-		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation").isInstance(rel) ) {
-		    mm = this.getClass().getMethod("visit",
-						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.SubsumedRelation")});
-		} else if (Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation").isInstance(rel) ) {
-		    mm = this.getClass().getMethod("visit",
-						   new Class [] {Class.forName("fr.inrialpes.exmo.align.impl.rel.IncompatRelation")});
-		}
-		if ( mm != null ) mm.invoke(this,new Object[] {rel});
-		else {
-		    if ( Class.forName("fr.inrialpes.exmo.align.impl.BasicRelation").isInstance(rel) ){
-			try {
-			    // This is only for individuals
-			    Object ob2 = cell.getObject2();
-			    if ( onto2.isIndividual( ob2 ) ) { 
-				// ob1 has been checked before
-				// It would be better to check that r is a relation of one of the ontologies by
-				// onto1.isObjectProperty( onto1.getEntity( new URI ( r ) ) )
-				String r = ((BasicRelation)rel).getRelation();
-				if ( r!=null && !r.equals("") ) {
-				    URI u2 = onto2.getEntityURI( ob2 );
-				    writer.print("    <"+r+" rdf:resource=\""+u2+"\"/>"+NL);
-				}
-			    }
-			} catch ( OntowrapException owex ) {
-			    throw new AlignmentException( "Error accessing ontology", owex );
-			}
-		    }
-		}
-	    } catch (IllegalAccessException e) {
-		e.printStackTrace();
-	    } catch (ClassNotFoundException e) {
-		e.printStackTrace();
-	    } catch (NoSuchMethodException e) {
-		e.printStackTrace();
-	    } catch (InvocationTargetException e) { 
-		e.printStackTrace();
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto2.getEntityURI( ob2 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Cannot find entity URI", owex );
 	    }
-	}
-    };
-
-    public void visit( EDOALCell cell ) throws AlignmentException {
-	this.cell = cell;
-	toProcess = cell.getRelation();
-	if ( ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.SUBSUMES
-	     && ((EDOALRelation)toProcess).getDirection() != EDOALRelation.Direction.HASINSTANCE ) {
-	    ((Expression)cell.getObject1()).accept( this );
 	} else {
-	    ((Expression)cell.getObject2()).accept( this );
+	    writer.println("    <"+owlrel+">");
+	    ((Expression)ob2).accept( this );
+	    writer.println("    </"+owlrel+">");
 	}
-	writer.print(NL);
     }
 
-    /**
-     * The current implementation is not satisfying:
-     * EDOALRelation is deconnected from Relation (for historical purposes)
-     * This is left this way because the complete relations should be reengineered
-     */
-    public void visit( EDOALRelation o ) throws AlignmentException {
-	String relName;
-	boolean reversed = false;
-	Object ob2 = cell.getObject2();
-	if ( o.getDirection() == EDOALRelation.Direction.EQUIVALENCE ) {
-	    if ( ob2 instanceof ClassExpression ) {
-		relName = "owl:equivalentClass";
-	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
-		relName = "owl:equivalentProperty";
-	    } else if ( ob2 instanceof InstanceExpression ) {
-		relName = "owl:sameAs";
-	    } else throw new AlignmentException( "Equivalence relation cannot apply to "+o );
-	} else if (  o.getDirection() == EDOALRelation.Direction.DISJOINTFROM ) {
-	    if ( ob2 instanceof ClassExpression ) {
-		relName = "owl:disjointFrom";
-	    } else if ( ob2 instanceof InstanceExpression ) {
-		relName = "owl:differentFrom";
-	    } else throw new AlignmentException( "Disjointness relation cannot apply to "+o );
-	} else if (  o.getDirection() == EDOALRelation.Direction.SUBSUMES ) {
-	    reversed = true;
-	    if ( ob2 instanceof ClassExpression ) {
-		relName = "owl:subClassOf";
-	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
-		relName = "owl:subPropertyOf";
-	    } else throw new AlignmentException( "Subsumption relation cannot apply to "+o );
-	} else if (  o.getDirection() == EDOALRelation.Direction.SUBSUMEDBY ) {
-	    if ( ob2 instanceof ClassExpression ) {
-		relName = "owl:subClassOf";
-	    } else if ( ob2 instanceof PropertyExpression || ob2 instanceof RelationExpression ) {
-		relName = "owl:subPropertyOf";
-	    } else throw new AlignmentException( "Subsumption relation cannot apply to "+o );
-	} else if (  o.getDirection() == EDOALRelation.Direction.INSTANCEOF ) {
-	    relName = "rdf:type";
-	} else if (  o.getDirection() == EDOALRelation.Direction.HASINSTANCE ) {
-	    reversed = true;
-	    relName = "rdf:type";
-	} else {
-	    throw new AlignmentException( "Cannot deal with relation "+o );
-	}
-	writer.print("  <"+relName+">"+NL);
-	increaseIndent();
-	if ( reversed ) {
-	    ((Expression)cell.getObject1()).accept( this );
+    public void visit( HasInstanceRelation rel ) throws AlignmentException {
+	Object ob1 = cell.getObject1();
+	String owlrel = getRelationName( onto1, rel, ob1 );
+	if ( owlrel == null ) throw new AlignmentException( "Cannot express relation "+rel );
+	if ( !edoal ) {
+	    try {
+		writer.print("    <"+owlrel+" rdf:resource=\""+onto1.getEntityURI( ob1 )+"\"/>"+NL);
+	    } catch ( OntowrapException owex ) {
+		throw new AlignmentException( "Error accessing ontology", owex );
+	    }
 	} else {
-	    ((Expression)ob2).accept( this );
+	    writer.println("    <"+owlrel+">");
+	    ((Expression)ob1).accept( this );
+	    writer.println("    </"+owlrel+">");
 	}
-	decreaseIndent();
-	writer.print(NL+"  </"+relName+">");
     }
 
     // ******* EDOAL
diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
index 392ba91f..d34b783e 100644
--- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java
+++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.7 - 2008
- * Copyright (C) INRIA, 2008-2010
+ * Copyright (C) INRIA, 2008-2011
  *
  * 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
@@ -23,16 +23,17 @@
 package fr.inrialpes.exmo.align.parser;
 
 import org.semanticweb.owl.align.AlignmentException;
+import org.semanticweb.owl.align.Relation;
 
 import fr.inrialpes.exmo.ontowrap.Ontology;
 import fr.inrialpes.exmo.ontowrap.BasicOntology;
 
+import fr.inrialpes.exmo.align.impl.BasicRelation;
 import fr.inrialpes.exmo.align.impl.Annotations;
 import fr.inrialpes.exmo.align.impl.Namespace;
 
 import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
-import fr.inrialpes.exmo.align.impl.edoal.EDOALRelation;
 import fr.inrialpes.exmo.align.impl.edoal.Expression;
 import fr.inrialpes.exmo.align.impl.edoal.Id;
 import fr.inrialpes.exmo.align.impl.edoal.Expression;
@@ -357,7 +358,7 @@ public class RDFParser {
 	    // determine the relation, the relation shall be Literal
 	    final String relation = node.getProperty((Property)SyntaxElement.RULE_RELATION.resource).getString();
 	    //Get the relation
-	    final EDOALRelation type = new EDOALRelation( relation );
+	    final Relation type = BasicRelation.createRelation( relation );
 	    if (type == null) {	// I raise an error in this case anyway
 		throw new IllegalArgumentException("Cannot parse the string \""+relation+"\" to a valid relation");
 	    }
diff --git a/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java b/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java
index 8f5c1049..8d4e5191 100644
--- a/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java
+++ b/src/fr/inrialpes/exmo/align/parser/TypeCheckingVisitor.java
@@ -20,7 +20,6 @@
 
 package fr.inrialpes.exmo.align.parser;
 
-
 import java.util.Hashtable;
 import java.util.Properties;
 import java.net.URI;
@@ -70,7 +69,6 @@ import fr.inrialpes.exmo.align.impl.edoal.Comparator;
 
 import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
-import fr.inrialpes.exmo.align.impl.edoal.EDOALRelation;
 
 /**
  * Checks if an EDOALAlignment is well-typed
@@ -132,11 +130,12 @@ public class TypeCheckingVisitor {
 
     public TYPE visit( EDOALCell cell ) throws AlignmentException {
 	this.cell = cell;
-	// JE2011???? Could be useful when not parsing EDOAL
+	// Could be useful when not parsing EDOAL
 	if ( alignment.getLevel().startsWith("2EDOAL") ) {
 	    TYPE t1 = visit( ((Expression)(cell.getObject1())) );
 	    TYPE t2 = visit( ((Expression)(cell.getObject2())) );
 	    // JE2011: This should be dependent on the Relation type (e.g., instanceOf)
+	    // See below
 	    if ( !compatible( t1, t2 ) ) return TYPE.ERROR;
 	}
 	return TYPE.ANY;
@@ -156,9 +155,13 @@ public class TypeCheckingVisitor {
 	return false;
     }
 
-    public TYPE visit( EDOALRelation rel ) {
-	return TYPE.ANY;
-    };
+    // JE2011
+    // This should no be related to the Relation class
+    // and it can implement a compatibility check from the given types!
+    // depending on the 
+    //public TYPE visit( EDOALRelation rel ) {
+    //	return TYPE.ANY;
+    //};
 
     public TYPE visit( final Transformation trsf ) throws AlignmentException {
 	// getType() could allow to do better typing
diff --git a/test/src/EDOALTest.java b/test/src/EDOALTest.java
index 39ae8f87..15057a35 100644
--- a/test/src/EDOALTest.java
+++ b/test/src/EDOALTest.java
@@ -43,16 +43,7 @@ import java.io.OutputStreamWriter;
 import java.io.FileOutputStream;
 
 
-/*
- *
- * JE: 2010
- *
- * THIS SHOULD TEST ALL ERRORS RAISED BY CONSTRUCTORS
- *
- *
- *
- *
- */
+// JE2010: THIS SHOULD TEST ALL ERRORS RAISED BY CONSTRUCTORS
 
 /**
  * These tests corresponds to the tests presented in the examples/omwg directory
@@ -130,7 +121,7 @@ java -cp ../../lib/procalign.jar fr.inrialpes.exmo.align.util.ParserPrinter wine
 	// This tests the round triping
 	assertEquals( wine2.length(), stream.toString().length() );
 	// This provides an absolute value
-	assertEquals( wine2.length(), 4709 );
+	assertEquals( wine2.length(), 4671 );
 	// This does not work because (at least) the order of correspondences is never the same...
 	//assertEquals( wine2, stream.toString() );
     }
-- 
GitLab