From 9c01f3a092e420b9afedd3d5eab400ffa827edda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Sat, 14 Jan 2012 15:47:39 +0000
Subject: [PATCH] - reengineered visitor pattern implementation (Visitable is
 useless/Reflective pattern added)

---
 html/relnotes.html                            |   6 +-
 .../exmo/align/impl/BasicAlignment.java       |   4 +-
 .../exmo/align/impl/edoal/Apply.java          |   6 +-
 .../align/impl/edoal/ClassConstruction.java   |   3 +-
 .../align/impl/edoal/ClassExpression.java     |   3 +-
 .../exmo/align/impl/edoal/ClassId.java        |   3 +-
 .../align/impl/edoal/ClassRestriction.java    |   3 +-
 .../exmo/align/impl/edoal/Datatype.java       |   8 +-
 .../exmo/align/impl/edoal/Expression.java     |   8 +-
 .../align/impl/edoal/InstanceExpression.java  |   6 +-
 .../exmo/align/impl/edoal/PathExpression.java |  10 +-
 .../impl/edoal/PropertyConstruction.java      |   3 +-
 .../align/impl/edoal/PropertyExpression.java  |   8 +-
 .../align/impl/edoal/PropertyRestriction.java |   9 +-
 .../impl/edoal/RelationConstruction.java      |   3 +-
 .../align/impl/edoal/RelationExpression.java  |   8 +-
 .../align/impl/edoal/RelationRestriction.java |   8 +-
 .../exmo/align/impl/edoal/TransfService.java  | 263 +++++++++---------
 .../exmo/align/impl/edoal/Transformation.java |   8 +-
 .../exmo/align/impl/edoal/Value.java          |   6 +-
 .../align/impl/edoal/ValueConstraint.java     |  11 +-
 .../align/impl/edoal/ValueExpression.java     |   8 +-
 .../exmo/align/impl/rel/EquivRelation.java    |   8 +-
 .../renderer/COWLMappingRendererVisitor.java  |  49 +---
 .../renderer/GenericReflectiveVisitor.java    |  92 ++++++
 .../renderer/HTMLMetadataRendererVisitor.java |  24 +-
 .../impl/renderer/HTMLRendererVisitor.java    |  17 +-
 .../renderer/IndentedRendererVisitor.java     |   4 +-
 .../renderer/OWLAxiomsRendererVisitor.java    |  36 +--
 .../impl/renderer/RDFRendererVisitor.java     |  32 +--
 .../renderer/SEKTMappingRendererVisitor.java  |  51 +---
 .../impl/renderer/SKOSRendererVisitor.java    |  50 +---
 .../impl/renderer/SWRLRendererVisitor.java    |  52 +---
 .../renderer/XMLMetadataRendererVisitor.java  |  24 +-
 .../impl/renderer/XSLTRendererVisitor.java    |  43 +--
 .../owl/align/AlignmentVisitor.java           |   8 +-
 test/src/EDOALExportTest.java                 |  33 ++-
 37 files changed, 427 insertions(+), 491 deletions(-)
 create mode 100644 src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java

diff --git a/html/relnotes.html b/html/relnotes.html
index 2b275568..c3d0bdf3 100644
--- a/html/relnotes.html
+++ b/html/relnotes.html
@@ -42,8 +42,7 @@ The development of 4 versions continues.
 <li>Complete tutorial4 with distributed reasoning.</li>
 <li>Genericize evaluators in <tt>GraphEvaluator</tt> and <tt>GenPlot</tt> (eval)</li>
 <li>Implementation of a provenance metadata tag (server/impl)</li>
-<li>Replace <tt>DistanceAlignment</tt> and <tt>Similarity</tt> with a version more in line
-  with <a href="http://ontosim.gforge.inria.fr">OntoSim</a> (impl)</tt>
+<li>Replace <tt>DistanceAlignment</tt> and <tt>Similarity</tt> with a version more in line with <a href="http://ontosim.gforge.inria.fr">OntoSim</a> (impl)</tt>
 <!--li>Implemented transformations in EDOAL (edoal)</li-->
 <li>Improve HTML interface layout and usability (server)</li>
 <li>Implement metadata edition (server)</li>
@@ -71,6 +70,7 @@ with a warning:
 <p><ul compact="1">
 <li>Created new "Command line interface" directory (util/cli)</li>
 <li>Full reengineering of the test generator (gen)</li>
+<li>Improved visitors by implementing a reflective visitor (impl)</li>
 <li>Implemented <tt>extractss</tt> for ** alignments in <tt>DistanceAlignment</tt> (impl)</li>
 <li>Changed default type of <tt>StringDistAlignment</tt> to "?*" for
   preserving the previous behaviour (impl)</li>
@@ -86,6 +86,8 @@ with a warning:
 <li>Added better error checking in <tt>toObjectAlignment</tt> (impl)</li>
 <li>Fixed a bug on <tt>DistanceAlignment</tt> 1:1 extraction when the
   second ontology is larger than the first one (impl)</li>
+<li>Fixed a bug in the EDOAL parser and printer for taking into
+  account the <tt>edoal:type</tt> within <tt>edoal:Literal</tt> (edoal)</li>
 <li>Used more systematically <tt>finally</tt></li>
 </ul></p>
 
diff --git a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
index c954b296..0612c2d4 100644
--- a/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
+++ b/src/fr/inrialpes/exmo/align/impl/BasicAlignment.java
@@ -60,8 +60,8 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
 
 public class BasicAlignment implements Alignment {
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
-	visitor.visit(this);
+    public void accept( AlignmentVisitor visitor ) throws AlignmentException {
+	visitor.visit( this );
     }
 
     protected Ontology<Object> onto1 = null;
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Apply.java b/src/fr/inrialpes/exmo/align/impl/edoal/Apply.java
index 0b49ed15..fe6d6258 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Apply.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Apply.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2010
+ * Copyright (C) INRIA, 2010, 2012
  *
  * 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
@@ -24,9 +24,7 @@ import java.util.List;
 import java.net.URI;
 import java.net.URISyntaxException;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
 
 import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
@@ -69,7 +67,7 @@ public class Apply implements ValueExpression {
 	arguments = args;
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassConstruction.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassConstruction.java
index 50f6048e..0f2e78b8 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassConstruction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassConstruction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006 - was ClassExpr
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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,7 +30,6 @@ import fr.inrialpes.exmo.align.parser.SyntaxElement;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassExpression.java
index 80581715..3f9ae9f0 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassExpression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006 - was ClassExpr
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009, 2012
  *
  * 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
@@ -26,7 +26,6 @@ import java.util.Collection;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassId.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassId.java
index d6b48a9c..0e2d36c8 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassId.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassId.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -26,7 +26,6 @@ import java.util.Collection;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 import java.net.URI;
 import java.net.URISyntaxException;
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassRestriction.java
index c6ce6b45..a71413bd 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ClassRestriction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassRestriction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.6 - 2006
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009, 2012
  *
  * 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
@@ -24,7 +24,6 @@ package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
index f34ca819..e6a90c12 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Datatype.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.2 - 2006
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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,8 +23,6 @@
 package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -35,12 +33,12 @@ import org.semanticweb.owl.align.Visitable;
  * </p>
  */
 
-public class Datatype implements Visitable { //implements Cloneable
+public class Datatype { //implements Cloneable
 
     /** Holds the type */
     private String type;
 
-    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+    public void accept( EDOALVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Expression.java b/src/fr/inrialpes/exmo/align/impl/edoal/Expression.java
index 0cde36ec..495a9434 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Expression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Expression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.7 - 2007
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -27,9 +27,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
 
 import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
@@ -60,7 +58,7 @@ import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
  * @version $Revision: 1.7 $ $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
 
-public abstract class Expression implements Cloneable, Visitable {
+public abstract class Expression implements Cloneable {
 
     // should not be reasonable to have several variables
     // This would cost too much
@@ -68,7 +66,7 @@ public abstract class Expression implements Cloneable, Visitable {
 
     protected Expression() {}
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/InstanceExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/InstanceExpression.java
index 7845c8f0..1d910606 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/InstanceExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/InstanceExpression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.4 - 2006
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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,8 +23,6 @@
 package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -49,7 +47,7 @@ public class InstanceExpression extends Expression implements ValueExpression {
 	super();
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
     /*
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/PathExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/PathExpression.java
index afd4c724..92eb6030 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/PathExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/PathExpression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -25,8 +25,6 @@ package fr.inrialpes.exmo.align.impl.edoal;
 import java.util.Collection;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
@@ -44,14 +42,14 @@ import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
  * @version $Revision: 1.5 $ $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
 
-public abstract class PathExpression extends Expression implements Cloneable, Visitable, ValueExpression {
+public abstract class PathExpression extends Expression implements Cloneable, ValueExpression {
 
     public PathExpression() {
 	super();
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
-	visitor.visit(this);
+    public void accept( EDOALVisitor visitor ) throws AlignmentException {
+	visitor.visit( this );
     }
     public void accept(TypeCheckingVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyConstruction.java b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyConstruction.java
index 0edc0574..22811217 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyConstruction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyConstruction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006 - was PropertyExpr
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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,7 +30,6 @@ import fr.inrialpes.exmo.align.parser.SyntaxElement;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyExpression.java
index b13ff56f..3c5dbc2e 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyExpression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.7 - 2006 -- then AttributeExpr.java
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -26,8 +26,6 @@ import java.util.Collection;
 import java.util.Set;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -42,7 +40,7 @@ import org.semanticweb.owl.align.Visitable;
  * @version $Revision: 1.7 $
  */
 
-public abstract class PropertyExpression extends PathExpression implements Cloneable, Visitable {
+public abstract class PropertyExpression extends PathExpression implements Cloneable {
 
     /**
      * Creates a simple PropertyExpression
@@ -51,7 +49,7 @@ public abstract class PropertyExpression extends PathExpression implements Clone
 	super();
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyRestriction.java
index 0c231f96..a7993365 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/PropertyRestriction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/PropertyRestriction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.6 - 2006 -- then AttributeCondition.java
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009, 2012
  *
  * 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,8 +23,6 @@
 package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -48,13 +46,14 @@ import org.semanticweb.owl.align.Visitable;
  * @author Francois Scharffe
  * @version $Revision: 1.6 $ $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
-public abstract class PropertyRestriction extends PropertyExpression implements Cloneable, Visitable {
+
+public abstract class PropertyRestriction extends PropertyExpression implements Cloneable {
 
     protected PropertyRestriction() {
 	super();
     }
     
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/RelationConstruction.java b/src/fr/inrialpes/exmo/align/impl/edoal/RelationConstruction.java
index b67829f7..8399e245 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/RelationConstruction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/RelationConstruction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006 - was RelationExpr
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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,7 +30,6 @@ import fr.inrialpes.exmo.align.parser.SyntaxElement;
 
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/RelationExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/RelationExpression.java
index 8ecc8b33..abc947ea 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/RelationExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/RelationExpression.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009, 2012
  *
  * 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
@@ -25,8 +25,6 @@ package fr.inrialpes.exmo.align.impl.edoal;
 import java.util.Collection;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 
 /**
@@ -43,13 +41,13 @@ import org.semanticweb.owl.align.Visitable;
  * @version $Revision: 1.5 $ $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
 
-public abstract class RelationExpression extends PathExpression implements Cloneable, Visitable {
+public abstract class RelationExpression extends PathExpression implements Cloneable {
 
     public RelationExpression() {
 	super();
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
     /*
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/RelationRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/RelationRestriction.java
index ca12cdfc..9b1557bb 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/RelationRestriction.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/RelationRestriction.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.5 - 2006
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009, 2012
  *
  * 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,8 +23,6 @@
 package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -48,11 +46,11 @@ import org.semanticweb.owl.align.Visitable;
  * @author Francois Scharffe
  * @version $Revision: 1.5 $ $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
-public abstract class RelationRestriction extends RelationExpression implements Visitable {
+public abstract class RelationRestriction extends RelationExpression {
 
     protected RelationRestriction() {}
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/TransfService.java b/src/fr/inrialpes/exmo/align/impl/edoal/TransfService.java
index 757397d2..239c280d 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/TransfService.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/TransfService.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.2 - 2006
- * Copyright (C) INRIA, 2009
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -29,8 +29,6 @@ import java.util.Set;
 import java.net.URI;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
 /**
  * <p>
@@ -53,55 +51,56 @@ import org.semanticweb.owl.align.Visitable;
  * 
  * @author richi
  * @version $Revision: 1.2 $
- * @date $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
+ * date $Date: 2010-03-07 20:40:05 +0100 (Sun, 07 Mar 2010) $
  */
-public class TransfService implements Cloneable, Visitable {
-	/** resource (uri) to the service */
-	private URI res;
-
-	/** id of the transformation function (only used if it is a service) */
-	private URI id;
-
-	/** paramteters for the transformation */
-	private Set<Id> params;
-
-	/**
-	 * <p>
-	 * Constructs a transf.
-	 * </p>
-	 * 
-	 * @param res
-	 *            uri to the service
-	 * @param params
-	 *            parameters for the transformation
-	 * @throws NullPointerException
-	 *             if the res is {@code null}
-	 */
-	public TransfService(final URI res, final Collection<Id> params) {
-		this(res, null, params);
-	}
-
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+public class TransfService implements Cloneable {
+    /** resource (uri) to the service */
+    private URI res;
+
+    /** id of the transformation function (only used if it is a service) */
+    private URI id;
+
+    /** paramteters for the transformation */
+    private Set<Id> params;
+    
+    /**
+     * <p>
+     * Constructs a transf.
+     * </p>
+     * 
+     * @param res
+     *            uri to the service
+     * @param params
+     *            parameters for the transformation
+     * @throws NullPointerException
+     *             if the res is {@code null}
+     */
+    public TransfService(final URI res, final Collection<Id> params) {
+	this(res, null, params);
+    }
+    /*
+    public void accept( EDOALVisitor visitor ) throws AlignmentException {
 	visitor.visit(this);
     }
-
-	/**
-	 * <p>
-	 * Constructs a service.
-	 * </p>
-	 * 
-	 * @param res
-	 *            uri to the service
-	 * @param id
-	 *            id of the transformation function
-	 * @param params
-	 *            parameters for the transformation
-	 * @throws NullPointerException
-	 *             if the res is {@code null}
-	 */
+    */
+
+    /**
+     * <p>
+     * Constructs a service.
+     * </p>
+     * 
+     * @param res
+     *            uri to the service
+     * @param id
+     *            id of the transformation function
+     * @param params
+     *            parameters for the transformation
+     * @throws NullPointerException
+     *             if the res is {@code null}
+     */
     @SuppressWarnings( "unchecked" )
-    public TransfService(final URI res, final URI id,
-			 final Collection<Id> params) {
+	public TransfService(final URI res, final URI id,
+			     final Collection<Id> params) {
 	if (res == null) {
 	    throw new NullPointerException("The resource must not be null");
 	}
@@ -116,98 +115,98 @@ public class TransfService implements Cloneable, Visitable {
 	}
     }
 
-	/**
-	 * Returns the resource / uri to the transformation.
-	 * 
-	 * @return the uri to the transformator
-	 */
-	public URI getRes() {
-		return res;
-	}
-
-	/**
-	 * Returns the id of the transformation function. This function only returns
-	 * a usable value (another value than {@code null}) if it is a service.
-	 * 
-	 * @return the id of the function
-	 * @see #hasId()
-	 */
-	public URI getId() {
-		return id;
-	}
+    /**
+     * Returns the resource / uri to the transformation.
+     * 
+     * @return the uri to the transformator
+     */
+    public URI getRes() {
+	return res;
+    }
 
-	/**
-	 * Returns an unmodifiable set of parameters needed for the transformation.
-	 * 
-	 * @return the set of parameters
-	 */
-	public Set<Id> getParameters() {
-		return Collections.unmodifiableSet(params);
-	}
+    /**
+     * Returns the id of the transformation function. This function only returns
+     * a usable value (another value than {@code null}) if it is a service.
+     * 
+     * @return the id of the function
+     * @see #hasId()
+     */
+    public URI getId() {
+	return id;
+    }
 
-	/**
-	 * Returns whether there is a id.
-	 * 
-	 * @return {@code true} if there is a usable id, otherwise {@code false}
-	 * @see #getId()
-	 */
-	public boolean hasId() {
-		return id != null;
-	}
+    /**
+     * Returns an unmodifiable set of parameters needed for the transformation.
+     * 
+     * @return the set of parameters
+     */
+    public Set<Id> getParameters() {
+	return Collections.unmodifiableSet(params);
+    }
 
-	/**
-	 * <p>
-	 * Returns a short string description of this object. <b>The format of the
-	 * returned string is undocumented and subject to change.</b>
-	 * </p>
-	 * <p>
-	 * An example string could be:
-	 * {@code transf: http://my/super/transf params: [dollar]}
-	 * </p>
-	 */
-	public String toString() {
-		return "transf: " + res + ((id != null) ? " id: " + id : "")
-				+ " params: " + params;
-	}
+    /**
+     * Returns whether there is a id.
+     * 
+     * @return {@code true} if there is a usable id, otherwise {@code false}
+     * @see #getId()
+     */
+    public boolean hasId() {
+	return id != null;
+    }
 
-	public boolean equals(final Object o) {
-		if (o == this) {
-			return true;
-		}
-		if (!(o instanceof TransfService)) {
-			return false;
-		}
-		TransfService t = (TransfService) o;
-		return res.equals(t.res)
-				&& ((id == t.id) || ((id != null) && id.equals(t.id)))
-				&& (params.size() == t.params.size())
-				&& params.containsAll(t.params);
+    /**
+     * <p>
+     * Returns a short string description of this object. <b>The format of the
+     * returned string is undocumented and subject to change.</b>
+     * </p>
+     * <p>
+     * An example string could be:
+     * {@code transf: http://my/super/transf params: [dollar]}
+     * </p>
+     */
+    public String toString() {
+	return "transf: " + res + ((id != null) ? " id: " + id : "")
+	    + " params: " + params;
+    }
+    
+    public boolean equals(final Object o) {
+	if (o == this) {
+	    return true;
 	}
-
-	public int hashCode() {
-		int hash = 17;
-		hash = hash * 37 + res.hashCode();
-		hash = hash * 37 + ((id != null) ? id.hashCode() : 0);
-		hash = hash * 37 + params.hashCode();
-		return hash;
+	if (!(o instanceof TransfService)) {
+	    return false;
 	}
+	TransfService t = (TransfService) o;
+	return res.equals(t.res)
+	    && ((id == t.id) || ((id != null) && id.equals(t.id)))
+	    && (params.size() == t.params.size())
+	    && params.containsAll(t.params);
+    }
+    
+    public int hashCode() {
+	int hash = 17;
+	hash = hash * 37 + res.hashCode();
+	hash = hash * 37 + ((id != null) ? id.hashCode() : 0);
+	hash = hash * 37 + params.hashCode();
+	return hash;
+    }
 
     @SuppressWarnings( "unchecked" )
 	public Object clone() {
-		try {
-			TransfService clone = (TransfService) super.clone();
-			// JE: noclone on URI
-			//clone.res = (URI) res.clone();
-			clone.res = res;
-			clone.params = (params.isEmpty()) ? Collections.EMPTY_SET //[W:unchecked]
-					: new HashSet<Id>(params);
-			// JE: noclone on URI
-			//clone.id = (id == null) ? null : (URI) id.clone();
-			clone.id = (id == null) ? null : id;
-			return clone;
-		} catch (CloneNotSupportedException e) {
-			assert true : "Object is always cloneable";
-		}
-		return null;
+	try {
+	    TransfService clone = (TransfService) super.clone();
+	    // JE: noclone on URI
+	    //clone.res = (URI) res.clone();
+	    clone.res = res;
+	    clone.params = (params.isEmpty()) ? Collections.EMPTY_SET //[W:unchecked]
+		: new HashSet<Id>(params);
+	    // JE: noclone on URI
+	    //clone.id = (id == null) ? null : (URI) id.clone();
+	    clone.id = (id == null) ? null : id;
+	    return clone;
+	} catch (CloneNotSupportedException e) {
+	    assert true : "Object is always cloneable";
 	}
+	return null;
+    }
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Transformation.java b/src/fr/inrialpes/exmo/align/impl/edoal/Transformation.java
index 495de9f1..2b3348a1 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Transformation.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Transformation.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2010
+ * Copyright (C) INRIA, 2010, 2012
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -21,9 +21,7 @@
 
 package fr.inrialpes.exmo.align.impl.edoal;
 
-import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.Visitable;
 
 import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
@@ -35,14 +33,14 @@ import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
  * @version $Id$ 
  */
 
-public class Transformation implements Visitable {
+public class Transformation {
 
     // JE: bad values...
     private String type; // "oo", "o-" or "-o"
     private ValueExpression expr1;
     private ValueExpression expr2;
 
-    public void accept( AlignmentVisitor visitor) throws AlignmentException {
+    public void accept( EDOALVisitor visitor) throws AlignmentException {
         visitor.visit( this );
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Value.java b/src/fr/inrialpes/exmo/align/impl/edoal/Value.java
index bb7305f8..7147a844 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/Value.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/Value.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.2 - 2006
- * Copyright (C) INRIA, 2009-2010
+ * Copyright (C) INRIA, 2009-2010, 2012
  *
  * 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
@@ -24,9 +24,7 @@ package fr.inrialpes.exmo.align.impl.edoal;
 
 import java.net.URI;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
 
 import fr.inrialpes.exmo.align.parser.TypeCheckingVisitor;
 
@@ -77,7 +75,7 @@ public class Value implements ValueExpression { //implements Cloneable, Visitabl
 	this.type = type;
     }
 
-    public void accept(AlignmentVisitor visitor) throws AlignmentException {
+    public void accept(EDOALVisitor visitor) throws AlignmentException {
 	visitor.visit(this);
     }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ValueConstraint.java b/src/fr/inrialpes/exmo/align/impl/edoal/ValueConstraint.java
index 932df32d..a00a760a 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ValueConstraint.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ValueConstraint.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2010
+ * Copyright (C) INRIA, 2010, 2012
  *
  * 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
@@ -21,10 +21,9 @@
 package fr.inrialpes.exmo.align.impl.edoal;
 
 import org.semanticweb.owl.align.AlignmentException;
-import org.semanticweb.owl.align.AlignmentVisitor;
-import org.semanticweb.owl.align.Visitable;
 
-public class ValueConstraint implements Cloneable, Visitable {
+// JE: 2012 this class seems not used anywhere
+public class ValueConstraint implements Cloneable {
 
     // JE: 2010 this must be replaced by path-or-value
     Value value = null;
@@ -40,8 +39,10 @@ public class ValueConstraint implements Cloneable, Visitable {
 	comparator = comp;
     }    
 
-    public void accept( AlignmentVisitor visitor ) throws AlignmentException {
+    /*
+      public void accept( EDOALVisitor visitor ) throws AlignmentException {
 	visitor.visit(this);
     }
+    */
 
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ValueExpression.java b/src/fr/inrialpes/exmo/align/impl/edoal/ValueExpression.java
index d976ea65..12b3a93e 100644
--- a/src/fr/inrialpes/exmo/align/impl/edoal/ValueExpression.java
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ValueExpression.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2010
+ * Copyright (C) INRIA, 2010, 2012
  *
  * 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,13 +20,15 @@
 
 package fr.inrialpes.exmo.align.impl.edoal;
 
-import org.semanticweb.owl.align.Visitable;
+import org.semanticweb.owl.align.AlignmentException;
 
 /** 
  * Interface implemented by expressions which can be used as values:
  * Value, Path, Instance
  */
 
-public interface ValueExpression extends Visitable {
+public interface ValueExpression {
+
+    public void accept( EDOALVisitor v ) throws AlignmentException;
 }
 
diff --git a/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
index 6fd79a97..81316312 100644
--- a/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
+++ b/src/fr/inrialpes/exmo/align/impl/rel/EquivRelation.java
@@ -33,10 +33,10 @@ import fr.inrialpes.exmo.align.impl.BasicRelation;
  * @version $Id$
  */
 
-public class EquivRelation extends BasicRelation
-{
-    public void accept( AlignmentVisitor visitor) throws AlignmentException {
-	visitor.visit( this );
+public class EquivRelation extends BasicRelation {
+
+    public void accept( AlignmentVisitor visitor ) throws AlignmentException {
+	visitor.visit( (EquivRelation)this );
     }
 
     static final String prettyLabel = "=";
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java
index 3c52364e..7464504c 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/COWLMappingRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2004, 2007-2010
+ * Copyright (C) INRIA, 2003-2004, 2007-2010, 2012
  *
  * 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
@@ -24,10 +24,7 @@ import java.net.URI;
 import java.util.Enumeration;
 import java.util.Properties;
 import java.io.PrintWriter;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -46,9 +43,8 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
+public class COWLMappingRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
 
-public class COWLMappingRendererVisitor implements AlignmentVisitor
-{
     PrintWriter writer = null;
     Alignment alignment = null;
     LoadedOntology onto1 = null;
@@ -61,13 +57,9 @@ public class COWLMappingRendererVisitor implements AlignmentVisitor
 
     public void init( Properties p ) {}
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	if ( !(align instanceof ObjectAlignment) )
 	    throw new AlignmentException("COWLMappingRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement()");
 	alignment = align;
@@ -100,6 +92,8 @@ public class COWLMappingRendererVisitor implements AlignmentVisitor
 	writer.print("</rdf:RDF>\n");
     }
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	writer.print("    <cowl:bridgeRule>\n");
 	cell.getRelation().accept( this );
@@ -146,34 +140,11 @@ public class COWLMappingRendererVisitor implements AlignmentVisitor
 	    writer.print("       </cowl:target>\n");
 	    writer.print("     </cowl:INCOMPATIBLE>\n");
     }
+
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	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});
-	} catch (IllegalAccessException e) {
-	    e.printStackTrace();
-	} catch (ClassNotFoundException e) {
-	    e.printStackTrace();
-	} catch (NoSuchMethodException e) {
-	    e.printStackTrace();
-	} catch (InvocationTargetException e) { 
-	    e.printStackTrace();
-	}
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
+	throw new AlignmentException( "Cannot render generic Relation" );
     }
 
     public void printObject( Object ob, LoadedOntology onto ) throws AlignmentException {
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java
new file mode 100644
index 00000000..5ad52ad9
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/GenericReflectiveVisitor.java
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) INRIA, 2012
+ *
+ * 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.renderer; 
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class offers the tools for implementing Reflective visitors,
+ * i.e., visitors in which the visit method will depend on the actual
+ * class of the visited object.
+ *
+ * This is useful for the AlignmentVisitors because: Alignment, Cell
+ * and Relation may be extended.
+ */
+public class GenericReflectiveVisitor {
+
+    /**
+     * Finds the visit(X) method corresponding to the object class (subclass of a root class)
+     * Look-up for X in the superclass of c (up to root, otherwise it loops)
+     * If not found, look it up in the implemented interface
+     * (there may be such a method for interfaces)
+     */
+    protected Method getMethod( Class c, Class root ) {
+	Class  newc = c;
+	Method m    = null;
+	while ( m == null  &&  newc != root && newc != null ) { // null father of Object.class?
+	    String method = newc.getName();
+	    method = "visit";// + method.substring( method.lastIndexOf('.') + 1 );
+	    try {
+		m = getClass().getMethod( method, new Class[] { newc } );
+	    } catch ( NoSuchMethodException ex ) {
+		newc = newc.getSuperclass();
+	    }
+	}
+	if ( m == null ) {//newc == Object.class ) {
+	    // System.out.println( "Searching for interfaces" );
+	    Class[] interfaces = c.getInterfaces();
+	    for ( int i=0; i < interfaces.length; i++ ) {
+		if ( interfaces[i] != root ) {
+		    String method = interfaces[i].getName();
+		    //method = "visit" + method.substring( method.lastIndexOf('.') + 1 );
+		    try {
+			m = getClass().getMethod( method, new Class[] { interfaces[i] } );
+		    } catch ( NoSuchMethodException ex ) { }
+		}
+	    }
+	}
+	/*
+	if ( m == null )
+	    try {
+		//m = getClass().getMethod( "visitObject", new Class[] { Object.class } );
+		m = getClass().getMethod( "visit", new Class[] { Object.class } );
+	    } catch (Exception ex) { }
+	*/
+	return m;
+    }
+
+    public boolean subsumedInvocableMethod( Object visitor, Object o, Class cl ) {
+	Method method = getMethod( o.getClass(), cl );
+	if ( method != null ) {
+	    try {
+		method.invoke( visitor, new Object[] {o} );
+		return true;
+	    } catch ( IllegalAccessException iaex ) {
+		iaex.printStackTrace();
+	    } catch ( InvocationTargetException itex ) { 
+		itex.printStackTrace();
+	    }
+	}
+	return false;
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLMetadataRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLMetadataRendererVisitor.java
index f35aae4c..b450c9d8 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLMetadataRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLMetadataRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2006-2010
+ * Copyright (C) INRIA, 2006-2010, 2012
  *
  * 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
@@ -26,8 +26,9 @@ import java.util.Properties;
 import java.io.PrintWriter;
 import java.net.URI;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
 
@@ -47,8 +48,7 @@ import fr.inrialpes.exmo.ontowrap.LoadedOntology;
  * @version $Id$ 
  */
 
-public class HTMLMetadataRendererVisitor implements AlignmentVisitor
-{
+public class HTMLMetadataRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     
     PrintWriter writer = null;
     Alignment alignment = null;
@@ -64,11 +64,9 @@ public class HTMLMetadataRendererVisitor implements AlignmentVisitor
 	     && !p.getProperty( "embedded" ).equals("") ) embedded = true;
     };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	alignment = align;
 	nslist = new Hashtable<String,String>();
 	nslist.put(Namespace.ALIGNMENT.uri,"align");
@@ -130,4 +128,14 @@ public class HTMLMetadataRendererVisitor implements AlignmentVisitor
 	writer.print("</body>\n</html>\n");
     }
 
+    public void visit( Cell c ) {
+	if ( subsumedInvocableMethod( this, c, Cell.class ) ) return;
+	// default behaviour
+    };
+
+    public void visit( Relation r ) {
+	if ( subsumedInvocableMethod( this, r, Relation.class ) ) return;
+	// default behaviour
+    };
+    
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
index 367d58c7..67c19f5c 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/HTMLRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2006-2010
+ * Copyright (C) INRIA, 2006-2010, 2012
  *
  * 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
@@ -26,7 +26,6 @@ import java.util.Hashtable;
 import java.io.PrintWriter;
 import java.net.URI;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -50,7 +49,7 @@ import fr.inrialpes.exmo.ontowrap.LoadedOntology;
  * @version $Id$ 
  */
 
-public class HTMLRendererVisitor implements AlignmentVisitor {
+public class HTMLRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     
     PrintWriter writer = null;
     Alignment alignment = null;
@@ -68,13 +67,9 @@ public class HTMLRendererVisitor implements AlignmentVisitor {
 	     && !p.getProperty( "embedded" ).equals("") ) embedded = true;
     };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	alignment = align;
 	nslist = new Hashtable<String,String>();
 	nslist.put(Namespace.ALIGNMENT.uri,"align");
@@ -150,6 +145,8 @@ public class HTMLRendererVisitor implements AlignmentVisitor {
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	URI u1, u2;
 	// JE: I think that now these two clauses should be unified (3.4)
@@ -179,6 +176,8 @@ public class HTMLRendererVisitor implements AlignmentVisitor {
 	writer.println("</tr>");
     }
     public void visit( Relation rel ) {
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
 	rel.write( writer );
     };
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/IndentedRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/IndentedRendererVisitor.java
index 17acb5d3..05d1128f 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/IndentedRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/IndentedRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2010
+ * Copyright (C) INRIA, 2010, 2012
  *
  * 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
@@ -35,7 +35,7 @@ import java.net.URI;
  * @version $Id$
  */
 
-public class IndentedRendererVisitor {
+public class IndentedRendererVisitor extends GenericReflectiveVisitor {
 
     PrintWriter writer = null;
 
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/OWLAxiomsRendererVisitor.java
index 0b0f0d1c..e197bea7 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-2011
+ * Copyright (C) INRIA, 2003-2004, 2007-2012
  *
  * 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
@@ -24,10 +24,7 @@ import java.util.Enumeration;
 import java.util.Properties;
 import java.io.PrintWriter;
 import java.net.URI;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -82,6 +79,7 @@ import fr.inrialpes.exmo.align.impl.edoal.Datatype;
 import fr.inrialpes.exmo.align.impl.edoal.Comparator;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALCell;
 import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
+import fr.inrialpes.exmo.align.impl.edoal.EDOALVisitor;
 
 /**
  * Renders an alignment as a new ontology merging these.
@@ -90,7 +88,7 @@ import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
  * @version $Id$ 
  */
 
-public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor {
+public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements AlignmentVisitor, EDOALVisitor {
     boolean heterogeneous = false;
     boolean edoal = false;
     Alignment alignment = null;
@@ -109,17 +107,9 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 	if ( p.getProperty("heterogeneous") != null ) heterogeneous = true;
     };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Expression ) visit( (Expression)o );
-	else if ( o instanceof ValueExpression ) visit( (ValueExpression)o );
-	else if ( o instanceof Transformation ) visit( (Transformation)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-	else if ( o instanceof Alignment ) visit( (Alignment)o );
-	else throw new AlignmentException( "Cannot dispatch Expression "+o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	alignment = align;
 	if ( align instanceof ObjectAlignment ){
 	    onto1 = (LoadedOntology)((ObjectAlignment)alignment).getOntologyObject1();
@@ -165,6 +155,8 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	if ( cell.getId() != null ) writer.print(NL+NL+"<!-- "+cell.getId()+" -->"+NL);
 	if ( cell instanceof EDOALCell ) {
 	    visit( (EDOALCell)cell );
@@ -217,6 +209,8 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
     // 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 {
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
 	Object ob2 = cell.getObject2();
 	if ( edoal ) {
 	    String owlrel = getRelationName( rel, ob2 );
@@ -455,20 +449,15 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 
     public void visit( Expression o ) throws AlignmentException {
 	if ( o instanceof ClassExpression ) visit( (ClassExpression)o );
-	else if ( o instanceof RelationRestriction ) visit( (RelationRestriction)o );
-	else if ( o instanceof PropertyRestriction ) visit( (PropertyRestriction)o );
-	else if ( o instanceof ClassRestriction ) visit( (ClassRestriction)o );
 	else if ( o instanceof PathExpression ) visit( (PathExpression)o );
-	else if ( o instanceof PropertyExpression ) visit( (PropertyExpression)o );
 	else if ( o instanceof InstanceExpression ) visit( (InstanceExpression)o );
-	else if ( o instanceof RelationExpression ) visit( (RelationExpression)o );
-	else throw new AlignmentException( "Cannot dispatch Expression "+o );
+	else throw new AlignmentException( "Cannot dispatch generic Expression "+o );
     }
 
     public void visit( final PathExpression p ) throws AlignmentException {
 	if ( p instanceof RelationExpression ) visit( (RelationExpression)p );
 	else if ( p instanceof PropertyExpression ) visit( (PropertyExpression)p );
-	else throw new AlignmentException( "Cannot dispatch PathExpression "+p );
+	else throw new AlignmentException( "Cannot dispatch generic PathExpression "+p );
     }
 
     public void visit( final ClassExpression e ) throws AlignmentException {
@@ -940,7 +929,7 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
 	else if ( e instanceof PathExpression )  visit( (PathExpression)e );
 	else if ( e instanceof Apply )  visit( (Apply)e );
 	else if ( e instanceof Value )  visit( (Value)e );
-	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
+	else throw new AlignmentException( "Cannot dispatch generic ValueExpression "+e );
     }
 
     // Unused: see ClassValueRestriction above
@@ -968,6 +957,5 @@ public class OWLAxiomsRendererVisitor extends IndentedRendererVisitor implements
     public void visit( final Datatype e ) {
 	indentedOutput("<owl:Datatype><owl:onDataType rdf:resource=\""+e.plainText()+"\"/></owl:Datatype>");
     }
-	
 
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
index d5e70bf1..6bc42f65 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
@@ -28,7 +28,6 @@ import java.util.Properties;
 import java.io.PrintWriter;
 import java.net.URI;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -115,32 +114,9 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align
 	    NL = p.getProperty( "newline" );
     }
 
-    /*
-     * JE: These major dispatches are a pain.
-     * I should learn a bit more Java about that 
-     * (and at least inverse the order
-     */
-    // JE: Beware: THERE MAY BE EFFECTIVE STUFF MISSING THERE (CAN WE DO THE DISPATCH LOWER -- YES)
-    // It is a real mess already...
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof ClassExpression ) visit( (ClassExpression)o );
-	else if ( o instanceof RelationRestriction ) visit( (RelationRestriction)o );
-	else if ( o instanceof PropertyRestriction ) visit( (PropertyRestriction)o );
-	else if ( o instanceof ClassRestriction ) visit( (ClassRestriction)o );
-	else if ( o instanceof PathExpression ) visit( (PathExpression)o );
-	else if ( o instanceof PropertyExpression ) visit( (PropertyExpression)o );
-	else if ( o instanceof InstanceExpression ) visit( (InstanceExpression)o );
-	else if ( o instanceof RelationExpression ) visit( (RelationExpression)o );
-	else if ( o instanceof Expression ) visit( (Expression)o );
-	else if ( o instanceof ValueExpression ) visit( (ValueExpression)o );
-	else if ( o instanceof Transformation ) visit( (Transformation)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-	else if ( o instanceof Alignment ) visit( (Alignment)o );
-	else throw new AlignmentException( "Cannot dispatch expression "+o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	String extensionString = "";
 	alignment = align;
 	nslist = new Hashtable<String,String>();
@@ -254,6 +230,8 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	URI u1 = cell.getObject1AsURI(alignment);
 	URI u2 = cell.getObject2AsURI(alignment);
@@ -329,6 +307,8 @@ public class RDFRendererVisitor extends IndentedRendererVisitor implements Align
     }
 
     public void visit( Relation rel ) {
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
 	rel.write( writer );
     };
 
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java
index f36601ea..1608ee45 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/SEKTMappingRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2005, 2007-2010
+ * Copyright (C) INRIA, 2003-2005, 2007-2010, 2012
  *
  * 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
@@ -25,10 +25,7 @@ import java.util.Properties;
 import java.util.Random;
 import java.io.PrintWriter;
 import java.net.URI;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -48,7 +45,7 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
-public class SEKTMappingRendererVisitor implements AlignmentVisitor {
+public class SEKTMappingRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     PrintWriter writer = null;
     Alignment alignment = null;
     LoadedOntology onto1 = null;
@@ -64,13 +61,9 @@ public class SEKTMappingRendererVisitor implements AlignmentVisitor {
 
     public void init( Properties p ) {};
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	if ( !(align instanceof ObjectAlignment) )
 	    throw new AlignmentException("SEKTMappingRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement()");
 	alignment = align;
@@ -86,6 +79,8 @@ public class SEKTMappingRendererVisitor implements AlignmentVisitor {
 	writer.print(")\n");
     }
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	String id = String.format( "s%06d", generator.nextInt(100000) );
 	Object ob1 = cell.getObject1();
@@ -135,33 +130,9 @@ public class SEKTMappingRendererVisitor implements AlignmentVisitor {
 	writer.print("    unidirectional\n");
     }
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	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});
-	} catch (IllegalAccessException e) {
-	    e.printStackTrace();
-	} catch (ClassNotFoundException e) {
-	    e.printStackTrace();
-	} catch (NoSuchMethodException e) {
-	    e.printStackTrace();
-	} catch (InvocationTargetException e) { 
-	    e.printStackTrace();
-	}
-	//	} catch (Exception e) { throw new AlignmentException("Dispatching problem ", e); };
-    };
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
+	throw new AlignmentException( "Cannot render generic Relation" );
+    }
+
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SKOSRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SKOSRendererVisitor.java
index 85b11cc1..3d0eb51d 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/SKOSRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/SKOSRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2004, 2006-2010
+ * Copyright (C) INRIA, 2003-2004, 2006-2010, 2012
  * Copyright (C) Quentin Reul, 2008
  *
  * This program is free software; you can redistribute it and/or modify
@@ -25,10 +25,7 @@ import java.util.Enumeration;
 import java.util.Properties;
 import java.io.PrintWriter;
 import java.net.URI;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -48,7 +45,7 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
-public class SKOSRendererVisitor implements AlignmentVisitor {
+public class SKOSRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     PrintWriter writer = null;
     Alignment alignment = null;
     LoadedOntology onto1 = null;
@@ -68,14 +65,9 @@ public class SKOSRendererVisitor implements AlignmentVisitor {
 	     && !p.getProperty( "pre2008" ).equals("") ) pre2008 = true;
     };
 
-    // This must be considered
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	alignment = align;
 	if ( align instanceof ObjectAlignment ) {
 	    onto1 = (LoadedOntology)((ObjectAlignment)align).getOntologyObject1();
@@ -117,6 +109,8 @@ public class SKOSRendererVisitor implements AlignmentVisitor {
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	if ( onto1 != null ) {
 	    try {
@@ -155,32 +149,8 @@ public class SKOSRendererVisitor implements AlignmentVisitor {
 	throw new AlignmentException("Cannot translate in SKOS"+rel);
     }
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	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});
-	} catch (IllegalAccessException e) {
-	    e.printStackTrace();
-	} catch (ClassNotFoundException e) {
-	    e.printStackTrace();
-	} catch (NoSuchMethodException e) {
-	    e.printStackTrace();
-	} catch (InvocationTargetException e) { 
-	    e.printStackTrace();
-	}
-    };
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
+	throw new AlignmentException( "Cannot render generic Relation" );
+    }
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java
index 72198d88..23a5bfa2 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/SWRLRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2004, 2007-2010
+ * Copyright (C) INRIA, 2003-2004, 2007-2010, 2012
  *
  * 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
@@ -25,10 +25,6 @@ import java.util.Properties;
 import java.io.PrintWriter;
 import java.net.URI;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -49,7 +45,7 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
-public class SWRLRendererVisitor implements AlignmentVisitor {
+public class SWRLRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     PrintWriter writer = null;
     Alignment alignment = null;
     LoadedOntology onto1 = null;
@@ -66,13 +62,9 @@ public class SWRLRendererVisitor implements AlignmentVisitor {
 	     && !p.getProperty( "embedded" ).equals("") ) embedded = true;
    };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	if ( !( align instanceof ObjectAlignment) )
 	    throw new AlignmentException("SWRLRenderer: cannot render simple alignment. Turn them into ObjectAlignment, by toObjectAlignement()");
 	alignment = align;
@@ -98,6 +90,8 @@ public class SWRLRendererVisitor implements AlignmentVisitor {
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	cell.getRelation().accept( this );
     }
@@ -157,34 +151,10 @@ public class SWRLRendererVisitor implements AlignmentVisitor {
     public void visit( SubsumeRelation rel ){};
     public void visit( SubsumedRelation rel ){};
     public void visit( IncompatRelation rel ){};
-
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	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});
-	} catch (IllegalAccessException e) {
-	    e.printStackTrace();
-	} catch (ClassNotFoundException e) {
-	    e.printStackTrace();
-	} catch (NoSuchMethodException e) {
-	    e.printStackTrace();
-	} catch (InvocationTargetException e) { 
-	    e.printStackTrace();
-	}
-    };
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
+	throw new AlignmentException( "Cannot render generic Relation" );
+    }
+
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/XMLMetadataRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/XMLMetadataRendererVisitor.java
index f74d6cc0..f69c70c1 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/XMLMetadataRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/XMLMetadataRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2007, 2009-2010
+ * Copyright (C) INRIA, 2007, 2009-2010, 2012
  *
  * 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
@@ -25,8 +25,10 @@ import java.util.Hashtable;
 import java.util.Properties;
 import java.io.PrintWriter;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.Alignment;
+import org.semanticweb.owl.align.Cell;
+import org.semanticweb.owl.align.Relation;
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.AlignmentVisitor;
 
@@ -41,7 +43,7 @@ import fr.inrialpes.exmo.align.impl.BasicAlignment;
  * @version $Id$ 
  */
 
-public class XMLMetadataRendererVisitor implements AlignmentVisitor {
+public class XMLMetadataRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     
     PrintWriter writer = null;
     Alignment alignment = null;
@@ -58,11 +60,9 @@ public class XMLMetadataRendererVisitor implements AlignmentVisitor {
 	     && !p.getProperty( "embedded" ).equals("") ) embedded = true;
     };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	String extensionString = "";
 	alignment = align;
 	nslist = new Hashtable<String,String>();
@@ -149,4 +149,14 @@ public class XMLMetadataRendererVisitor implements AlignmentVisitor {
 	writer.print("</rdf:RDF>\n");
     }
 
+    public void visit( Cell c ) {
+	if ( subsumedInvocableMethod( this, c, Cell.class ) ) return;
+	// default behaviour
+    };
+
+    public void visit( Relation r ) {
+	if ( subsumedInvocableMethod( this, r, Relation.class ) ) return;
+	// default behaviour
+    };
+    
 }
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java
index f4aa0ea0..ab197073 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/XSLTRendererVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2003-2004, 2006-2010
+ * Copyright (C) INRIA, 2003-2004, 2006-2010, 2012
  *
  * 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
@@ -24,11 +24,8 @@ import java.util.Hashtable;
 import java.util.Enumeration;
 import java.util.Properties;
 import java.io.PrintWriter;
-
-import java.lang.reflect.Method;
 import java.net.URI;
 
-import org.semanticweb.owl.align.Visitable;
 import org.semanticweb.owl.align.Alignment;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
@@ -49,7 +46,7 @@ import fr.inrialpes.exmo.ontowrap.OntowrapException;
  * @version $Id$ 
  */
 
-public class XSLTRendererVisitor implements AlignmentVisitor {
+public class XSLTRendererVisitor extends GenericReflectiveVisitor implements AlignmentVisitor {
     PrintWriter writer = null;
     Alignment alignment = null;
     Cell cell = null;
@@ -73,13 +70,9 @@ public class XSLTRendererVisitor implements AlignmentVisitor {
 	     && !p.getProperty( "embedded" ).equals("") ) embedded = true;
     };
 
-    public void visit( Visitable o ) throws AlignmentException {
-	if ( o instanceof Alignment ) visit( (Alignment)o );
-	else if ( o instanceof Cell ) visit( (Cell)o );
-	else if ( o instanceof Relation ) visit( (Relation)o );
-    }
-
     public void visit( Alignment align ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, align, Alignment.class ) ) return;
+	// default behaviour
 	alignment = align;
 	if ( align instanceof ObjectAlignment ) {
 	    onto1 = (LoadedOntology)((ObjectAlignment)align).getOntologyObject1();
@@ -126,6 +119,8 @@ public class XSLTRendererVisitor implements AlignmentVisitor {
     }
 
     public void visit( Cell cell ) throws AlignmentException {
+	if ( subsumedInvocableMethod( this, cell, Cell.class ) ) return;
+	// default behaviour
 	this.cell = cell;
 	cell.getRelation().accept( this );
     }
@@ -184,26 +179,10 @@ public class XSLTRendererVisitor implements AlignmentVisitor {
     public void visit( SubsumeRelation rel ){};
     public void visit( SubsumedRelation rel ){};
     public void visit( IncompatRelation rel ){};
-
     public void visit( Relation rel ) throws AlignmentException {
-	// JE: I do not understand why I need this,
-	// but this seems to be the case...
-	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});
-	} catch (Exception e) { throw new AlignmentException("Dispatching problem ", e); };
-    };
+	if ( subsumedInvocableMethod( this, rel, Relation.class ) ) return;
+	// default behaviour
+	throw new AlignmentException( "Cannot render generic Relation" );
+    }
+
 }
diff --git a/src/org/semanticweb/owl/align/AlignmentVisitor.java b/src/org/semanticweb/owl/align/AlignmentVisitor.java
index 7ed680aa..7d3f227c 100644
--- a/src/org/semanticweb/owl/align/AlignmentVisitor.java
+++ b/src/org/semanticweb/owl/align/AlignmentVisitor.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2004, 2008-2009
+ * Copyright (C) INRIA, 2004, 2008-2009, 2012
  *
  * 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
@@ -31,5 +31,7 @@ import java.util.Properties;
 
 public interface AlignmentVisitor {
     public void init( Properties p );
-    public void visit( Visitable o ) throws AlignmentException;
- }
+    public void visit( Alignment o ) throws AlignmentException;
+    public void visit( Cell o ) throws AlignmentException;
+    public void visit( Relation o ) throws AlignmentException;
+}
diff --git a/test/src/EDOALExportTest.java b/test/src/EDOALExportTest.java
index 067b78bd..fffbba77 100644
--- a/test/src/EDOALExportTest.java
+++ b/test/src/EDOALExportTest.java
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
  * Sourceforge version 1.3 -- 2007
- * Copyright (C) INRIA, 2009-2011
+ * Copyright (C) INRIA, 2009-2012
  *
  * 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,7 +30,6 @@ import org.testng.annotations.Test;
 import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.Alignment;
-import org.semanticweb.owl.align.Visitable;
 
 import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor;
 import fr.inrialpes.exmo.align.impl.renderer.OWLAxiomsRendererVisitor;
@@ -98,7 +97,7 @@ public class EDOALExportTest {
     public void setUp() throws Exception {
     }
 
-    private String render( Visitable v ) throws Exception {
+    private String render( Expression v ) throws Exception {
 	// JE2009: This can only be improved if we can change the stream
 	stream = new ByteArrayOutputStream(); 
 	writer = new PrintWriter ( new BufferedWriter(
@@ -447,8 +446,18 @@ public class EDOALExportTest {
 	final EDOALAlignment doc = new EDOALAlignment();
 	doc.setExtension( Namespace.ALIGNMENT.uri, Annotations.ID, "http://asdf" );
 	doc.init( o1, o2 );
-	
-	assertEquals( render( doc ), 
+
+	stream = new ByteArrayOutputStream(); 
+	writer = new PrintWriter ( new BufferedWriter(
+				                 new OutputStreamWriter( stream, "UTF-8" )), true);
+	renderer = new RDFRendererVisitor( writer );
+	renderer.setIndentString("");	// Indent should be empty
+	renderer.setNewLineString("");
+	doc.accept( renderer );//doc.render( renderer );
+	writer.flush();
+	writer.close();
+	stream.close();
+	assertEquals( stream.toString(), 
 "<?xml version='1.0' encoding='utf-8' standalone='no'?><rdf:RDF xmlns='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#'"+
          " xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'"+
          " xmlns:xsd='http://www.w3.org/2001/XMLSchema#'"+
@@ -464,7 +473,17 @@ public class EDOALExportTest {
 	    + "</Ontology>" + "</onto2>"
 		      + "</Alignment>" +"</rdf:RDF>" );
 	doc.setType( "1*" );
-	assertEquals( render( doc ), 
+	stream = new ByteArrayOutputStream(); 
+	writer = new PrintWriter ( new BufferedWriter(
+				                 new OutputStreamWriter( stream, "UTF-8" )), true);
+	renderer = new RDFRendererVisitor( writer );
+	renderer.setIndentString("");	// Indent should be empty
+	renderer.setNewLineString("");
+	doc.accept( renderer );//doc.render( renderer );
+	writer.flush();
+	writer.close();
+	stream.close();
+	assertEquals( stream.toString(), 
 "<?xml version='1.0' encoding='utf-8' standalone='no'?><rdf:RDF xmlns='http://knowledgeweb.semanticweb.org/heterogeneity/alignment#'"+
          " xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'"+
          " xmlns:xsd='http://www.w3.org/2001/XMLSchema#'"+
@@ -478,7 +497,7 @@ public class EDOALExportTest {
 	    + "<Ontology rdf:about=\"http://target\"><location>http://target</location>"
 	    + "<formalism><Formalism align:name=\"wsml\" align:uri=\"http://wsml\"/></formalism>"
 	    + "</Ontology>" + "</onto2>"
-		      + "</Alignment>" +"</rdf:RDF>" );
+	    + "</Alignment>" +"</rdf:RDF>" );
     }
 
 }
-- 
GitLab