From 9415c7f3f17a18bab36d1115e28cf276c7f55378 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr> Date: Sat, 10 Feb 2007 20:46:32 +0000 Subject: [PATCH] - Modified the database schema (larger size -- exceded in some example) - protected (quote) database assertions - added initDatabase, resetDatabase and first updateDatabase - rewrote all sql statements in uppercase - added version attribute and stored in database - added log in the database of the server and check it before reset - added copyright notice for the RTSI snippet and JWhich --- .../align/service/AServProtocolManager.java | 78 ++++---- .../exmo/align/service/AlignmentService.java | 5 +- .../inrialpes/exmo/align/service/Cache.java | 5 +- .../exmo/align/service/CacheImpl.java | 179 ++++++++++++++++-- .../exmo/align/service/DBServiceImpl.java | 6 +- .../inrialpes/exmo/align/service/dbschema.sql | 65 ------- 6 files changed, 209 insertions(+), 129 deletions(-) delete mode 100644 src/fr/inrialpes/exmo/align/service/dbschema.sql diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java index a96abcc1..df41696b 100644 --- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java +++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java @@ -16,6 +16,37 @@ * 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. + * + * A small part of this class (within the implementations() method) is: + * Copyright (C) Daniel Le Berre, 2001 + * from his util.RTSI class + * which contains a few lines: + * Copyright (C) 2002-2005, FullSpan Software + * under BSD licence + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of FullSpan Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. */ package fr.inrialpes.exmo.align.service; @@ -31,7 +62,6 @@ import org.semanticweb.owl.align.AlignmentProcess; import org.semanticweb.owl.align.AlignmentVisitor; import org.semanticweb.owl.align.AlignmentException; -//*/3.0 import org.semanticweb.owl.util.OWLManager; import org.semanticweb.owl.model.OWLOntology; import org.semanticweb.owl.model.OWLException; @@ -96,9 +126,9 @@ public class AServProtocolManager { public void init( DBService connection, Parameters p ) throws SQLException { alignmentCache = new CacheImpl( connection ); - alignmentCache.init(); + alignmentCache.init( p ); // dummy string - myId = "localhost://alignserv"; + myId = "http://"+p.getParameter("host")+":"+p.getParameter("port"); renderers = implementations( "org.semanticweb.owl.align.AlignmentVisitor" ); methods = implementations( "org.semanticweb.owl.align.AlignmentProcess" ); methods.remove("fr.inrialpes.exmo.align.impl.DistanceAlignment"); // this one is generic @@ -121,6 +151,8 @@ public class AServProtocolManager { } public void close() { + try { alignmentCache.close(); } + catch (SQLException sqle) { sqle.printStackTrace(); } } private int newId() { return localId++; } @@ -195,17 +227,11 @@ public class AServProtocolManager { if ( params.getParameter("init") != null && !params.getParameter("init").equals("") ) { try { //if (debug > 0) System.err.println(" Retrieving init"); - //AlignmentParser aparser = new AlignmentParser(0); - //init = aparser.parse((String)params.getParameter("init"), loadedOntologies); try { init = alignmentCache.getAlignment( (String)params.getParameter("init") ); } catch (Exception e) { return new UnknownAlignment(newId(),mess,myId,mess.getSender(),(String)params.getParameter("init"),(Parameters)null); } - // Not really useful - //onto1 = (OWLOntology)init.getOntology1(); - //onto2 = (OWLOntology)init.getOntology2(); - //if (debug > 0) System.err.println(" Init retrieved"); } catch (Exception e) { return new UnknownAlignment(newId(),mess,myId,mess.getSender(),(String)params.getParameter("init"),(Parameters)null); } @@ -241,8 +267,6 @@ public class AServProtocolManager { if ( method == null ) method = "fr.inrialpes.exmo.align.impl.method.StringDistAlignment"; Class alignmentClass = Class.forName(method); - //Class oClass = Class.forName("org.semanticweb.owl.model.OWLOntology"); - //Class[] cparams = { oClass, oClass }; Class[] cparams = {}; java.lang.reflect.Constructor alignmentConstructor = alignmentClass.getConstructor(cparams); AlignmentProcess result = (AlignmentProcess)alignmentConstructor.newInstance(mparams); @@ -295,31 +319,13 @@ public class AServProtocolManager { } catch (Exception e) { return new ErrorMsg(newId(),mess,myId,mess.getSender(),"MalformedURI problem",(Parameters)null); }; //done below - // This useless and is done only for launching the error - //OWLOntology onto1 = reachable( uri1 ); - //OWLOntology onto2 = reachable( uri2 ); - //if ( onto1 == null ){ - // Unreachable - // return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto1"),(Parameters)null); - //} else if ( onto2 == null ){ - // return new UnreachableOntology(newId(),mess,myId,mess.getSender(),(String)params.getParameter("onto2"),(Parameters)null); - //} else { - // try { - // find it - // Set alignments = alignmentCache.getAlignments( onto1.getLogicalURI(), onto2.getLogicalURI() ); - Set alignments = alignmentCache.getAlignments( uri1, uri2 ); - String msg = ""; - for( Iterator it = alignments.iterator(); it.hasNext(); ){ - //ids.put( ((Alignment)it.next()).getExtension( "id" ) ); - msg += ((Alignment)it.next()).getExtension( "id" ); - msg += " "; - } - return new AlignmentIds(newId(),mess,myId,mess.getSender(),msg,(Parameters)null); - // } catch (Exception e) { // URI problems in gLU - //e.printStackTrace(); - //return new ErrorMsg(newId(),mess,myId,mess.getSender(),"getlogicalURI problem on the ontologies",(Parameters)null); - //} - //} + Set alignments = alignmentCache.getAlignments( uri1, uri2 ); + String msg = ""; + for( Iterator it = alignments.iterator(); it.hasNext(); ){ + msg += ((Alignment)it.next()).getExtension( "id" ); + msg += " "; + } + return new AlignmentIds(newId(),mess,myId,mess.getSender(),msg,(Parameters)null); } // ABSOLUTELY NOT IMPLEMENTED diff --git a/src/fr/inrialpes/exmo/align/service/AlignmentService.java b/src/fr/inrialpes/exmo/align/service/AlignmentService.java index 4897ca03..3763552a 100644 --- a/src/fr/inrialpes/exmo/align/service/AlignmentService.java +++ b/src/fr/inrialpes/exmo/align/service/AlignmentService.java @@ -137,14 +137,15 @@ public class AlignmentService { // Close services for ( Enumeration e = services.elements() ; e.hasMoreElements() ; ) { AlignmentServiceProfile serv = (AlignmentServiceProfile)e.nextElement(); - try { serv.close(); - } catch ( AServException ex ) { + try { serv.close(); } + catch ( AServException ex ) { System.err.println("Cannot close "+serv); ex.printStackTrace(); } } // Shut down database connection + manager.close(); connection.close(); if ( debug > 0 ) System.err.println("Database connection closed"); } diff --git a/src/fr/inrialpes/exmo/align/service/Cache.java b/src/fr/inrialpes/exmo/align/service/Cache.java index 66653bdf..1cd16144 100644 --- a/src/fr/inrialpes/exmo/align/service/Cache.java +++ b/src/fr/inrialpes/exmo/align/service/Cache.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) XX, 2006 + * Copyright (C) Seungkeun Lee, 2006 * Copyright (C) INRIA Rh�ne-Alpes, 2006-2007 * * This program is free software; you can redistribute it and/or @@ -27,9 +27,10 @@ import java.sql.SQLException; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; +import org.semanticweb.owl.align.Parameters; public interface Cache { - void init() throws SQLException; + void init( Parameters p ) throws SQLException; Alignment getMetadata( String id ) throws Exception; Alignment getAlignment( String id ) throws Exception; Set getAlignments( URI uri ); diff --git a/src/fr/inrialpes/exmo/align/service/CacheImpl.java b/src/fr/inrialpes/exmo/align/service/CacheImpl.java index 10344629..650b4abd 100644 --- a/src/fr/inrialpes/exmo/align/service/CacheImpl.java +++ b/src/fr/inrialpes/exmo/align/service/CacheImpl.java @@ -45,6 +45,7 @@ import fr.inrialpes.exmo.align.impl.URICell; import org.semanticweb.owl.align.Alignment; import org.semanticweb.owl.align.AlignmentException; import org.semanticweb.owl.align.Cell; +import org.semanticweb.owl.align.Parameters; /** * This class caches the content of the alignment database. I.e., @@ -56,7 +57,13 @@ import org.semanticweb.owl.align.Cell; public class CacheImpl implements Cache { Hashtable alignmentTable = null; Hashtable ontologyTable = null; + + String host = null; + String port = null; + int rights = 1; // writing rights in the database (default is 1) + final int VERSION = 300; // Version of the API to be stored in the database + Statement st = null; ResultSet rs = null; Connection conn = null; @@ -82,11 +89,25 @@ public class CacheImpl implements Cache { * loads the alignment descriptions from the database and put them in the * alignmentTable hashtable */ - public void init() throws SQLException { + public void init( Parameters p ) throws SQLException { + port = (String)p.getParameter("http"); // bad idea + host = (String)p.getParameter("host"); + // test if a database is here, otherwise create it + rs = (ResultSet)st.executeQuery("SHOW TABLES LIKE 'server'"); + if ( !rs.next() ) initDatabase(); + // register by the database + st.executeUpdate("INSERT INTO server (host, port, edit, version) VALUES ('"+host+"','"+port+"','"+rights+"',"+VERSION+")"); + // load alignment descriptions loadAlignments( true ); } - //********************************************************************** + public void close() throws SQLException { + // unregister by the database + st.executeUpdate("DELETE FROM server WHERE host='"+host+"' AND port='"+port+"'"); + } + + // ********************************************************************** + // LOADING FROM DATABASE /** * loads the alignment descriptions from the database and put them in the * alignmentTable hashtable @@ -110,8 +131,7 @@ public class CacheImpl implements Cache { if (force) { // Retrieve the alignment ids - query = "select id " + "from alignment"; - rs = (ResultSet) st.executeQuery(query); + rs = (ResultSet) st.executeQuery("SELECT id FROM alignment"); while(rs.next()) { id = rs.getString("id"); idInfo.add(id); @@ -143,7 +163,7 @@ public class CacheImpl implements Cache { try { // Get basic ontology metadata - query = "select * from alignment where id = '" + id +"'"; + query = "SELECT * FROM alignment WHERE id = '" + id +"'"; rs = (ResultSet) st.executeQuery(query); while(rs.next()) { // Either uri1 or file1 @@ -156,7 +176,7 @@ public class CacheImpl implements Cache { } // Get extension metadata - query = "select * from extension where id = '" + id + "'"; + query = "SELECT * FROM extension WHERE id = '" + id + "'"; rs = (ResultSet) st.executeQuery(query); while(rs.next()) { tag = rs.getString("tag"); @@ -193,7 +213,7 @@ public class CacheImpl implements Cache { result.setOntology2( new URI( result.getExtension( "ouri2" ) ) ); // Get cells - query = "select * from cell where id = '" + id + "'"; + query = "SELECT * FROM cell WHERE id = '" + id + "'"; rs = (ResultSet) st.executeQuery(query); while(rs.next()) { ent1 = new URI(rs.getString("uri1")); @@ -213,11 +233,7 @@ public class CacheImpl implements Cache { private String generateAlignmentId() { // Generate an id based on a URI prefix + Date + random number - Date date; - String id; - date = new Date(); - id = "http://localhost:8089/" + date.getTime() + "/" + randomNum(); - return id; + return "http://"+host+":"+port+"/alid/" + new Date().getTime() + "/" + randomNum(); } private int randomNum() { @@ -226,6 +242,7 @@ public class CacheImpl implements Cache { } //********************************************************************** + // FETCHING FROM CACHE /** * retrieve alignment metadata from id * This is more difficult because we return the alignment we have @@ -233,10 +250,8 @@ public class CacheImpl implements Cache { */ public Alignment getMetadata( String id ) throws Exception { Alignment result = (Alignment)alignmentTable.get( id ); - if ( result == null ) throw new Exception("getMetadata: Cannot find alignment"); - return result; } @@ -258,7 +273,6 @@ public class CacheImpl implements Cache { return result; } - //********************************************************************** public Set getAlignments( URI uri ) { return (Set)ontologyTable.get( uri ); } @@ -277,6 +291,8 @@ public class CacheImpl implements Cache { return result; } + //********************************************************************** + // RECORDING ALIGNMENTS /** * records newly created alignment */ @@ -336,6 +352,36 @@ public class CacheImpl implements Cache { } //********************************************************************** + // STORING IN DATABASE + /** + * quote: + * Prepare a string to be used in SQL queries by preceeding occurences of + * "'", """, and "\" by a "\". + * This should be implemented at a lower level within Java itself + * (or the sql package). + * This function is used here for protecting everything to be entered in + * the database + */ + public String quote( String s ) { + String result = null; + char[] chars = s.toCharArray(); + int j = 0; + int i = 0; + char c; + for ( ; i < chars.length; i++ ){ + c = chars[i]; + if ( c == '\'' || c == '"' || c == '\\' ) { + result += new String( chars, j, i-j ) + "\\" + c; + j = i+1; + }; + } + if ( result != null ) { + return result + new String( chars, j, i-j ); + } else { + return s; + } + } + public void storeAlignment( String id ) throws Exception { String query = null; Alignment alignment = null; @@ -366,16 +412,16 @@ public class CacheImpl implements Cache { String type = alignment.getType(); String level = alignment.getLevel(); - query = "insert into alignment " + + query = "INSERT INTO alignment " + "(id, owlontology1, owlontology2, type, level, file1, file2, uri1, uri2) " + - "values ('" + id + "','" + s_O1 + "','" + s_O2 + "','" + type + "','" + level + "','" + s_File1 + "','" + s_File2 + "','" + s_uri1 + "','" + s_uri2 + "')"; + "VALUES ('" + quote(id) + "','" + quote(s_O1) + "','" + quote(s_O2) + "','" + quote(type) + "','" + quote(level) + "','" + quote(s_File1) + "','" + quote(s_File2) + "','" + quote(s_uri1) + "','" + quote(s_uri2) + "')"; st.executeUpdate(query); for( Enumeration e = alignment.getExtensions().getNames() ; e.hasMoreElements() ; ){ String tag = (String)e.nextElement(); String s_method = alignment.getExtension(tag); - query = "insert into extension " + + query = "INSERT INTO extension " + "(id, tag, method) " + - "values ('" + id + "','" + tag + "','" + s_method + "')"; + "VALUES ('" + quote(id) + "','" + quote(tag) + "','" + quote(s_method) + "')"; st.executeUpdate(query); } @@ -394,9 +440,9 @@ public class CacheImpl implements Cache { temp[4] = c.getSemantics(); else temp[4] = ""; temp[5] = ((BasicRelation)c.getRelation()).getRelation(); - query = "insert into cell " + + query = "INSERT INTO cell " + "(id, cell_id, uri1, uri2, measure, semantics, relation) " + - "values ('" + id + "','" + temp[0] + "','" + temp[1] + "','" + temp[2] + "','" + temp[3] + "','" + temp[4] + "','" + temp[5] + "')"; + "VALUES ('" + quote(id) + "','" + quote(temp[0]) + "','" + quote(temp[1]) + "','" + quote(temp[2]) + "','" + quote(temp[3]) + "','" + quote(temp[4]) + "','" + quote(temp[5]) + "')"; st.executeUpdate(query); } } @@ -406,6 +452,7 @@ public class CacheImpl implements Cache { } //********************************************************************** + // CACHE MANAGEMENT (Not implemented yet) public void resetCacheStamp( Alignment result ){ result.setExtension("fr.inrialpes.exmo.align.service.cached", new Date().toString() ); } @@ -418,4 +465,94 @@ public class CacheImpl implements Cache { // - clean up cells // } } + + // ********************************************************************** + // DATABASE CREATION AND UPDATING + /* + # server info + + create table server ( + host varchar(50), + port varchar(5), + edit varchar(5) + ); + + + # alignment info + + create table alignment ( + id varchar(100), + owlontology1 varchar(250), + owlontology2 varchar(250), + type varchar(5), + level varchar(1), + file1 varchar(250), + file2 varchar(250), + uri1 varchar(250), + uri2 varchar(250)); + + # cell info + + create table cell( + id varchar(100), + cell_id varchar(250), + uri1 varchar(250), + uri2 varchar(250), + semantics varchar(30), + measure varchar(20), + relation varchar(5)); + + # extension info + + create table extension( + id varchar(100), + tag varchar(100), + method varchar(500)); + + */ + + public void initDatabase() throws SQLException { + // Create tables + st.executeUpdate("CREATE TABLE alignment (id VARCHAR(100), owlontology1 VARCHAR(250), owlontology2 VARCHAR(250), type VARCHAR(5), level VARCHAR(1), file1 VARCHAR(250), file2 VARCHAR(250), uri1 VARCHAR(250), uri2 VARCHAR(250))"); + st.executeUpdate("CREATE TABLE cell(id VARCHAR(100), cell_id VARCHAR(250), uri1 VARCHAR(250), uri2 VARCHAR(250), semantics VARCHAR(30), measure VARCHAR(20), relation VARCHAR(5))"); + st.executeUpdate("CREATE TABLE extension(id VARCHAR(100), tag VARCHAR(100), method VARCHAR(500))"); + st.executeUpdate("CREATE TABLE server (host VARCHAR(50), port VARCHAR(5), edit BOOLEAN, version VARCHAR(5))"); + st.executeUpdate("INSERT INTO server (host, port, edit, version) VALUES ('dbms', 'port', 0, '"+VERSION+"')"); + } + + public void resetDatabase( boolean force ) throws SQLException, AlignmentException { + // Check that no one else is connected... + if ( force != true ){ + ResultSet rs = (ResultSet) st.executeQuery("SELECT COUNT(*) AS rowcount FROM server WHERE edit=1"); + rs.next(); + int count = rs.getInt("rowcount") ; + rs.close() ; + if ( count > 1 ) { + throw new AlignmentException("Cannot init database: other processes use it"); + } + } + // Suppress old database if exists + st.executeUpdate("DROP TABLE IF EXISTS server"); + st.executeUpdate("DROP TABLE IF EXISTS alignment"); + st.executeUpdate("DROP TABLE IF EXISTS cell"); + st.executeUpdate("DROP TABLE IF EXISTS extension"); + // Redo it + initDatabase(); + // Register this server, etc. characteristics (incl. version name) + st.executeUpdate("INSERT INTO server (host, port, edit, version) VALUES ('"+host+"','"+port+"','"+rights+"',"+VERSION+")"); + } + + public void updateDatabase( ) throws SQLException, AlignmentException { + // get the version number + ResultSet rs = (ResultSet) st.executeQuery("SELECT version FROM server WHERE port='port'"); + rs.next(); + int version = rs.getInt("version") ; + if ( version <= VERSION ) { + throw new AlignmentException("Database must be upgraded ("+version+" -> "+VERSION+")"); + // In theory it is possible to: + // - fully load all the database + // - resetDatabase( false ); + // - completely save the database + } + } } diff --git a/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java b/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java index d7ddd5d0..f914a963 100644 --- a/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java +++ b/src/fr/inrialpes/exmo/align/service/DBServiceImpl.java @@ -53,15 +53,15 @@ public class DBServiceImpl implements DBService{ } public void connect( String password ) throws SQLException { - connect( IPAddress, port, user, password ); + connect( IPAddress, port, user, password, database ); } public void connect( String user, String password ) throws SQLException { - connect( IPAddress, port, user, password ); + connect( IPAddress, port, user, password, database ); } public void connect( String port, String user, String password ) throws SQLException { - connect( IPAddress, port, user, password ); + connect( IPAddress, port, user, password, database ); } public void connect(String IPAddress, String port, String user, String password ) throws SQLException { diff --git a/src/fr/inrialpes/exmo/align/service/dbschema.sql b/src/fr/inrialpes/exmo/align/service/dbschema.sql deleted file mode 100644 index a3dd3761..00000000 --- a/src/fr/inrialpes/exmo/align/service/dbschema.sql +++ /dev/null @@ -1,65 +0,0 @@ -# -# Create the database. If you change any value here, report -# the changes in the DBInfo.php file. -# - -CREATE DATABASE AServDB; - -# -# Create a MySQL user. Change 'localhost' to the name of the server -# that hosts MySQL. -# - -GRANT ALL PRIVILEGES ON AServDB.* TO adminAServ@localhost - IDENTIFIED BY 'aaa345'; - -# -# Create a MySQL user with restricted right for SQL queries -# - -GRANT select ON AServ.* TO alignserver@localhost IDENTIFIED BY 'adf342'; - -connect AServDB; - -# server info - -create table server ( - host varchar(50), - port varchar(5), - edit varchar(5) -); - - -# alignment info - -create table alignment ( - id varchar(100), - owlontology1 varchar(100), - owlontology2 varchar(100), - type varchar(5), - level varchar(1), - file1 varchar(100), - file2 varchar(100), - uri1 varchar(100), - uri2 varchar(100)); - - -# cell info - -create table cell( - id varchar(100), - cell_id varchar(20), - uri1 varchar(100), - uri2 varchar(100), - semantics varchar(30), - measure varchar(20), - relation varchar(5)); - - -# extension info - -create table extension( - id varchar(100), - tag varchar(100), - method varchar(500)); - -- GitLab