From 07a3e361dc1b0b0f33399916979b5cc482ddf635 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Thu, 18 Mar 2010 20:52:30 +0000
Subject: [PATCH] - improved EDOAL parser/printer cohesion

---
 examples/omwg/total.xml                       | 299 ++++++++++++++++++
 .../impl/edoal/ClassDomainRestriction.java    |  54 ++++
 .../impl/renderer/RDFRendererVisitor.java     | 250 ++++++++-------
 .../exmo/align/parser/RDFParser.java          |  43 +--
 test/src/EDOALExportTest.java                 |  64 ++--
 test/src/EDOALParserTest.java                 |  51 ++-
 test/src/EDOALTest.java                       |   3 +-
 7 files changed, 590 insertions(+), 174 deletions(-)
 create mode 100644 examples/omwg/total.xml
 create mode 100644 src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java

diff --git a/examples/omwg/total.xml b/examples/omwg/total.xml
new file mode 100644
index 00000000..ee73e059
--- /dev/null
+++ b/examples/omwg/total.xml
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE rdf:RDF [
+<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
+<!ENTITY wine "http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#">
+<!ENTITY vin "http://ontology.deri.org/vin#">
+<!ENTITY proton "http://proton.semanticweb.org/">
+]>
+
+<!-- JE2010: With the "#" in the end, this is parsed (by the RDF parser...)
+    without it, this is not! -->
+<rdf:RDF xmlns="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#" 
+	 xml:base="http://oms.omwg.org/wine-vin/"
+         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+	 xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
+         xmlns:align="http://knowledgeweb.semanticweb.org/heterogeneity/alignment#"
+	 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+	 xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ex="http://example.org"
+	 xmlns:wine="http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#"
+	 xmlns:vin="http://ontology.deri.org/vin#"
+	 xmlns:proton="http://proton.semanticweb.org/"
+         xmlns:edoal="http://ns.inria.org/edoal/1.0/#">
+  
+  <Alignment rdf:about="http://oms.omwg.org/wine-vin/"> 
+    <xml>yes</xml>
+    <dc:creator>http://www.scharffe.fr/foaf.rdf</dc:creator>
+    <dc:date>2006/06/07</dc:date>
+    <method>manual</method>
+    <purpose>example</purpose>
+    <level>2EDOAL</level>
+    <type>**</type>    
+    <onto1>
+      <Ontology rdf:about="&wine;">
+      <formalism>
+	<Formalism>
+	 <uri>http://www.w3.org/TR/owl-guide/</uri>
+	 <name>owl</name>
+	</Formalism>
+      </formalism>
+      </Ontology>
+    </onto1> 
+    <onto2>
+      <Ontology rdf:about="&vin;">
+      <location>http://www.scharffe.fr/ontologies/OntologieDuVin.wsml</location>
+      <formalism>
+	<Formalism align:uri="http://www.wsmo.org/wsml/wsml-syntax/wsml-dl"
+		   align:name="wsml" />
+      </formalism>
+      </Ontology>
+    </onto2>
+    <!-- Class basis -->
+    <!--map>
+      <Cell rdf:about="MappingRule_class_basis">
+	<entity1><edoal:Class rdf:about="&wine;VintageYear"/></entity1>
+        <entity2><edoal:Class rdf:about="&vin;Millesime"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>Equivalence</relation>
+      </Cell>
+    </map-->
+    <!-- class const: and or not -->
+    <!--map>
+      <Cell rdf:about="MappingRule_class_const">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:not>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:or rdf:parseType="Collection">
+		      <edoal:Class>
+			<edoal:and rdf:parseType="Collection">
+			  <edoal:Class rdf:about="&wine;Bordeaux1"/>
+			  <edoal:Class rdf:about="&wine;Bordeaux2"/>
+			</edoal:and>
+		      </edoal:Class>
+		      <edoal:Class>
+			<edoal:not>
+			  <edoal:Class rdf:about="&wine;Bordeaux3"/>
+			</edoal:not>
+		      </edoal:Class>
+		    </edoal:or>
+		  </edoal:Class>
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&wine;Bordeaux4"/>
+		    </edoal:not>
+		  </edoal:Class>
+		</edoal:and>
+	      </edoal:Class>
+	    </edoal:not>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:Class>
+		<edoal:or rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&wine;Bordeaux5"/>
+		    </edoal:not>
+		  </edoal:Class>
+		  <edoal:Class rdf:about="&wine;Bordeaux6"/>
+		</edoal:or>
+	      </edoal:Class>
+	      <edoal:Class>
+		<edoal:and rdf:parseType="Collection">
+		  <edoal:Class>
+		    <edoal:not>
+		      <edoal:Class rdf:about="&wine;Bordeaux7"/>
+		    </edoal:not>
+		  </edoal:Class>
+		  <edoal:Class rdf:about="&wine;Bordeaux7"/>
+		</edoal:and>
+	      </edoal:Class>
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map-->
+    <!-- class rest: att-type... -->
+    <!--map>
+      <Cell rdf:about="MappingRule_class_rest">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Vin"/>
+	      <edoal:RelationDomainRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:compose>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+  		<edoal:class><edoal:Class rdf:about="&wine;FrenchRegion"/></edoal:class>
+	      </edoal:RelationDomainRestriction>	  
+	      <edoal:PropertyTypeRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Property>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		      <edoal:Property rdf:about="&proton;dptnb"/>
+		    </edoal:compose>
+		  </edoal:Property>
+		</edoal:onAttribute>
+  		<edoal:datatype>An-integer-as-datatype</edoal:datatype>
+	      </edoal:PropertyTypeRestriction>	  
+	      <edoal:AttributeOccurenceRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:or rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&wine;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:or>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;less-than"/>
+  		<edoal:value>12</edoal:value>
+	      </edoal:AttributeOccurenceRestriction>	  
+	      <edoal:Class rdf:about="&wine;Bordeaux7"/>
+	    </edoal:or>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeValueRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:compose>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:value><edoal:Instance rdf:about="&vin;Aquitaine"/></edoal:value>
+	      </edoal:AttributeValueRestriction>	  
+	      <edoal:AttributeOccurenceRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:and rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:and>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;greater-than"/>
+  		<edoal:value>4</edoal:value>
+	      </edoal:AttributeOccurenceRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map-->
+    <!-- class const and rest -->
+    <!-- rel basis -->
+    <!--map>
+      <Cell rdf:about="MappingRule_rel_basis">
+	<entity1><edoal:Relation rdf:about="&wine;locatedIn"/></entity1>
+        <entity2><edoal:Relation rdf:about="&vin;hasTerroir"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>SubsumedBy</relation>
+      </Cell>
+    </map-->
+    <!-- rel const: and or not compose inverse trans refl sym -->
+    <!-- rel rest: att-type... -->
+    <!-- rel const and rest -->
+    <!-- prop basis -->
+    <!--map>
+      <Cell rdf:about="MappingRule_prop_basis">
+        <entity1><edoal:Property rdf:about="&wine;yearValue"/></entity1>
+        <entity2><edoal:Property rdf:about="&vin;anneeMillesime"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>Equivalence</relation>
+      </Cell>
+    </map-->
+    <!-- prop const: and or not compose -->
+    <!-- prop rest: att-type... -->
+    <!-- prop const and rest -->
+    <!-- instance -->
+    <!--map>
+      <Cell rdf:about="MappingRule_inst_basis">
+	<entity1><edoal:Instance rdf:about="&wine;ChateauMargaux1995"/></entity1>
+        <entity2><edoal:Instance rdf:about="&vin;MoutonRotschild1889"/></entity2>
+        <measure rdf:datatype="&xsd;float">1.0</measure>
+        <relation>SubsumedBy</relation>
+      </Cell>
+    </map-->
+    <!-- Miscelaneous -->
+    <!--map>
+      <Cell rdf:about="MappingRule_3">
+	<entity1>
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&wine;Bordeaux17"/>
+	      <edoal:Class>
+		<edoal:or parseType="Collection">
+		  <edoal:Class rdf:about="&wine;Bordeaux18"/>
+		  <edoal:Class rdf:about="&wine;Bordeaux18"/>
+		</edoal:or>
+	      </edoal:Class>
+	    </edoal:and>
+	  </edoal:Class>
+	</entity1>
+	<entity2> 
+	  <edoal:Class>
+	    <edoal:and rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Vin"/>
+	      <edoal:AttributeValueRestriction> 
+		<edoal:onAttribute>
+		  <edoal:Relation>
+		    <edoal:compose rdf:parseType="Collection">
+		      <edoal:Relation rdf:about="&vin;hasTerroir"/>
+		      <edoal:Relation rdf:about="&proton;locatedIn"/>
+		    </edoal:compose>
+		  </edoal:Relation>
+		</edoal:onAttribute>
+		<edoal:comparator rdf:resource="&xsd;equals"/>
+  		<edoal:value><edoal:Instance rdf:about="&vin;Aquitaine"/></edoal:value>
+	      </edoal:AttributeValueRestriction>	  
+	    </edoal:and>
+	  </edoal:Class>
+        </entity2>
+	<measure rdf:datatype='&xsd;float'>1.</measure>
+	<relation>SubsumedBy</relation>
+      </Cell>
+    </map-->
+    <!--map>
+      <Cell rdf:about="MappingRule_4">
+	<entity1>
+ 	  <edoal:Class>
+	    <edoal:or rdf:parseType="Collection">
+	      <edoal:Class rdf:about="&vin;Acidite"/>
+	      <edoal:Class rdf:about="&vin;Astreingence"/>
+	      <edoal:Class rdf:about="&vin;Amertume"/>
+            </edoal:or>
+    	  </edoal:Class>
+	</entity1>
+	<entity2>
+          <edoal:Class>
+            <edoal:not>
+              <edoal:Class rdf:about="&wine;WineFlavor"/>
+	    </edoal:not>
+	  </edoal:Class>
+	</entity2>
+        <measure rdf:datatype='&xsd;float'>1.</measure>
+        <relation>SubsumedBy</relation>
+      </Cell>
+   </map-->
+  </Alignment>
+ </rdf:RDF>
diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java b/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java
new file mode 100644
index 00000000..7b697c26
--- /dev/null
+++ b/src/fr/inrialpes/exmo/align/impl/edoal/ClassDomainRestriction.java
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2006 Digital Enterprise Research Insitute (DERI) Innsbruck
+ * Sourceforge version 1.5 - 2006
+ * Copyright (C) INRIA, 2009-2010
+ *
+ * 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.edoal;
+
+public class ClassDomainRestriction extends ClassRestriction implements Cloneable {
+
+    ClassExpression domain = null;
+
+    /**
+     * Constructs a typeCondition with the given restriction.
+     * 
+     * @param res
+     *            the restriction for the domain
+     * @param target
+     *            the target expression which should be restricted
+     * @throws NullPointerException
+     *             if the restriction is null
+     */
+    public ClassDomainRestriction(final PathExpression p,
+				final ClassExpression cl) {
+	super(p);
+	// Check that this is a property
+	domain = cl;
+    }
+
+    public ClassExpression getDomain() {
+	return domain;
+    }
+
+    public void setDomain( ClassExpression cl ) {
+	domain = cl;
+    }
+
+}
diff --git a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
index d82552c3..799e5340 100644
--- a/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
+++ b/src/fr/inrialpes/exmo/align/impl/renderer/RDFRendererVisitor.java
@@ -55,6 +55,7 @@ import fr.inrialpes.exmo.align.impl.edoal.ClassId;
 import fr.inrialpes.exmo.align.impl.edoal.ClassConstruction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassTypeRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassDomainRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassValueRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassOccurenceRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.PropertyExpression;
@@ -103,9 +104,9 @@ public class RDFRendererVisitor implements AlignmentVisitor {
     private String linePrefix = "";
 
     private int prefixCount = 0;
-	
-    private int exprLevel = 0;
 
+    private boolean isPattern = false;
+	
     public RDFRendererVisitor( PrintWriter writer ){
 	NL = System.getProperty("line.separator");
 	this.writer = writer;
@@ -180,6 +181,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	    writer.print("' standalone='no'?>"+NL);
 	}
 	writer.print("<"+SyntaxElement.RDF.print(DEF)+" xmlns='"+Namespace.ALIGNMENT.prefix+"'");
+	// JE2009: (1) I must use xml:base
 	//writer.print(NL+"         xml:base='"+Namespace.ALIGNMENT.uri+"'");
 	for ( Enumeration e = nslist.keys() ; e.hasMoreElements(); ) {
 	    String k = (String)e.nextElement();
@@ -202,6 +204,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print(">"+NL);
 	increaseIndent();
 	indentedOutputln( "<"+SyntaxElement.XML.print(DEF)+">yes</"+SyntaxElement.XML.print(DEF)+">" );
+	if ( alignment.getLevel().startsWith("2EDOALPattern") ) isPattern = true;
 	indentedOutputln( "<"+SyntaxElement.LEVEL.print(DEF)+">"+align.getLevel()+"</"+SyntaxElement.LEVEL.print(DEF)+">" );
 	indentedOutputln( "<"+SyntaxElement.TYPE.print(DEF)+">"+align.getType()+"</"+SyntaxElement.TYPE.print(DEF)+">");
 	writer.print(extensionString);
@@ -254,9 +257,6 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	if ( onto.getFormalism() != null ) {
 	    indentedOutputln("<"+SyntaxElement.FORMATT.print(DEF)+">");
 	    increaseIndent();
-	    // JE2009: (1) I must use xml:base
-	    // (2) I must use SyntaxElement
-	    //SyntaxElement.RDF_PARSETYPE.print(DEF)
 	    indentedOutputln("<"+SyntaxElement.FORMALISM.print(DEF)+" "+SyntaxElement.NAME.print()+"=\""+onto.getFormalism()+"\" "+SyntaxElement.URI.print()+"=\""+onto.getFormURI()+"\"/>");
 	    decreaseIndent();
 	    indentedOutputln("</"+SyntaxElement.FORMATT.print(DEF)+">");
@@ -270,7 +270,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	URI u1 = cell.getObject1AsURI(alignment);
 	URI u2 = cell.getObject2AsURI(alignment);
 	if ( ( u1 != null && u2 != null)
-	     || alignment.getLevel().equals("2EDOAL") ){
+	     || alignment.getLevel().startsWith("2EDOAL") ){ //expensive test
 	    indentedOutputln("<"+SyntaxElement.MAP.print(DEF)+">");
 	    increaseIndent();
 	    indentedOutput("<"+SyntaxElement.CELL.print(DEF));
@@ -281,7 +281,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	    // Would be better to put it more generic
 	    // But this should be it! (at least for this one)
 	    increaseIndent();
-	    if ( alignment.getLevel().equals("2EDOAL") ) {
+	    if ( alignment.getLevel().startsWith("2EDOAL") ) {
 		indentedOutputln("<"+SyntaxElement.ENTITY1.print(DEF)+">");
 		increaseIndent();
 		((Expression)(cell.getObject1())).accept( this );
@@ -352,12 +352,27 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
     }
 
+    /*
+      // Rewrite this with indentedOutput:
+
+increaseIndent();
+indentedOutputln(); //= writer.print(linePrefix); + writer.print() + 
+indentedOutput();
+write.print();
+writer.print(">"+NL);
+decreaseIndent(); //exprLevel++; exprLevel--; is ineffective
+
+     */
+
     // DONE+TESTED
     public void visit( final ClassId e ) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.CLASS_EXPR.print(DEF));
+	indentedOutput("<"+SyntaxElement.CLASS_EXPR.print(DEF));
 	writer.print(" "+SyntaxElement.RDF_ABOUT.print(DEF));
 	writer.print("=\""+e.getURI());
+	// JE2010: this should be reproduced everywhere
+	if ( isPattern && e.getVariable() != null ) {
+	    writer.print( "\" "+SyntaxElement.VAR.print(DEF)+"=\""+e.getVariable().name() );
+	}
 	writer.print("\"/>");
     }
 
@@ -365,111 +380,125 @@ public class RDFRendererVisitor implements AlignmentVisitor {
     public void visit( final ClassConstruction e ) throws AlignmentException {
 	final Constructor op = e.getOperator();
 	String sop = SyntaxElement.getElement( op ).print(DEF) ;
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.CLASS_EXPR.print(DEF));
+	indentedOutput("<"+SyntaxElement.CLASS_EXPR.print(DEF));
 	increaseIndent();
-	writer.print(">");
-	writer.print(linePrefix);
-	writer.print("<"+sop);
+	writer.print(">"+NL);
+	indentedOutput("<"+sop);
 	if ( (op == Constructor.AND) || (op == Constructor.OR) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
-	writer.print(">");
+	writer.print(">"+NL);
 	increaseIndent();
-	exprLevel++;
-	if ( (op == Constructor.AND) || (op == Constructor.OR) ) {
-	    for (final ClassExpression ce : e.getComponents()) {
-		writer.print(linePrefix);
-		visit( ce );
-	    }
-	} else {
-	    for (final ClassExpression ce : e.getComponents()) {
-		visit( ce );
-	    }
+	for (final ClassExpression ce : e.getComponents()) {
+	    writer.print(linePrefix);
+	    visit( ce );
+	    writer.print(NL);
 	}
-	exprLevel--;
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+sop+">");
+	indentedOutput("</"+sop+">"+NL);
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.CLASS_EXPR.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.CLASS_EXPR.print(DEF)+">");
     }
     
     // DONE+TESTED
     public void visit(final ClassRestriction e) throws AlignmentException {
 	if ( e instanceof ClassValueRestriction ) visit( (ClassValueRestriction)e );
 	else if ( e instanceof ClassTypeRestriction )  visit( (ClassTypeRestriction)e );
+	else if ( e instanceof ClassDomainRestriction )  visit( (ClassDomainRestriction)e );
 	else if ( e instanceof ClassOccurenceRestriction )  visit( (ClassOccurenceRestriction)e );
 	else throw new AlignmentException( "Cannot dispatch ClassExpression "+e );
     }
 
     // DONE+TESTED
     public void visit( final ClassValueRestriction c ) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.PROPERTY_VALUE_COND.print(DEF)+">");
+	indentedOutput("<"+SyntaxElement.PROPERTY_VALUE_COND.print(DEF)+">"+NL);
+	increaseIndent();
+	indentedOutput("<"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
 	increaseIndent();
-	writer.print("<"+SyntaxElement.ONPROPERTY.print(DEF)+">");
 	visit( c.getRestrictionPath() );
-	writer.print("</"+SyntaxElement.ONPROPERTY.print(DEF)+">");
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.COMPARATOR.print(DEF));
+	decreaseIndent();
+	writer.print(NL);
+	indentedOutputln("</"+SyntaxElement.ONPROPERTY.print(DEF)+">");
+	indentedOutput("<"+SyntaxElement.COMPARATOR.print(DEF));
 	writer.print(" "+SyntaxElement.RDF_RESOURCE.print(DEF));
 	writer.print("=\""+((ClassValueRestriction)c).getComparator().getURI());
-	writer.print("\"/>");
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.VALUE.print(DEF)+">");
+	writer.print("\"/>"+NL);
+	indentedOutput("<"+SyntaxElement.VALUE.print(DEF)+">");
 	if ( c.getValue() != null ) {
 	    visit( c.getValue() );
 	} else if ( c.getInstanceValue() != null ) {
+	    increaseIndent();
+	    writer.print(NL);
 	    visit( c.getInstanceValue() );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutputln();
 	} else {
+	    increaseIndent();
+	    writer.print(NL);
 	    visit( c.getPathValue() );
+	    writer.print(NL);
+	    decreaseIndent();
+	    indentedOutputln();
 	}
-	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">");
+	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">"+NL);
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.PROPERTY_VALUE_COND.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.PROPERTY_VALUE_COND.print(DEF)+">");
     }
 
     // DONE+TESTED
     public void visit( final ClassTypeRestriction c ) throws AlignmentException {
-	writer.print("<"+SyntaxElement.PROPERTY_TYPE_COND.print(DEF)+">");
+	indentedOutput("<"+SyntaxElement.PROPERTY_TYPE_COND.print(DEF)+">"+NL);
+	increaseIndent();
+	indentedOutput("<"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
 	increaseIndent();
-	writer.print("<"+SyntaxElement.ONPROPERTY.print(DEF)+">");
 	visit( c.getRestrictionPath() );
-	writer.print("</"+SyntaxElement.ONPROPERTY.print(DEF)+">");
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.COMPARATOR.print(DEF));
-	writer.print(" "+SyntaxElement.RDF_RESOURCE.print(DEF));
-	// This is always EQUAL
-	writer.print("=\""+Comparator.EQUAL.getURI());
-	writer.print("\"/>");
-	writer.print(linePrefix);
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
 	visit( c.getType() );
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.PROPERTY_TYPE_COND.print(DEF)+">");
+	writer.print(NL);
+	indentedOutput("</"+SyntaxElement.PROPERTY_TYPE_COND.print(DEF)+">");
+    }
+
+    // DONE+TESTED
+    public void visit( final ClassDomainRestriction c ) throws AlignmentException {
+	indentedOutput("<"+SyntaxElement.RELATION_DOMAIN_COND.print(DEF)+">"+NL);
+	increaseIndent();
+	indentedOutput("<"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
+	increaseIndent();
+	visit( c.getRestrictionPath() );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
+	indentedOutput("<"+SyntaxElement.TOCLASS.print(DEF)+">"+NL);
+	increaseIndent();
+	visit( c.getDomain() );
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</"+SyntaxElement.TOCLASS.print(DEF)+">"+NL);
+	decreaseIndent();
+	indentedOutput("</"+SyntaxElement.RELATION_DOMAIN_COND.print(DEF)+">");
     }
 
     // DONE+TESTED
     public void visit( final ClassOccurenceRestriction c ) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.PROPERTY_OCCURENCE_COND.print(DEF)+">");
+	indentedOutput("<"+SyntaxElement.PROPERTY_OCCURENCE_COND.print(DEF)+">"+NL);
+	increaseIndent();
+	indentedOutput("<"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
 	increaseIndent();
-	writer.print("<"+SyntaxElement.ONPROPERTY.print(DEF)+">");
 	visit( c.getRestrictionPath() );
-	writer.print("</"+SyntaxElement.ONPROPERTY.print(DEF)+">");
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.COMPARATOR.print(DEF));
+	writer.print(NL);
+	decreaseIndent();
+	indentedOutput("</"+SyntaxElement.ONPROPERTY.print(DEF)+">"+NL);
+	indentedOutput("<"+SyntaxElement.COMPARATOR.print(DEF));
 	writer.print(" "+SyntaxElement.RDF_RESOURCE.print(DEF));
 	writer.print("=\""+c.getComparator().getURI());
-	writer.print("\"/>");
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.VALUE.print(DEF)+">");
+	writer.print("\"/>"+NL);
+	indentedOutput("<"+SyntaxElement.VALUE.print(DEF)+">");
 	writer.print(c.getOccurence());
-	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">");
+	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">"+NL);
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.PROPERTY_OCCURENCE_COND.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.PROPERTY_OCCURENCE_COND.print(DEF)+">");
     }
     
     // DONE
@@ -482,9 +511,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	
     // DONE
     public void visit(final PropertyId e) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.PROPERTY_EXPR.print(DEF));
-	increaseIndent();
+	indentedOutput("<"+SyntaxElement.PROPERTY_EXPR.print(DEF));
 	writer.print(" "+SyntaxElement.RDF_ABOUT.print(DEF));
 	writer.print("=\""+e.getURI());
 	writer.print("\"/>");
@@ -492,40 +519,35 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 
     // DONE
     public void visit(final PropertyConstruction e) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.PROPERTY_EXPR.print(DEF));
+	indentedOutput("<"+SyntaxElement.PROPERTY_EXPR.print(DEF));
 	increaseIndent();
 	final Constructor op = e.getOperator();
 	String sop = SyntaxElement.getElement( op ).print(DEF) ;
-	writer.print(">");
-	writer.print(linePrefix);
-	writer.print("<"+sop);
+	writer.print(">"+NL);
+	indentedOutput("<"+sop);
 	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
-	writer.print(">");
+	writer.print(">"+NL);
 	increaseIndent();
-	exprLevel++;
 	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) {
 	    for ( final PathExpression pe : e.getComponents() ) {
 		writer.print(linePrefix);
 		visit( pe );
+		writer.print(NL);
 	    }
 	} else {
 	    for (final PathExpression pe : e.getComponents()) {
 		visit( pe );
 	    }
 	}
-	exprLevel--;
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+sop+">");
+	indentedOutput("</"+sop+">"+NL);
 	// export transf
 	//if (e.getTransf() != null) {
 	//    visit( e.getTransf() );
 	//}
 	// closing the tag
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.PROPERTY_EXPR.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.PROPERTY_EXPR.print(DEF)+">");
     }
     
     // DONE
@@ -553,36 +575,33 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	} else {
 	    visit( c.getPath() );
 	}
-	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">");
+	writer.print("</"+SyntaxElement.VALUE.print(DEF)+">"+NL);
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.VALUE_COND.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.VALUE_COND.print(DEF)+">");
     }
 
     // DONE
     public void visit(final PropertyDomainRestriction c) throws AlignmentException {
 	writer.print(linePrefix);
 	increaseIndent();
-	writer.print("<"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">");
+	writer.print("<"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">"+NL);
 	increaseIndent();
 	writer.print("<"+SyntaxElement.TOCLASS.print(DEF)+">");
 	visit( c.getDomain() );
-	writer.print("</"+SyntaxElement.TOCLASS.print(DEF)+">");
+	writer.print("</"+SyntaxElement.TOCLASS.print(DEF)+">"+NL);
 	decreaseIndent();
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">"+NL);
     }
 
     // DONE
     public void visit(final PropertyTypeRestriction c) throws AlignmentException {
 	writer.print(linePrefix);
 	increaseIndent();
-	writer.print("<"+SyntaxElement.TYPE_COND.print(DEF)+">");
+	writer.print("<"+SyntaxElement.TYPE_COND.print(DEF)+">"+NL);
 	visit( c.getType() );
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.TYPE_COND.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.TYPE_COND.print(DEF)+">");
     }
     
     // DONE
@@ -595,8 +614,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	
     // DONE
     public void visit( final RelationId e ) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.RELATION_EXPR.print(DEF));
+	indentedOutput("<"+SyntaxElement.RELATION_EXPR.print(DEF));
 	writer.print(" "+SyntaxElement.RDF_ABOUT.print(DEF));
 	writer.print("=\""+e.getURI());
 	writer.print("\"/>");
@@ -604,35 +622,30 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 
     // DONE
     public void visit( final RelationConstruction e ) throws AlignmentException {
-	writer.print(linePrefix);
-	writer.print("<"+SyntaxElement.RELATION_EXPR.print(DEF));
+	indentedOutput("<"+SyntaxElement.RELATION_EXPR.print(DEF));
 	increaseIndent();
 	final Constructor op = e.getOperator();
 	String sop = SyntaxElement.getElement( op ).print(DEF) ;
-	writer.print(">");
-	writer.print(linePrefix);
-	writer.print("<"+sop);
+	writer.print(">"+NL);
+	indentedOutput("<"+sop);
 	if ( (op == Constructor.OR) || (op == Constructor.AND) || (op == Constructor.COMP) ) writer.print(" "+SyntaxElement.RDF_PARSETYPE.print(DEF)+"=\"Collection\"");
-	writer.print(">");
+	writer.print(">"+NL);
 	increaseIndent();
-	exprLevel++;
 	if ( (op == Constructor.AND) || (op == Constructor.OR) || (op == Constructor.COMP) ) {
 	    for (final PathExpression re : e.getComponents()) {
 		writer.print(linePrefix);
 		visit( re );
+		writer.print(NL);
 	    }
 	} else { // NOT... or else: enumerate them
 	    for (final PathExpression re : e.getComponents()) {
 		visit( re );
 	    }
 	}
-	exprLevel--;
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+sop+">");
+	indentedOutput("</"+sop+">"+NL);
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.RELATION_EXPR.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.RELATION_EXPR.print(DEF)+">");
     }
     
     // DONE
@@ -653,8 +666,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print("</"+SyntaxElement.TOCLASS.print(DEF)+">");
 	decreaseIndent();
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.CODOMAIN_RESTRICTION.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.CODOMAIN_RESTRICTION.print(DEF)+">");
     }
 
     // DONE
@@ -668,8 +680,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	writer.print("</"+SyntaxElement.TOCLASS.print(DEF)+">");
 	decreaseIndent();
 	decreaseIndent();
-	writer.print(linePrefix);
-	writer.print("</"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">");
+	indentedOutput("</"+SyntaxElement.DOMAIN_RESTRICTION.print(DEF)+">");
     }
     
     // DONE
@@ -680,9 +691,10 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 
     // DONE+TESTED
     public void visit( final InstanceId e ) throws AlignmentException {
-	writer.print("<"+SyntaxElement.INSTANCE_EXPR.print(DEF)+" "
-		     +SyntaxElement.RDF_ABOUT.print(DEF)+"=\""
-		     +e.getURI()+"\"/>");
+	indentedOutput("<"+SyntaxElement.INSTANCE_EXPR.print(DEF));
+	writer.print(" "+SyntaxElement.RDF_ABOUT.print(DEF));
+	writer.print("=\""+e.getURI());
+	writer.print("\"/>");
     }
     
     // DONE+TESTED
@@ -692,7 +704,7 @@ public class RDFRendererVisitor implements AlignmentVisitor {
 	
     // DONE
     public void visit( final Datatype e ) throws AlignmentException {
-	writer.print("<"+SyntaxElement.DATATYPE.print(DEF)+">");
+	indentedOutput("<"+SyntaxElement.DATATYPE.print(DEF)+">");
 	writer.print(e.plainText());
 	writer.print("</"+SyntaxElement.DATATYPE.print(DEF)+">");
     }
@@ -708,8 +720,6 @@ public class RDFRendererVisitor implements AlignmentVisitor {
      */
     private void increaseIndent() {
 	prefixCount++;
-	//v1
-	//calcPrefix();
     }
     
     /**
@@ -718,8 +728,6 @@ public class RDFRendererVisitor implements AlignmentVisitor {
     private void decreaseIndent() {
 	if (prefixCount > 0) {
 	    prefixCount--;
-	    //v1
-	    //calcPrefix();
 	}
     }
     
@@ -735,13 +743,17 @@ public class RDFRendererVisitor implements AlignmentVisitor {
     }
 
     private void indentedOutputln( String s ){
-	//v2
 	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
 	writer.print(s+NL);
     }
     private void indentedOutput( String s ){
-	//v2
 	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
 	writer.print(s);
     }
+    private void indentedOutputln(){
+	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
+    }
+    private void indentedOutput(){
+	for (int i = 0; i < prefixCount; i++) writer.print(INDENT);
+    }
 }
diff --git a/src/fr/inrialpes/exmo/align/parser/RDFParser.java b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
index aaa0cd85..698f7b26 100644
--- a/src/fr/inrialpes/exmo/align/parser/RDFParser.java
+++ b/src/fr/inrialpes/exmo/align/parser/RDFParser.java
@@ -41,6 +41,7 @@ import fr.inrialpes.exmo.align.impl.edoal.ClassId;
 import fr.inrialpes.exmo.align.impl.edoal.ClassConstruction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassTypeRestriction;
+import fr.inrialpes.exmo.align.impl.edoal.ClassDomainRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassValueRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.ClassOccurenceRestriction;
 import fr.inrialpes.exmo.align.impl.edoal.PathExpression;
@@ -79,11 +80,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.LinkedList;
 
-// JE2010: to be suppressed
-// How do I shut up the logger?
-
 import java.util.logging.Logger;
-import java.util.logging.Handler;
 import java.util.logging.Level;
 
 // Yes we are relying on Jena for parsing RDF
@@ -103,9 +100,8 @@ import com.hp.hpl.jena.vocabulary.RDF;
 
 /**
  * <p>
- * Parser for the omwg xml mapping syntax. The document reader is Jena, input can be any document 
- * which can be read by Jena. The input document format shall be consistent with format document -- 
- * Expressive alignment language and implementation.  You can also see the example input document--example.rdf
+ * Parser for the EDOAL syntax. The reader is Jena, input is an EDOALAlignment
+ * The input document format shall be consistent with format document 
  * 
  * </p>
  * <p>
@@ -124,7 +120,7 @@ public class RDFParser {
 
     private int debug = 0;
 
-    private boolean isPattern = false; //2010: why is parseAlignment static????
+    private boolean isPattern = false;
 
     /** 
      * Creates an RDF Parser.
@@ -170,21 +166,21 @@ public class RDFParser {
      * @throws AlignmentException if there is any exception, throw AlignmentException that include describe infomation
      * and a caused exception.
      */
-    public EDOALAlignment parse( final Model align ) throws AlignmentException {
+    public EDOALAlignment parse( final Model rdfmodel ) throws AlignmentException {
 	// Initialize the syntax description
 	initSyntax();
 	// Shut up logging handling
 	com.hp.hpl.jena.rdf.model.impl.RDFDefaultErrorHandler.silent = true;
 	// Get the statement including alignment resource as rdf:type
-	StmtIterator stmtIt = align.listStatements(null, RDF.type,(Resource)SyntaxElement.getResource("Alignment"));
+	StmtIterator stmtIt = rdfmodel.listStatements(null, RDF.type,(Resource)SyntaxElement.getResource("Alignment"));
 	// Take the first one if it exists
-	if ( !stmtIt.hasNext() ) throw new AlignmentException("There is no alignment in the RDF docuemnt");
+	if ( !stmtIt.hasNext() ) throw new AlignmentException("There is no alignment in the RDF document");
 	Statement alignDoc = stmtIt.nextStatement();
 	// Step from this statement
-	final EDOALAlignment doc = parseAlignment( alignDoc.getSubject() );
+	final EDOALAlignment al = parseAlignment( alignDoc.getSubject() );
 	// Clean up memory
-	align.close(); // JE: I am not sure that I will not have trouble with initSyntax
-	return doc;
+	rdfmodel.close(); // JE: I am not sure that I will not have trouble with initSyntax
+	return al;
     }
 
     // Below is the plumbing:
@@ -203,7 +199,8 @@ public class RDFParser {
 	if (is == null) throw new AlignmentException("The reader must not be null");
 	Model align = ModelFactory.createDefaultModel();
 	align.read( is, null );
-	// debug align.write(System.out);
+	// Apparently this does not really works
+	//align.write(System.out);
 	return parse( align );
     }
     
@@ -406,6 +403,7 @@ public class RDFParser {
 	if ( rdfType.equals( SyntaxElement.CLASS_EXPR.resource ) ||
 	     rdfType.equals( SyntaxElement.PROPERTY_OCCURENCE_COND.resource ) ||
 	     rdfType.equals( SyntaxElement.PROPERTY_TYPE_COND.resource ) ||
+	     rdfType.equals( SyntaxElement.RELATION_DOMAIN_COND.resource ) ||
 	     rdfType.equals( SyntaxElement.PROPERTY_VALUE_COND.resource ) ) {
 	    result = parseClass( node );
 	} else if ( rdfType.equals( SyntaxElement.PROPERTY_EXPR.resource ) ||
@@ -473,21 +471,21 @@ public class RDFParser {
 	} else {
 	    if ( !rdfType.equals( SyntaxElement.PROPERTY_OCCURENCE_COND.resource ) &&
 		 !rdfType.equals( SyntaxElement.PROPERTY_TYPE_COND.resource ) &&
+		 !rdfType.equals( SyntaxElement.RELATION_DOMAIN_COND.resource ) &&
 		 !rdfType.equals( SyntaxElement.PROPERTY_VALUE_COND.resource ) ) {
 		throw new AlignmentException( "Bad class restriction type : "+rdfType );
 	    }
 	    PathExpression pe;
 	    Comparator comp;
-	    // Find onProperty
+	    // Find onAttribute
 	    Statement stmt = node.getProperty( (Property)SyntaxElement.ONPROPERTY.resource );
-	    if ( stmt == null ) throw new AlignmentException( "Required edoal:onProperty property" );
+	    if ( stmt == null ) throw new AlignmentException( "Required edoal:onAttribute property" );
 	    //JE2010MUSTCHECK
 	    pe = parsePathExpression( stmt.getResource() );
 	    if ( rdfType.equals( SyntaxElement.PROPERTY_TYPE_COND.resource ) ) {
 		// JEZ010: check that pe is a Property / Relation
 		// ==> different treatment
 		// Datatype could also be defined as objets...? (like rdf:resource="")
-		// Or classes? OF COURSE????
 		stmt = node.getProperty( (Property)SyntaxElement.DATATYPE.resource );
 		if ( stmt == null ) throw new AlignmentException( "Required edoal:datatype property" );
 		RDFNode nn = stmt.getObject();
@@ -496,6 +494,15 @@ public class RDFParser {
 		} else {
 		    throw new AlignmentException( "Bad edoal:datatype value" );
 		}
+	    } else if ( rdfType.equals( SyntaxElement.RELATION_DOMAIN_COND.resource ) ) {
+		stmt = node.getProperty( (Property)SyntaxElement.TOCLASS.resource );
+		if ( stmt == null ) throw new AlignmentException( "Required edoal:class property" );
+		RDFNode nn = stmt.getObject();
+		if ( nn.isResource() ) {
+		    return new ClassDomainRestriction( pe,  parseClass( (Resource)nn ) );
+		} else {
+		    throw new AlignmentException( "Incorrect class expression "+nn );
+		} 
 	    } else {
 		// Find comparator
 		// JE2010: This is not good as comparator management...
diff --git a/test/src/EDOALExportTest.java b/test/src/EDOALExportTest.java
index 472749ee..8b4e5785 100644
--- a/test/src/EDOALExportTest.java
+++ b/test/src/EDOALExportTest.java
@@ -199,23 +199,23 @@ Does bot work anymore because not visitable
     public void testExportClassCond() throws Exception {
 	ClassRestriction toExport = null;
 	toExport = new ClassValueRestriction(new PropertyId(new URI("http://my.sister#age")),Comparator.GREATER,new Value("18"));
-	assertEquals( render( toExport ), "<edoal:PropertyValueRestriction>"
-	    + "<edoal:onProperty><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onProperty>"
+	assertEquals( render( toExport ), "<edoal:AttributeValueRestriction>"
+	    + "<edoal:onAttribute><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onAttribute>"
 	    + "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#greater-than\"/>"
 	    + "<edoal:value>18</edoal:value>"
-			  + "</edoal:PropertyValueRestriction>" );
-	toExport = new ClassTypeRestriction( new PropertyId(new URI("http://my.sister#age")), new Datatype("18"));
+			  + "</edoal:AttributeValueRestriction>" );
+	toExport = new ClassTypeRestriction( new PropertyId(new URI("http://my.sister#age")), new Datatype("integer-under-100"));
 	assertEquals( render( toExport ), "<edoal:PropertyTypeRestriction>"
-	    + "<edoal:onProperty><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onProperty>"
-	    + "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#equals\"/>"
-	    + "<edoal:datatype>18</edoal:datatype>"
+	    + "<edoal:onAttribute><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onAttribute>"
+	    //+ "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#equals\"/>"
+	    + "<edoal:datatype>integer-under-100</edoal:datatype>"
 		+ "</edoal:PropertyTypeRestriction>" );
 	toExport = new ClassOccurenceRestriction( new PropertyId(new URI("http://my.sister#age")), Comparator.GREATER, 18);
-	assertEquals( render( toExport ), "<edoal:PropertyOccurenceRestriction>"
-	    + "<edoal:onProperty><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onProperty>"
+	assertEquals( render( toExport ), "<edoal:AttributeOccurenceRestriction>"
+	    + "<edoal:onAttribute><edoal:Property rdf:about=\"http://my.sister#age\"/></edoal:onAttribute>"
 	    + "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#greater-than\"/>"
 	    + "<edoal:value>18</edoal:value>"
-		      + "</edoal:PropertyOccurenceRestriction>" );
+		      + "</edoal:AttributeOccurenceRestriction>" );
     }
     
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
@@ -270,22 +270,22 @@ Does bot work anymore because not visitable
 	    + "<edoal:Class rdf:about=\"Acidite\"/>"
 	    + "<edoal:Class rdf:about=\"Amertume\"/>"
 	    + "<edoal:Class rdf:about=\"Astreinngence\"/>"
-	    + "<edoal:PropertyValueRestriction>"
-	    + "<edoal:onProperty>"
+	    + "<edoal:AttributeValueRestriction>"
+	    + "<edoal:onAttribute>"
 	    + "<edoal:Property rdf:about=\"http://vinum#age\"/>"
-	    + "</edoal:onProperty>"
+	    + "</edoal:onAttribute>"
 	    + "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#greater-than\"/>"
 	    + "<edoal:value>20</edoal:value>"
-	    + "</edoal:PropertyValueRestriction>"
+	    + "</edoal:AttributeValueRestriction>"
 	    + "</edoal:or>"+ "</edoal:Class>" );
     }
 
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
     public void testExportPropertyCond() throws Exception {
 	assertEquals( render( new PropertyDomainRestriction(new ClassId("http://meine/tolle/restriction")) ),
-		      "<edoal:DomainRestriction><edoal:toClass>"
+		      "<edoal:DomainRestriction><edoal:class>"
 		      + "<edoal:Class rdf:about=\"http://meine/tolle/restriction\"/>"
-		      + "</edoal:toClass></edoal:DomainRestriction>" );
+		      + "</edoal:class></edoal:DomainRestriction>" );
 	assertEquals( render( new PropertyValueRestriction( Comparator.EQUAL, new Value("18"))),
 		      "<edoal:ValueRestriction>"
 		      + "<edoal:comparator rdf:resource=\"http://www.w3.org/2001/XMLSchema#equals\"/>"
@@ -352,13 +352,13 @@ Does bot work anymore because not visitable
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
     public void testExportRelationCondCond() throws Exception {
 	RelationRestriction toExport = new RelationDomainRestriction(new ClassId("http://my/super/class"));
-	assertEquals( render( toExport), "<edoal:DomainRestriction><edoal:toClass>"
+	assertEquals( render( toExport), "<edoal:DomainRestriction><edoal:class>"
 		      + "<edoal:Class rdf:about=\"http://my/super/class\"/>"
-		      + "</edoal:toClass></edoal:DomainRestriction>");
+		      + "</edoal:class></edoal:DomainRestriction>");
     toExport = new RelationCoDomainRestriction(new ClassId("http://my/super/class"));
-	assertEquals( render( toExport), "<edoal:CodomainRestriction><edoal:toClass>"
+	assertEquals( render( toExport), "<edoal:CodomainRestriction><edoal:class>"
 	    + "<edoal:Class rdf:about=\"http://my/super/class\"/>"
-		      + "</edoal:toClass></edoal:CodomainRestriction>");
+		      + "</edoal:class></edoal:CodomainRestriction>");
     }
 
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
@@ -395,9 +395,9 @@ Does bot work anymore because not visitable
 	    + "<edoal:and rdf:parseType=\"Collection\">"
 	    + "<edoal:Relation rdf:about=\"http://my/super/relation0\"/>"
 	    + "<edoal:Relation rdf:about=\"http://my/super/relation1\"/>"
-	    + "<edoal:DomainRestriction><edoal:toClass>"
+	    + "<edoal:DomainRestriction><edoal:class>"
 	    + "<edoal:Class rdf:about=\"http://my/super/class\"/>"
-	    + "</edoal:toClass></edoal:DomainRestriction>" 
+	    + "</edoal:class></edoal:DomainRestriction>" 
 	    + "</edoal:and>" + "</edoal:Relation>");
 	toExport = new RelationConstruction( Constructor.OR, expressions );
 	assertEquals( render( toExport ), 
@@ -405,9 +405,9 @@ Does bot work anymore because not visitable
 	    + "<edoal:or rdf:parseType=\"Collection\">"
 	    + "<edoal:Relation rdf:about=\"http://my/super/relation0\"/>"
 	    + "<edoal:Relation rdf:about=\"http://my/super/relation1\"/>"
-	    + "<edoal:DomainRestriction><edoal:toClass>"
+	    + "<edoal:DomainRestriction><edoal:class>"
 	    + "<edoal:Class rdf:about=\"http://my/super/class\"/>"
-	    + "</edoal:toClass></edoal:DomainRestriction>" 
+	    + "</edoal:class></edoal:DomainRestriction>" 
 		      + "</edoal:or>" + "</edoal:Relation>");
 
 	final Set<PathExpression> expressions2 = new LinkedHashSet<PathExpression>();
@@ -421,9 +421,9 @@ Does bot work anymore because not visitable
 	    + "<edoal:Relation><edoal:not>"
 	    + "<edoal:Relation rdf:about=\"http://my/super/relation\"/>"
 	    + "</edoal:not></edoal:Relation>" 
-	    + "<edoal:CodomainRestriction><edoal:toClass>"
+	    + "<edoal:CodomainRestriction><edoal:class>"
 	    + "<edoal:Class rdf:about=\"http://my/super/class\"/>"
-	    + "</edoal:toClass></edoal:CodomainRestriction>" 
+	    + "</edoal:class></edoal:CodomainRestriction>" 
 	    + "</edoal:and>" + "</edoal:Relation>");
 	toExport = new RelationConstruction( Constructor.INVERSE, Collections.singleton((PathExpression)new RelationId("http://my/super/relation")));
 	assertEquals( render( toExport ), 
@@ -535,13 +535,13 @@ Does bot work anymore because not visitable
     public void testExportRelationExprExotic() throws Exception {
 	final String reference = "<edoal:Relation>"
 	    + "<edoal:and rdf:parseType=\"Collection\">"
-	    + "<edoal:DomainRestriction><edoal:toClass>"
-	    + "<edoal:Class rdf:about=\"r2\"/>" + "</edoal:toClass></edoal:DomainRestriction>"
+	    + "<edoal:DomainRestriction><edoal:class>"
+	    + "<edoal:Class rdf:about=\"r2\"/>" + "</edoal:class></edoal:DomainRestriction>"
 	    + "<edoal:Relation rdf:about=\"c1\"/>"
-	    + "<edoal:DomainRestriction><edoal:toClass>" + "<edoal:Class rdf:about=\"r1\"/>"
-	    + "</edoal:toClass></edoal:DomainRestriction>"
-	    + "<edoal:DomainRestriction><edoal:toClass>" + "<edoal:Class rdf:about=\"r0\"/>"
-	    + "</edoal:toClass></edoal:DomainRestriction>" + "</edoal:and>" + "</edoal:Relation>";
+	    + "<edoal:DomainRestriction><edoal:class>" + "<edoal:Class rdf:about=\"r1\"/>"
+	    + "</edoal:class></edoal:DomainRestriction>"
+	    + "<edoal:DomainRestriction><edoal:class>" + "<edoal:Class rdf:about=\"r0\"/>"
+	    + "</edoal:class></edoal:DomainRestriction>" + "</edoal:and>" + "</edoal:Relation>";
 	
 	RelationId c1 = new RelationId("c1");
 	RelationId c2 = new RelationId("c2");
diff --git a/test/src/EDOALParserTest.java b/test/src/EDOALParserTest.java
index 95864d3a..be205ced 100644
--- a/test/src/EDOALParserTest.java
+++ b/test/src/EDOALParserTest.java
@@ -33,6 +33,7 @@ import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.Alignment;
 
+import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor;
 import fr.inrialpes.exmo.align.parser.AlignmentParser;
 
 import org.w3c.dom.Document;
@@ -83,10 +84,14 @@ import fr.inrialpes.exmo.align.impl.edoal.RelationId;
 
 public class EDOALParserTest {
 
-    private static DocumentBuilder BUILDER;
+    //private static DocumentBuilder BUILDER;
+    private AlignmentParser aparser1 = null;
 
     @Test(groups = { "full", "omwg", "raw" })
     public void setUp() throws Exception {
+	aparser1 = new AlignmentParser( 0 );
+	assertNotNull( aparser1 );
+	/*
 	final DocumentBuilderFactory FAC = DocumentBuilderFactory.newInstance();
 	FAC.setValidating(false);
 	FAC.setNamespaceAware(false);
@@ -97,12 +102,50 @@ public class EDOALParserTest {
 	    e.printStackTrace();
 	}
 	BUILDER = doc;
+	*/
+    }
+
+    @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods={ "setUp" })
+    public void roundTripTest() throws Exception {
+	// Load the full test
+	aparser1.initAlignment( null );
+	Alignment alignment = aparser1.parse( "file:examples/omwg/total.xml" );
+	assertNotNull( alignment );
+	// Print it in a string
+	ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
+	PrintWriter writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( stream, "UTF-8" )), true);
+	AlignmentVisitor renderer = new RDFRendererVisitor( writer );
+	alignment.render( renderer );
+	writer.flush();
+	writer.close();
+	String str1 = stream.toString();
+	// Read it again
+	aparser1 = new AlignmentParser( 0 );
+	aparser1.initAlignment( null );
+	// Currently parseString does not seems to work for EDOAL
+	//System.err.println( str1 );
+	alignment = aparser1.parseString( str1 );
+	// Print it in another string
+	stream = new ByteArrayOutputStream(); 
+	writer = new PrintWriter (
+			  new BufferedWriter(
+			       new OutputStreamWriter( stream, "UTF-8" )), true);
+	renderer = new RDFRendererVisitor( writer );
+	alignment.render( renderer );
+	writer.flush();
+	writer.close();
+	String str2 = stream.toString();
+	assertEquals( str1.length(), str2.length() );
+	// They should be the same... (no because of invertion...)
+	// But have the same length
+	assertEquals( str1, str2 );
     }
 
+    /*
     @Test(groups = { "full", "omwg", "raw" }, dependsOnMethods = {"setUp"})
     public void testParsePath() {
-	// Does not work becaue it is supposed to work with RDF models...
-	/*
 	Utility uparser = new Utility();
 	assertEquals( uparser.parsePath( "<Property rdf:about='http://my.beauty.url'/>" ),
 		      
@@ -127,8 +170,8 @@ public class EDOALParserTest {
 	} catch (NoSuchMethodException e) {
 	    e.printStackTrace();
 	}
-	*/
     }
+    */
 
     /*
     @Test(groups = { "full", "omwg" }, dependsOnMethods = {"setUp"})
diff --git a/test/src/EDOALTest.java b/test/src/EDOALTest.java
index e9f8d718..382afc67 100644
--- a/test/src/EDOALTest.java
+++ b/test/src/EDOALTest.java
@@ -31,6 +31,7 @@ import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.Alignment;
 
+import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment;
 import fr.inrialpes.exmo.align.impl.renderer.RDFRendererVisitor;
 import fr.inrialpes.exmo.align.parser.AlignmentParser;
 
@@ -70,7 +71,7 @@ java -cp ../../lib/procalign.jar fr.inrialpes.exmo.align.util.ParserPrinter wine
 	assertNotNull( aparser1 );
 	alignment = aparser1.parse( "file:examples/omwg/wine.xml" );
 	assertNotNull( alignment );
-	//assertTrue( alignment instanceof EDOALAlignment );
+	assertTrue( alignment instanceof EDOALAlignment );
 	FileOutputStream stream = new FileOutputStream("test/output/wine2.xml");
 	PrintWriter writer = new PrintWriter (
 			  new BufferedWriter(
-- 
GitLab