From 1d1ee5140149d0b380e2e4b143d22d36b523f1aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Mon, 17 Nov 2014 11:59:19 +0000
Subject: [PATCH] - Enabled multiple URIs for the same alignment - Added
 "force" in load (preserving existing alignments with same URI)

---
 html/relnotes.html                            | 12 ++--
 html/rest.html                                | 27 ++++++++-
 .../exmo/align/impl/Annotations.java          |  3 +-
 .../inrialpes/exmo/align/impl/Namespace.java  |  1 +
 .../align/service/AServProtocolManager.java   | 49 +++++++++++++---
 .../exmo/align/service/AlignmentService.java  |  1 -
 .../inrialpes/exmo/align/service/Cache.java   |  7 ++-
 .../exmo/align/service/HTMLAServProfile.java  | 14 ++++-
 .../exmo/align/service/SQLCache.java          | 11 ++--
 .../exmo/align/service/VolatilCache.java      | 56 ++++++++++++++-----
 .../exmo/align/service/WSAServProfile.java    |  7 +++
 .../inrialpes/exmo/align/service/aserv.wsdl   | 26 ++++++++-
 12 files changed, 175 insertions(+), 39 deletions(-)

diff --git a/html/relnotes.html b/html/relnotes.html
index 38bb6f39..8c23b194 100644
--- a/html/relnotes.html
+++ b/html/relnotes.html
@@ -37,10 +37,10 @@ The development of 4 versions continues.
 <h2>Under development (you can contribute)</h2>
 
 <p><ul compact="1">
-<li>Provide several URIs for the same alignment (serv)</li>
+<li>Complete tutorial4 (doc).</li>
+<li>Implement correspondence selection (serv)</li>
 <li>Implement database store for EDOAL (serv)</li>
 <li>Implementation of a provenance metadata tag (serv/impl)</li>
-<li>Complete tutorial4 (doc).</li>
 <li>Implement metadata edition (serv)</li>
 <li>Add simple "harder" test generator (gen)</li>
 <li>Add simple "hidden" test generator (gen)</li>
@@ -53,7 +53,6 @@ The development of 4 versions continues.
 <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>Implement transformations in EDOAL (edoal)</li>
 <li>Improve HTML interface layout and usability (serv)</li>
-<li>Implement correspondence selection (serv)</li>
 <li>Automatically switch to correct <tt>ontowrap</tt> implementation in parsers (parser)</li>
 <li>Render alignments as module descriptions (impl)</li>
 <li>Implement extensive evaluation framework (impl)</li>
@@ -71,12 +70,12 @@ with a warning:
 <p>The Alignment API is now compiled in Java 1.7.</p>
 
 <!--h2>Version 4.9 (1xxx): ??/??/201X - Letraset</h2-->
-<!--h2>Version 4.8 (1xxx): ??/??/201x - Antésine</h2-->
+<!--h2>Version 4.8 (1xxx): ??/??/201x - AntÊsine</h2-->
 <!--h2>Version 4.7 (19xx): ??/11/2014 - Al pesto</h2-->
 <p><ul compact="1">
 <li><span style="color: red;">Deprecated</span> <tt>BasicAlignment.removeAlignCell()</tt>, use <tt>remCell()</tt> instead (impl)</tt>
 <li><span style="color: red;">Moved</span> <tt>QueryMediator</tt>, from <tt>service</tt> to <tt>queryprocessor</tt> (impl)</tt>
-<li><span style="color: red;">Changed</span> standard extension namespace to http://exmo.inrialpes.fr/align/ext/1.0/# (impl)</tt>
+<li><span style="color: red;">Changed</span> standard extension namespace to http://exmo.inrialpes.fr/align/ext/1.0/ (impl)</tt>
 <li>Fixed a bug in <tt>QueryMediator</tt> which doubled '#' (serv)</li>
 <li>Fixed a few mistakes in <tt>SilkRendererVisitor</tt> (impl)</li>
 <li>Fixed several bugs in <tt>GraphPatternRendererVisitor</tt> (impl)</li>
@@ -85,7 +84,9 @@ with a warning:
 <li>Implemented (fully) extension parsing in RDFParser (parser)</li>
 <li>Reorganised AlignmentServices into transport (HTTP) and service (HTML/Web service) (serv)</li>
 <li>Enabled query translation in interface and web service (serv)</li>
+<li>Enabled multiple URIs for the same alignment (serv)</li>
 <li>Added ontology network support in server (serv)</li>
+<li>Added get alignments by URI in server (serv)</li>
 <li>Added JSON interface for server (serv)</li>
 <li>Added a command-line utility for query translation (cli)</li>
 <li>Added a command-line utility for alignment aggregation (cli)</li>
@@ -101,6 +102,7 @@ with a warning:
 <li>Managed upload via <span style="color: green">Commons fileupload 1.3.1</span> and <span style="color: green">io 2.4</span> instead of Jetty (serv)</li>
 <li>Upgraded to <span style="color: green">Servlet API 3.1</span> (lib)</li>
 <li>Upgraded to <span style="color: green">Jetty 9.1.4</span> (lib)</li>
+<li>Upgraded to <span style="color: green">OWL API 3.5.0</span> (lib)</li>
 </ul></p>
 
 <h2>Version 4.6 (1875): 22/01/2014 - Da lec'h all</h2>
diff --git a/html/rest.html b/html/rest.html
index dd12b2ba..03dce661 100644
--- a/html/rest.html
+++ b/html/rest.html
@@ -228,6 +228,28 @@ and value of parameter <i>n</i>.
 </div>
 <p>
 
+<h3><span style="background-color: lightblue;">get</span><a name="get"></a></h3>
+<p>Finds alignment(s) identified by names or pretty name.</p>
+<p>URL: http://aserv.inrialpes.fr/rest/ <b>get</b> ? <b>uri</b> = &lt;URI&gt; </p>
+<p>URL: http://aserv.inrialpes.fr/rest/ <b>get</b> ? <b>desc</b> = &lt;String&gt; </p>
+<p>Parameters:<br />
+ <b>uri</b>  the URI of the alignment (does not need to have the server as prefix),<br />
+ <b>desc</b> a string describing the alignment to be found in the Pretty attribute.
+</p>
+
+<p>Result:<br />
+<div class="xml">
+&lt;getResponse>
+    &lt;msgid> MessageId &lt;/msgid>
+    &lt;in-reply-to> messageId &lt;/in-reply-to>
+    &lt;alignmentList>
+        &lt;alid> URI &lt;/alid> 
+        ...
+    &lt;/alignmentList>
+&lt;/getResponse>
+</div>
+<p>
+
 <h3><span style="background-color: lightblue;">corresp</span><a name="corresp"></a></h3>
 <p>Finds the concepts corresponding to a concept in a particular alignment.</p>
 <p>URL: http://aserv.inrialpes.fr/rest/ <b>corresp</b> ? <b>id</b>
@@ -476,12 +498,13 @@ This function can work in two ways: either with a url parameter
 which contains a publicly accessible URL that the server will use
 for uploading the file, or by using a POST request method, in which
 the alignment is in the message content (e.g., a loadfile java script, see <a href="http://aserv.inrialpes.fr/html/prmload?">here</a>).</p>
-<p>URI: http://aserv.inrialpes.fr/rest/ <b>load</b> ? <b>url</b> = &lt;URL&gt &amp; pretty = &lt;string&gt;</p>
+<p>URI: http://aserv.inrialpes.fr/rest/ <b>load</b> ? <b>url</b> = &lt;URL&gt &amp; pretty = &lt;string&gt; &amp; force = &lt;boolean&gt;</p>
 or
 <p>URI: http://aserv.inrialpes.fr/rest/ <b>load</b> ? pretty = &lt;string&gt;</p>
 <p>Parameters: 
 <br /><b>url:</b> the accessible URL where to find the alignment to upload.
 <br /><b>pretty:</b> a string that will name the resulting alignment.
+<br /><b>force:</b> a boolean (default: false) which forces new registration of the alignment, even if the alignment is already loaded.
 </p>
 <p>Result:<br />
 <div class="xml">
@@ -582,8 +605,6 @@ to be matched.
   someone has a need for them.</p>
 <p>Getting metadata by keys (one by one).</p>
 
-<p>findbyPrettyName for finding elements from their pretty name.</p>
-
 <p>findNetworksWithOntologies for finding network containing
   particular ontologies.</p>
 
diff --git a/src/fr/inrialpes/exmo/align/impl/Annotations.java b/src/fr/inrialpes/exmo/align/impl/Annotations.java
index 7ea2b5a6..80404b72 100644
--- a/src/fr/inrialpes/exmo/align/impl/Annotations.java
+++ b/src/fr/inrialpes/exmo/align/impl/Annotations.java
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Copyright (C) INRIA, 2008-2009
+ * Copyright (C) INRIA, 2008-2009, 2014
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
@@ -32,6 +32,7 @@ public class Annotations {
     public static String PROPERTIES = "properties";
     public static String PRETTY = "pretty";
     public static String PROVENANCE = "provenance";
+    public static String SAMEAS = "sameAs";
 
     /* Set to true for rejecting the use of deprecated (non deterministic) primitives */
     // JE2009: Unrelated to Annotations...
diff --git a/src/fr/inrialpes/exmo/align/impl/Namespace.java b/src/fr/inrialpes/exmo/align/impl/Namespace.java
index dd9a9993..7c070a70 100644
--- a/src/fr/inrialpes/exmo/align/impl/Namespace.java
+++ b/src/fr/inrialpes/exmo/align/impl/Namespace.java
@@ -42,6 +42,7 @@ public enum Namespace {
     XSD("http://www.w3.org/2001/XMLSchema", "xsd", true),
     XSI("http://www.w3.org/1999/XMLSchema-instance", "xsi", false),
     RDF("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdf", false),
+    OWL("http://www.w3.org/2002/07/owl#", "owl", false),
     NONE("", "fake", false),
     ATLMAP("http://www.atl.external.lmco.com/projects/ontology/ResultsOntology.n3#", "map", false);
 
diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
index 6649cf76..8120a37a 100644
--- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
+++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java
@@ -66,6 +66,7 @@ import org.semanticweb.owl.align.AlignmentVisitor;
 import org.semanticweb.owl.align.AlignmentException;
 import org.semanticweb.owl.align.Evaluator;
 import org.semanticweb.owl.align.OntologyNetwork;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -285,8 +286,11 @@ public class AServProtocolManager implements Service {
 	if ( pretty != null && !pretty.equals("") ) {
 	    al.setExtension( Namespace.EXT.uri, Annotations.PRETTY, pretty );
 	}
+	boolean force = false;
+	String rewrite = params.getProperty("force");
+	if ( rewrite != null && !rewrite.equals("") ) force = true;
 	// register it
-	String id = alignmentCache.recordNewAlignment( al, true );
+	String id = alignmentCache.recordNewAlignment( al, force );
 	// if the file has been uploaded: discard it
 	if ( params.getProperty("todiscard") != null ) {
 	    try {
@@ -366,7 +370,7 @@ public class AServProtocolManager implements Service {
 	String onto2 = params.getProperty("onto2");
 	URI uri1 = null;
 	URI uri2 = null;
-	Set<Alignment> alignments = new HashSet<Alignment>();
+	Set<Alignment> alignments = null;
 	try {
 	    if( onto1 != null && !onto1.equals("") ) {
 		uri1 = new URI( onto1 );
@@ -378,11 +382,38 @@ public class AServProtocolManager implements Service {
 	} catch (Exception e) {
 	    return new ErrorMsg( params, newId(), serverId,"MalformedURI problem" );
 	}; //done below
-	String msg = "";
-	String prettys = "";
-	for ( Alignment al : alignments ) {
-	    msg += al.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID )+" ";
-	    prettys += al.getExtension( Namespace.EXT.uri, Annotations.PRETTY )+ ":";
+	String msg = " ";
+	String prettys = ":";
+	if ( alignments != null ) {
+	    for ( Alignment al : alignments ) {
+		msg += al.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID )+" ";
+		prettys += al.getExtension( Namespace.EXT.uri, Annotations.PRETTY )+ ":";
+	    }
+	}
+	return new AlignmentIds( params, newId(), serverId, msg, prettys );
+    }
+
+    // DONE
+    // Implements: query-aligned
+    public Message getAlignments( Properties params ){
+	String uri = params.getProperty("uri");
+	String desc = params.getProperty("desc");
+	Set<Alignment> alignments = null;
+	try {
+	    if ( uri != null && !uri.equals("") ) alignments = alignmentCache.getAlignmentByURI( uri );
+	    if ( desc != null && alignments == null && !desc.equals("") ) { // Then try the description
+		alignments = alignmentCache.getAlignmentsByDescription( desc );
+	    }
+	} catch ( Exception ex ) {
+	    return new ErrorMsg( params, newId(), serverId, "Exception raised" );
+	}; //done below
+	String msg = " ";
+	String prettys = ":";
+	if ( alignments != null ) {
+	    for ( Alignment al : alignments ) {
+		msg += al.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID )+" ";
+		prettys += al.getExtension( Namespace.EXT.uri, Annotations.PRETTY )+ ":";
+	    }
 	}
 	return new AlignmentIds( params, newId(), serverId, msg, prettys );
     }
@@ -1193,8 +1224,8 @@ public class AServProtocolManager implements Service {
     protected String registerNetwork( BasicOntologyNetwork noo, String id ) {
 	String newid = id;
 	if ( id == null ) newid = alignmentCache.recordNewNetwork( noo, true );
-	for (Alignment al : noo.getAlignments() ) {
-	    alignmentCache.recordNewAlignment( al, true );
+	for ( Alignment al : noo.getAlignments() ) {
+	    alignmentCache.recordNewAlignment( al, false );
 	}
 	return newid;
     }
diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentService.java b/src/fr/inrialpes/exmo/align/service/AlignmentService.java
index ab5f98fb..82f64f6c 100644
--- a/src/fr/inrialpes/exmo/align/service/AlignmentService.java
+++ b/src/fr/inrialpes/exmo/align/service/AlignmentService.java
@@ -36,7 +36,6 @@ import org.apache.commons.cli.ParseException;
 
 import java.util.Hashtable;
 import java.util.Vector;
-import java.util.Enumeration;
 import java.util.Properties;
 import java.io.PrintStream;
 import java.io.File;
diff --git a/src/fr/inrialpes/exmo/align/service/Cache.java b/src/fr/inrialpes/exmo/align/service/Cache.java
index a396a679..c3bf06cb 100644
--- a/src/fr/inrialpes/exmo/align/service/Cache.java
+++ b/src/fr/inrialpes/exmo/align/service/Cache.java
@@ -20,7 +20,6 @@
 
 package fr.inrialpes.exmo.align.service;
 
-import java.util.Enumeration;
 import java.util.Collection;
 import java.util.Set;
 import java.util.Properties;
@@ -77,6 +76,12 @@ public interface Cache {
      */
     public Alignment getAlignment( String uri ) throws AlignmentException;
 	
+    /**
+     * retrieve full alignment from URI or description
+     */
+    public Set<Alignment> getAlignmentByURI( String uri ) throws AlignmentException;
+    public Set<Alignment> getAlignmentsByDescription( String desc ) throws AlignmentException;
+	
     /**
      * retrieve network of ontologies from id
      */
diff --git a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
index 0759bdaa..0c1ec0e5 100644
--- a/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
+++ b/src/fr/inrialpes/exmo/align/service/HTMLAServProfile.java
@@ -601,6 +601,7 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    }
 	} else if ( perf.equals("prmfind") ) {
 	    msg ="<h1>Find alignments between ontologies</h1><form action=\"find\">Ontology 1: <input type=\"text\" name=\"onto1\" size=\"80\"/> (uri)<br />Ontology 2: <input type=\"text\" name=\"onto2\" size=\"80\"/> (uri)<br /><small>These are the URI identifying the ontologies. Not those of places where to upload them.</small><br /><input type=\"submit\" name=\"action\" value=\"Find\"/></form>";
+	    msg += "<h1>Find alignments by URIs</h1><form action=\"get\">URI: <input type=\"text\" name=\"uri\" size=\"80\"/> (uri)<br />Description: <input type=\"text\" name=\"desc\" size=\"80\"/> (found in pretty)<br /><input type=\"submit\" name=\"action\" value=\"Get\"/></form>";
 	} else if ( perf.equals("find") ) {
 	    Message answer = manager.existingAlignments( params );
 	    if ( answer instanceof ErrorMsg ) {
@@ -609,6 +610,14 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 		msg = "<h1>Found alignments</h1>";
 		msg += displayAnswer( answer, params );
 	    }
+	} else if ( perf.equals("get") ) {
+	    Message answer = manager.getAlignments( params );
+	    if ( answer instanceof ErrorMsg ) {
+		msg = testErrorMessages( answer, params, eSource );
+	    } else {
+		msg = "<h1>Found alignments</h1>";
+		msg += displayAnswer( answer, params );
+	    }
 	} else if ( perf.equals("corresp") ) {
 	    Message answer = manager.findCorrespondences( params );
 	    if ( answer instanceof ErrorMsg ) {
@@ -658,13 +667,16 @@ public class HTMLAServProfile implements AlignmentServiceProfile {
 	    // Alignment in HTML can be rendre or metadata+tuples
 	} else if ( perf.equals("prmload") ) {
 	    // Should certainly be good to offer store as well
-	    msg = "<h1>Load an alignment</h1><form action=\"load\">Alignment URL: <input type=\"text\" name=\"url\" size=\"80\"/> (uri)<br /><small>This is the URL of the place where to find this alignment. It must be reachable by the server (i.e., file:// URI is acceptable if it is on the server).</small><br />Pretty name: <input type=\"text\" name=\"pretty\" size=\"80\"/><br /><input type=\"submit\" value=\"Load\"/></form>";
+	    msg = "<h1>Load an alignment</h1><form action=\"load\">Alignment URL: <input type=\"text\" name=\"url\" size=\"80\"/> (uri)<br /><small>This is the URL of the place where to find this alignment. It must be reachable by the server (i.e., file:// URI is acceptable if it is on the server).</small><br />Pretty name: <input type=\"text\" name=\"pretty\" size=\"80\"/><br />";
+	    msg += "<input type=\"checkbox\" name=\"force\" /> Force <br />";
+	    msg += "<input type=\"submit\" value=\"Load\"/></form>";
 	    //msg += "Alignment file: <form ENCTYPE=\"text/xml; charset=utf-8\" action=\"loadfile\" method=\"POST\">";
 	    msg += "Alignment file: <form enctype=\"multipart/form-data\" action=\"load\" method=\"POST\">";
 	    msg += "<input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\""+MAX_FILE_SIZE+"\"/>";
 	    msg += "<input name=\"content\" type=\"file\" size=\"35\">";
 	    msg += "<br /><small>NOTE: Max file size is "+(MAX_FILE_SIZE/1024)+"KB; this is experimental but works</small><br />";
 	    msg += "Pretty name: <input type=\"text\" name=\"pretty\" size=\"80\"/><br />";
+	    msg += "<input type=\"checkbox\" name=\"force\" /> Force <br />";
 	    msg += "<input type=\"submit\" Value=\"Upload\">";
 	    msg +=  " </form>";
 	} else if ( perf.equals("load") ) {
diff --git a/src/fr/inrialpes/exmo/align/service/SQLCache.java b/src/fr/inrialpes/exmo/align/service/SQLCache.java
index b8d412c7..356398fb 100644
--- a/src/fr/inrialpes/exmo/align/service/SQLCache.java
+++ b/src/fr/inrialpes/exmo/align/service/SQLCache.java
@@ -24,6 +24,7 @@ package fr.inrialpes.exmo.align.service;
 import java.util.Vector;
 import java.util.Date;
 import java.util.Properties;
+import java.util.Map.Entry;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.sql.Connection;
@@ -564,10 +565,12 @@ public class SQLCache extends VolatilCache implements Cache {
 			}
 		    }
 		    // URIINdex: store alternative URIs
-		    // For all alt URIs stored who knows where
-		    // Deal with prefs
-		    //query = "INSERT INTO alignmenturis "+"(id, uri) VALUES ("+quote(id)+","+quote(turi)+");";
-		    //st.executeUpdate(query);
+		    for ( Entry<String,Alignment> entry : alignmentURITable.entrySet() ) {
+			if ( entry.getValue() == alignment ) {
+			    query = "INSERT INTO alignmenturis "+"(id, uri,prefered) VALUES ("+quote(entry.getKey())+","+quote(id)+",false);";
+			    st.executeUpdate(query);
+			}
+		    }
 		    st.close();
 		} catch ( SQLException sqlex ) {
 		    logger.warn( "SQLError", sqlex );
diff --git a/src/fr/inrialpes/exmo/align/service/VolatilCache.java b/src/fr/inrialpes/exmo/align/service/VolatilCache.java
index 6c56a667..d1258a73 100644
--- a/src/fr/inrialpes/exmo/align/service/VolatilCache.java
+++ b/src/fr/inrialpes/exmo/align/service/VolatilCache.java
@@ -22,7 +22,6 @@ package fr.inrialpes.exmo.align.service;
 
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Vector;
 import java.util.Collection;
@@ -128,7 +127,32 @@ public class VolatilCache implements Cache {
     public Collection<OntologyNetwork> ontologyNetworks() {
     	return onetworkTable.values();
     }
-        
+
+    /**
+     * Find alignments by URI
+     */
+    public Set<Alignment> getAlignmentByURI( String uri ) {
+	Set<Alignment> result = null;
+	Alignment al = alignmentTable.get( uri );
+	if ( al == null ) al = alignmentURITable.get( uri );
+	if ( al != null ) {
+	    result = new HashSet<Alignment>();
+	    result.add( al );
+	}
+	return result;
+    }
+
+    /**
+     * Find alignments by pretty
+     * NOT IMPLEMENTED YET
+     */
+    public Set<Alignment> getAlignmentsByDescription( String desc ) {
+	return null;
+    }
+
+    /**
+     * Find alignments by ontology URIs
+     */
     public Set<Alignment> getAlignments( URI uri ) {
 	return ontologyTable.get( uri );
     }
@@ -269,17 +293,6 @@ public class VolatilCache implements Cache {
 	return result;
     }
 
-    // URIINdex:
-    public Alignment findAlignment( String uri ) throws AlignmentException {
-	Alignment result = null;
-	try {
-	    result = getAlignment( uri );
-	} catch (AlignmentException alex) {
-	    result = alignmentURITable.get( uri );
-	}
-	return result;
-    }
-
     /**
      * retrieve full alignment from id (and cache it)
      */
@@ -375,9 +388,21 @@ public class VolatilCache implements Cache {
 
     /**
      * records alignment identified by id
+     * force will register the new alignment even if it is already registered
      */
     public String recordAlignment( String uri, Alignment alignment, boolean force ) {
 	// URIINdex: if this guy already has a URI, record in table
+	String uriref = alignment.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID );
+	if ( uriref != null && !uriref.equals("") ) {
+	    Alignment altal = alignmentURITable.get( uriref );
+	    if ( altal == null || force ) {
+		alignmentURITable.put( uriref, alignment );
+		alignment.setExtension( Namespace.OWL.uri, Annotations.SAMEAS, uriref );
+	    } else { // An alignment carrying this URI is already here
+		String olduri = altal.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID );
+		return olduri;
+	    }
+	}
 	// record the Alignment at the corresponding Uri in tables!
 	alignment.setExtension( Namespace.ALIGNMENT.uri, Annotations.ID, uri );
 
@@ -422,6 +447,11 @@ public class VolatilCache implements Cache {
 	}
 	alignmentTable.remove( id );
 	// URIINdex: should remove all entries pointing to it
+	Set<String> toDelete = new HashSet<String>();
+	for ( Entry<String,Alignment> entry : alignmentURITable.entrySet() ) {
+	    if ( entry.getValue() == alignment ) toDelete.add( entry.getKey() );
+	}
+	for ( String u : toDelete ) alignmentURITable.remove( u );
     }
 
     //**********************************************************************
diff --git a/src/fr/inrialpes/exmo/align/service/WSAServProfile.java b/src/fr/inrialpes/exmo/align/service/WSAServProfile.java
index 569baec3..bda369c3 100644
--- a/src/fr/inrialpes/exmo/align/service/WSAServProfile.java
+++ b/src/fr/inrialpes/exmo/align/service/WSAServProfile.java
@@ -502,6 +502,13 @@ public class WSAServProfile implements AlignmentServiceProfile {
 		answer = manager.existingAlignments( newparameters );
             }
 	    msg += render( "findResponse", answer, param.getProperty("returnType"), newparameters);
+	} else if ( method.equals("getRequest") || method.equals("get") ) { // URI | String -> List of URI
+	    if ( newparameters.getProperty( "uri" ) == null || newparameters.getProperty( "desc" ) == null ) {
+		answer = new NonConformParameters(0,(Message)null,myId,"",message,(Properties)null);
+	    } else {
+		answer = manager.getAlignments( newparameters );
+            }
+	    msg += render( "getResponse", answer, param.getProperty("returnType"), newparameters);
 	} else if ( method.equals("evalRequest") || method.equals("eval") ) { // URI * URI -> List of URI
 	    if ( newparameters.getProperty( "id" ) == null ) {
 		answer = new NonConformParameters(0,(Message)null,myId,"",message,(Properties)null);
diff --git a/src/fr/inrialpes/exmo/align/service/aserv.wsdl b/src/fr/inrialpes/exmo/align/service/aserv.wsdl
index 60efab34..5836d223 100644
--- a/src/fr/inrialpes/exmo/align/service/aserv.wsdl
+++ b/src/fr/inrialpes/exmo/align/service/aserv.wsdl
@@ -234,6 +234,14 @@
      <wsdl:part name="alignmentList" type="alignmentList"/>
    </wsdl:message>
 
+   <wsdl:message name="getRequest">
+      <wsdl:part name="uri" type="xsd:anyURI"/>
+      <wsdl:part name="desc" type="xsd:string"/>
+   </wsdl:message>
+   <wsdl:message name="getResponse">
+     <wsdl:part name="alignmentList" type="alignmentList"/>
+   </wsdl:message>
+
    <wsdl:message name="evalRequest">
       <wsdl:part name="id" type="xsd:anyURI"/>
       <wsdl:part name="ref" type="xsd:anyURI"/>
@@ -247,6 +255,7 @@
    <wsdl:message name="loadRequest"> <!--xsd:choice OR better multipart-->
      <wsdl:part name="url" type="xsd:string"/>
      <wsdl:part name="pretty" type="xsd:string"/>
+     <wsdl:part name="force" type="xsd:boolean"/>
      <wsdl:part name="param" type="param"/> <!-- minOccurs="0" maxOccurs="unbounded" ?-->
    </wsdl:message>
    <wsdl:message name="loadResponse">
@@ -322,11 +331,15 @@
        <wsdl:input message="impl:findRequest" name="findRequest"/>
        <wsdl:output message="impl:findResponse" name="findResponse"/>
      </wsdl:operation>
+     <wsdl:operation name="get" parameterOrder="uri pretty">
+       <wsdl:input message="impl:getRequest" name="getRequest"/>
+       <wsdl:output message="impl:getResponse" name="getResponse"/>
+     </wsdl:operation>
      <wsdl:operation name="eval" parameterOrder="id ref method">
        <wsdl:input message="impl:evalRequest" name="evalRequest"/>
        <wsdl:output message="impl:evalResponse" name="evalResponse"/>
      </wsdl:operation>
-     <wsdl:operation name="load" parameterOrder="url pretty">
+     <wsdl:operation name="load" parameterOrder="url pretty force">
        <wsdl:input message="impl:loadRequest" name="loadRequest"/>
        <wsdl:output message="impl:loadResponse" name="loadResponse"/>
      </wsdl:operation>
@@ -489,6 +502,17 @@
 			namespace="urn:http://exmo.inrialpes.fr/align/service" use="encoded"/>
        </wsdl:output>
      </wsdl:operation>
+     <wsdl:operation name="get">
+       <wsdlsoap:operation soapAction=""/>
+       <wsdl:input name="getRequest">
+         <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+			namespace="urn:http://exmo.inrialpes.fr/align/service" use="encoded"/>
+       </wsdl:input>
+       <wsdl:output name="getResponse">
+         <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
+			namespace="urn:http://exmo.inrialpes.fr/align/service" use="encoded"/>
+       </wsdl:output>
+     </wsdl:operation>
      <wsdl:operation name="eval">
        <wsdlsoap:operation soapAction=""/>
        <wsdl:input name="evalRequest">
-- 
GitLab