diff --git a/html/relnotes.html b/html/relnotes.html index 2704cdccff307dd963e5614b03a5d10df8bffb81..10fcd2b98c4b907af86dd26d8fc510b83497e55f 100644 --- a/html/relnotes.html +++ b/html/relnotes.html @@ -38,7 +38,6 @@ The development of 4 versions continues. <p><ul compact="1"> <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>Implement metadata edition (serv)</li> <li>Add simple "harder" test generator (gen)</li> @@ -66,12 +65,13 @@ The default type of StringDistAlignment should be reverted to "**" with a warning: --> -<!--h2>Version 4.9 (1xxx): ??/??/201X - Letraset</h2--> -<!--h2>Version 4.8 (1xxx): ??/??/201x - AntÊsine</h2--> +<!--h2>Version 4.9 (2xxx): ??/??/201X - Letraset</h2--> +<!--h2>Version 4.8 (2xxx): ??/??/2015 - Antésine</h2--> <p><ul compact="1"> <li>Added interface <tt>AlignmentRepairer</tt> (api)</tt> <li>Implemented <tt>AbstractRepairer</tt> (impl)</tt> +<li>Implement database store for EDOAL (serv)</li> </ul></p> <h2>Version 4.7 (2014): 06/12/2014 - Al pesto</h2> diff --git a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java index d6c2c2fdda8990b45ce600cf86ea8a4d2ece5b87..dc7db1d3cbdc590820965217c934369d61616217 100644 --- a/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java +++ b/src/fr/inrialpes/exmo/align/impl/edoal/Comparator.java @@ -1,7 +1,7 @@ /* * $Id$ * - * Copyright (C) INRIA, 2009-2010, 2012 + * Copyright (C) INRIA, 2009-2010, 2012, 2015 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -29,7 +29,6 @@ public class Comparator { URI uri = null; - // This replaces the Comparator class // SHOULD CERTAINLY BE AN ENUM public static Comparator EQUAL = initComparator( Namespace.EDOAL.prefix+"equals", 0 ); public static Comparator LOWER = initComparator( Namespace.EDOAL.prefix+"lower-than", -1 ); @@ -66,4 +65,10 @@ public class Comparator { return uri; } + public boolean equals ( Object ob ) { + if ( ob == this ) return true; + else if ( !(ob instanceof Comparator) ) return false; + else return uri.equals( ((Comparator)ob).getURI() ); + } + } diff --git a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java index 0811176a89ebc89676b9a18cb4aba41916616e55..b2506904df2ebe0b3dbbacf376af0548d09060be 100644 --- a/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java +++ b/src/fr/inrialpes/exmo/align/service/AServProtocolManager.java @@ -52,6 +52,7 @@ import fr.inrialpes.exmo.align.service.msg.UnknownOntologyNetwork; import fr.inrialpes.exmo.align.service.msg.UnreachableAlignment; import fr.inrialpes.exmo.align.service.msg.UnreachableOntology; import fr.inrialpes.exmo.align.service.msg.CannotRenderAlignment; +import fr.inrialpes.exmo.align.service.msg.CannotStoreAlignment; import fr.inrialpes.exmo.align.service.msg.UnreachableOntologyNetwork; import fr.inrialpes.exmo.ontowrap.OntologyFactory; @@ -507,6 +508,7 @@ public class AServProtocolManager implements Service { al = alignmentCache.getAlignment( id ); logger.trace("Alignment found"); } catch (Exception e) { + logger.debug( "Alignment {} not found", id, e ); return new UnknownAlignment( params, newId(), serverId,id ); } // Render it @@ -554,18 +556,16 @@ public class AServProtocolManager implements Service { public Message store( Properties params ) { String id = params.getProperty("id"); Alignment al = null; - try { try { al = alignmentCache.getAlignment( id ); - } catch(Exception ex) { + } catch( Exception ex ) { logger.warn( "Unknown Id {} in Store", id ); + return new UnknownAlignment( params, newId(), serverId, id ); } // Be sure it is not already stored if ( !alignmentCache.isAlignmentStored( al ) ) { - alignmentCache.storeAlignment( id ); - // Retrieve the alignment again al = alignmentCache.getAlignment( id ); // for all directories... @@ -581,8 +581,9 @@ public class AServProtocolManager implements Service { // Could also be an AlreadyStoredAlignment error return new AlignmentId( params, newId(), serverId, id, al.getExtension( Namespace.EXT.uri, Annotations.PRETTY )); - } catch (Exception e) { - return new UnknownAlignment( params, newId(), serverId,id ); + } catch ( Exception ex ) { + logger.debug( "Impossible storage ", ex ); + return new CannotStoreAlignment( params, newId(), serverId, id ); } } diff --git a/src/fr/inrialpes/exmo/align/service/EDOALSQLCache.java b/src/fr/inrialpes/exmo/align/service/EDOALSQLCache.java new file mode 100644 index 0000000000000000000000000000000000000000..b152b3b9053e23ae29719fab469a2204a19431f0 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/service/EDOALSQLCache.java @@ -0,0 +1,1050 @@ +/* + * $Id$ + * + * Copyright (C) INRIA, 2014-2015 + * + * 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 + */ + +/* + * This implementation works. However, it may be inneficient in terms of time + * or space taken in the database (too many tables and too many indirections). + * It could be replaced by another. + * + * Caveats: + * - Another problem is the status of this class. It may be better to make it a + * subclass of SQLCache... + */ + +package fr.inrialpes.exmo.align.service; + +import java.util.List; +import java.util.Vector; +import java.net.URI; +import java.net.URISyntaxException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import org.semanticweb.owl.align.Alignment; +import org.semanticweb.owl.align.AlignmentException; + +import fr.inrialpes.exmo.align.parser.SyntaxElement.Constructor; + +import fr.inrialpes.exmo.align.impl.edoal.Id; +import fr.inrialpes.exmo.align.impl.edoal.PathExpression; +import fr.inrialpes.exmo.align.impl.edoal.Expression; +import fr.inrialpes.exmo.align.impl.edoal.ClassExpression; +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; +import fr.inrialpes.exmo.align.impl.edoal.PropertyId; +import fr.inrialpes.exmo.align.impl.edoal.PropertyConstruction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyTypeRestriction; +import fr.inrialpes.exmo.align.impl.edoal.PropertyValueRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationId; +import fr.inrialpes.exmo.align.impl.edoal.RelationExpression; +import fr.inrialpes.exmo.align.impl.edoal.RelationConstruction; +import fr.inrialpes.exmo.align.impl.edoal.RelationRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.RelationCoDomainRestriction; +import fr.inrialpes.exmo.align.impl.edoal.InstanceId; +import fr.inrialpes.exmo.align.impl.edoal.InstanceExpression; + +import fr.inrialpes.exmo.align.impl.edoal.Transformation; +import fr.inrialpes.exmo.align.impl.edoal.ValueExpression; +import fr.inrialpes.exmo.align.impl.edoal.Value; +import fr.inrialpes.exmo.align.impl.edoal.Apply; +import fr.inrialpes.exmo.align.impl.edoal.Datatype; +import fr.inrialpes.exmo.align.impl.edoal.EDOALCell; +import fr.inrialpes.exmo.align.impl.edoal.EDOALVisitor; +import fr.inrialpes.exmo.align.impl.edoal.Linkkey; +import fr.inrialpes.exmo.align.impl.edoal.LinkkeyBinding; +import fr.inrialpes.exmo.align.impl.edoal.LinkkeyEquals; +import fr.inrialpes.exmo.align.impl.edoal.LinkkeyIntersects; +import fr.inrialpes.exmo.align.impl.edoal.Comparator; + +/** + * Stores an EDOAL expression in SQL + * and extract EDOAL expressions from the database + * + * @author Jérôme Euzenat + * @version $Id$ + * + */ + +public class EDOALSQLCache { + final static Logger logger = LoggerFactory.getLogger(EDOALSQLCache.class); + + private boolean isPattern = false; + + DBService service = null; + Connection conn = null; + + // These identifiers are used for indicating in database tables in which table to look for element + // (and additionally, what is the constructor) + // id identifier + public static final int ID = 0; + // class constructor + public static final int AND = 1; + public static final int OR = 2; + public static final int NOT = 3; + // property constructor + public static final int COMP = 4; + // relation constructor + public static final int INV = 5; + public static final int SYM = 6; + public static final int TRANS = 7; + public static final int REFL = 8; + // class restriction + public static final int OCC_GEQ = 11; + public static final int OCC_LEQ = 12; + public static final int OCC_EQ = 13; + public static final int ALL = 14; + public static final int EXIST = 15; + // property restriction + public static final int DOM = 21; + public static final int TYP = 22; + public static final int VAL = 23; + // relation restriction + public static final int COD = 24; + // relation restriction + // PATH and VALUE ENTITY + public static final int LIT = 31; + public static final int REL = 32; + public static final int PPT = 33; + public static final int INST = 34; + // Binding types + public static final int EQUAL_KEY = 41; + public static final int INTER_KEY = 42; + // Transformation types + public static final int OO = 51; + public static final int O_ = 52; + public static final int _O = 53; + + public static final int VALUE = 1; + public static final int INSTANCE = 2; + public static final int PATH = 3; + public static final int APPLY = 4; + public static final int RELATION = 5; + public static final int PROPERTY = 6; + public static final int CLASS = 7; + public static final int REST = 8; + + public EDOALSQLCache( DBService serv ) { + service = serv; + } + + // ***TODO*** + // TODO: Massively use prepared queries + // They can be very different + + private PreparedStatement findLinkkey; + private PreparedStatement findTransformation; + private PreparedStatement insertLinkkey; + + public void compileQueries() { + try { + conn = service.getConnection(); + findLinkkey = conn.prepareStatement( "SELECT intid FROM linkkey WHERE cellid=?" ); + findTransformation = conn.prepareStatement( "SELECT type,joinid1,joinid2 FROM transf WHERE cellid=?" ); + insertLinkkey = conn.prepareStatement( "INSERT INTO linkkey (cellid) VALUES (?)", Statement.RETURN_GENERATED_KEYS ); + } catch ( SQLException sex ) { + logger.info( "This is not gonna work... to fix" ); + } + } + + public Statement createStatement() throws SQLException { + conn = service.getConnection(); + return conn.createStatement(); + } + + public PreparedStatement createInsertStatement( String updatePattern ) throws SQLException { + conn = service.getConnection(); + return conn.prepareStatement( updatePattern, Statement.RETURN_GENERATED_KEYS ); + } + + public long executeUpdateWithId( PreparedStatement st, String msg ) throws SQLException { + if ( st.executeUpdate() != 0 ) { + try ( ResultSet generatedKeys = st.getGeneratedKeys() ) { + if ( generatedKeys.next() ) { + return generatedKeys.getLong(1); + } else { + throw new SQLException("Creating "+msg+" entry failed, no ID obtained."); + } + } + } else throw new SQLException("Creating "+msg+" enty failed."); + } + + public void init() throws AlignmentException { + // Should be done at the begining, but not necessarily in init + try { + conn = service.getConnection(); + // service must be initialised (from SQLCache likely) + conn.setAutoCommit( false ); + // visit something + compileQueries(); + } catch ( SQLException sqlex ) { + throw new AlignmentException( "Cannot connect to database", sqlex ); + //} catch ( AlignmentException alex ) { + } finally { + try { conn.setAutoCommit( true ); } catch ( SQLException sqlex ) {} + } + } + + // ***TODO*** + // Deal with variables here... + // if (isPattern) { renderVariables(e); } + public void renderVariables( Expression expr ) { + /* + if (expr.getVariable() != null) { + writer.print(" " + SyntaxElement.VAR.print(DEF) + "=\"" + expr.getVariable().name()); + }*/ + } + + // This is only for the expressions which are in correspondences + + // **TODO** + public void erase( EDOALCell cell ) { + } + + public Expression extractExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,joinid FROM edoalexpr WHERE intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve EDOAL expression : "+intid ); + int type = rs.getInt( "type" ); + if ( type == RELATION ) return extractRelationExpression( rs.getLong( "joinid" ) ); + else if ( type == PROPERTY ) return extractPropertyExpression( rs.getLong( "joinid" ) ); + else if ( type == INSTANCE ) return extractInstanceExpression( rs.getLong( "joinid" ) ); + else return extractClassExpression( rs.getLong( "joinid" ) ); + } + } + + public long visit( final Expression e ) throws SQLException, AlignmentException { + long intid; + int type; + if ( e instanceof ClassExpression ) { + intid = visit( (ClassExpression)e ); + type = CLASS; + } else if ( e instanceof PropertyExpression ) { + intid = visit( (PropertyExpression)e ); + type = PROPERTY; + } else if ( e instanceof RelationExpression ) { + intid = visit( (RelationExpression)e ); + type = RELATION; + } else if ( e instanceof InstanceExpression ) { + intid = visit( (InstanceExpression)e ); + type = INSTANCE; + } else throw new AlignmentException( "Invalid expression type in a correspondence : "+e ); + return registerExpression( "edoalexpr", type, intid ); + } + + public ClassExpression extractClassExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,joinid FROM classexpr WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + int type = rs.getInt( "type" ); + if ( type == ID ) return extractClassId( rs.getLong( "joinid" ) ); + else if ( type == OR || type == AND || type == NOT ) + return extractClassConstruction( type, rs.getLong( "joinid" ) ); + else if ( type == REST ) + return extractClassRestriction( rs.getLong( "joinid" ) ); + else throw new AlignmentException( "Invalid class expression type : "+type ); + } else { + throw new AlignmentException( "Cannot retrieve class expression "+intid ); + } + } + } + + public long visit( final ClassExpression e ) throws SQLException, AlignmentException { + if ( e instanceof ClassId ) return visit( (ClassId)e ); + else if ( e instanceof ClassConstruction ) return visit( (ClassConstruction)e ); + else if ( e instanceof ClassRestriction ) return visit( (ClassRestriction)e ); + else throw new AlignmentException( "Invalid ClassExpression type: "+e ); + } + + public ClassId extractClassId( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT uri FROM classid WHERE intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve class id : "+intid ); + try { + return new ClassId( new URI( rs.getString( "uri" ) ) ); + + } catch ( URISyntaxException urisex ) { + throw new AlignmentException( "Invalid URI", urisex ); + } + } + } + + public long visit( final ClassId e ) throws SQLException, AlignmentException { + long idres = registerId( e, "classid" ); + return registerExpression( "classexpr", ID, idres ); + } + + public ClassConstruction extractClassConstruction( int op, long intid ) throws SQLException, AlignmentException { + Constructor constr = null; + if ( op == AND ) constr = Constructor.AND; + else if ( op == OR ) constr = Constructor.OR; + else if ( op == NOT ) constr = Constructor.NOT; + else throw new AlignmentException( "Invalid operator "+op ); + List<ClassExpression> expressions = new Vector<ClassExpression>(); + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT id FROM classlist WHERE intid='"+intid+"' ORDER BY id" ); + while ( rs.next() ) { + expressions.add( extractClassExpression( rs.getLong( "id" ) ) ); + } + return new ClassConstruction( constr, expressions ); + } + } + + public long visit( final ClassConstruction e ) throws SQLException, AlignmentException { + // Get the constructor + final Constructor op = e.getOperator(); + int type; + if ( op == Constructor.OR ) type = OR; + else if ( op == Constructor.AND ) type = AND; + else if ( op == Constructor.NOT ) type = NOT; + else throw new AlignmentException( "Invalid constructor "+op ); + if ( (op == Constructor.OR) || (op == Constructor.AND) ) { + // Create the relexpr + long exprres = registerExpression( "classexpr", type, 0 ); + // Iterate on components + try ( Statement st = service.getConnection().createStatement() ) { + for ( final ClassExpression ce : e.getComponents() ) { + long pres = visit( ce ); + st.executeUpdate( "INSERT INTO classlist (intid,id) VALUES ('"+exprres+"','"+pres+"')" ); + } + } + // Return the relexpr + return exprres; + } else { // NOT + final ClassExpression ce = e.getComponents().iterator().next(); // OK... + // Create the component + long pres = visit( ce ); + // Create the relexpr + return registerExpression( "classexpr", type, pres ); + } + } + + public ClassRestriction extractClassRestriction( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT path,type,joinid FROM classrest WHERE intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve class restriction "+intid ); + int type = rs.getInt( "type" ); + PathExpression pe = extractPathExpression( rs.getLong( "path" ) ); + if ( type >= OCC_GEQ && type <= OCC_EQ ) { + int val = rs.getInt( "joinid" ); // HERE COULD BE A PROBLEM + Comparator comp = null; + if ( type == OCC_GEQ ) comp = Comparator.GREATER; + else if ( type == OCC_LEQ ) comp = Comparator.LOWER; + else if ( type == OCC_EQ ) comp = Comparator.EQUAL; + return new ClassOccurenceRestriction( pe, comp, val ); + } else if ( type == DOM ) + return new ClassDomainRestriction( pe, extractClassExpression( rs.getLong( "joinid" ) ) ); + else if ( type == TYP ) + return new ClassTypeRestriction( pe, new Datatype( extractDatatype( rs.getLong( "joinid" ) ).toString() ) ); + else if ( type == VAL ) + return extractClassValueRestriction( pe, rs.getLong( "joinid" ) ); + else throw new AlignmentException( "Incorect class restriction type "+type ); + } + } + + public long visit( final ClassRestriction e ) throws SQLException, AlignmentException { + long idres; + long pathid = visit( e.getRestrictionPath() ); + if ( e instanceof ClassValueRestriction ) idres = visit( pathid, (ClassValueRestriction)e ); + else if ( e instanceof ClassTypeRestriction ) idres = visit( pathid, (ClassTypeRestriction)e ); + else if ( e instanceof ClassDomainRestriction ) idres = visit( pathid, (ClassDomainRestriction)e ); + else if ( e instanceof ClassOccurenceRestriction ) idres = visit( pathid, (ClassOccurenceRestriction)e ); + else throw new AlignmentException( "Invalid ClassExpression type: "+e ); + return registerExpression( "classexpr", REST, idres ); + } + + public ClassValueRestriction extractClassValueRestriction( PathExpression pe, long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT comp,joinid FROM valuerest WHERE type='"+CLASS+"' AND intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve class value restriction "+intid ); + Comparator comp; + try { + comp = Comparator.getComparator( new URI( rs.getString( "comp" ) ) ); + } catch (URISyntaxException urisex) { + throw new AlignmentException( "Invalid comparator URI : "+rs.getString( "comp" ) ); + } + ValueExpression ve = extractValueExpression( rs.getLong( "joinid" ) ); + return new ClassValueRestriction( pe, comp, ve ); + } + } + + public long visit( long pathid, final ClassValueRestriction c ) throws SQLException, AlignmentException { + // Create the restriction + long val = visit( c.getValue() ); + String uri = c.getComparator().toString(); // what about retrieving? + // Register it in value rest + PreparedStatement st2 = createInsertStatement( "INSERT INTO valuerest (type,comp,joinid) VALUES (?,?,?)" ); + st2.setInt( 1, CLASS ); + st2.setString( 2, uri ); + st2.setLong( 3, val ); + long res = executeUpdateWithId( st2, "class value restriction" ); + // Register it finally + return registerClassRestriction( VAL, pathid, res ); + } + + public long visit( long pathid, final ClassTypeRestriction c ) throws SQLException, AlignmentException { + // Create the restriction + long typ = visit( c.getType() ); + // Register it + return registerClassRestriction( TYP, pathid, typ ); + } + + public long visit( long pathid, final ClassDomainRestriction c ) throws SQLException, AlignmentException { + // Create the restriction + long dom = visit( c.getDomain() ); + // Register it + return registerClassRestriction( c.isUniversal()?ALL:EXIST, pathid, dom ); + } + + public long visit( long pathid, final ClassOccurenceRestriction c ) throws SQLException, AlignmentException { + // Create the restriction + int val = c.getOccurence(); + Comparator comp = c.getComparator(); + // Register it + int type; + if ( Comparator.EQUAL.equals( comp ) ) type = OCC_EQ; + else if ( Comparator.GREATER.equals( comp ) ) type = OCC_GEQ; + else if ( Comparator.LOWER.equals( comp ) ) type = OCC_LEQ; + else throw new AlignmentException( "Cannot deal with cardinality comparator "+comp ); + return registerClassRestriction( type, pathid, val ); + } + + public long registerClassRestriction( int type, long path, long joinid ) throws SQLException, AlignmentException { + try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO classrest (path,type,joinid) VALUES (?,?,?)" ) ) { + st2.setLong( 1, path ); + st2.setInt( 2, type ); + st2.setLong( 3, joinid ); + return executeUpdateWithId( st2, "class restriction" ); + } + } + + public PathExpression extractPathExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,joinid FROM pathexpr WHERE intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve path : "+intid ); + if ( rs.getInt( "type" ) == RELATION ) return extractRelationExpression( rs.getLong( "joinid" ) ); + else return extractPropertyExpression( rs.getLong( "joinid" ) ); + } + } + + public long visit( PathExpression e ) throws SQLException, AlignmentException { + long intres; + int type; + if ( e instanceof PropertyExpression ) { + intres = visit( (PropertyExpression)e ); + type = PROPERTY; + } else if ( e instanceof RelationExpression ) { + intres = visit( (RelationExpression)e ); + type = RELATION; + } else throw new AlignmentException( "Invalid ClassExpression type: "+e ); + return registerExpression( "pathexpr", type, intres ); + } + + public PropertyExpression extractPropertyExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,joinid FROM propexpr WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + int type = rs.getInt( "type" ); + if ( type == ID ) return extractPropertyId( rs.getLong( "joinid" ) ); + else if ( type == OR || type == AND || type == COMP || type == NOT ) + return extractPropertyConstruction( type, rs.getLong( "joinid" ) ); + else if ( type == DOM ) return extractPropertyDomainRestriction( rs.getLong( "joinid" ) ); + else if ( type == TYP ) return extractPropertyTypeRestriction( rs.getLong( "joinid" ) ); + else if ( type == VAL ) return extractPropertyValueRestriction( rs.getLong( "joinid" ) ); + else throw new AlignmentException( "Invalid property expression type : "+type ); + } else { + throw new AlignmentException( "Cannot retrieve property expression "+intid ); + } + } + } + + public long visit( PropertyExpression e ) throws SQLException, AlignmentException { + if ( e instanceof PropertyValueRestriction ) { + return visit( (PropertyValueRestriction)e ); + } else if ( e instanceof PropertyTypeRestriction ) { + return visit( (PropertyTypeRestriction)e ); + } else if ( e instanceof PropertyDomainRestriction ) { + return visit( (PropertyDomainRestriction)e ); + } else if ( e instanceof PropertyId ) { + return visit( (PropertyId)e ); + } else if ( e instanceof PropertyConstruction ) { + return visit( (PropertyConstruction)e ); // It does the job... + } else throw new AlignmentException( "Invalid property expression "+e ); + } + + public PropertyId extractPropertyId( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT uri FROM propid WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + try { + return new PropertyId( new URI( rs.getString( "uri" ) ) ); + } catch (URISyntaxException uriex) { + throw new AlignmentException( "Badly formatted URI "+rs.getString("uri"), uriex ); + } + } else { + throw new AlignmentException( "Cannot retrieve property "+intid ); + } + } + } + + public long visit( PropertyId e ) throws SQLException { + long idres = registerId( e, "propid" ); + return registerExpression( "propexpr", ID, idres ); + } + + // *Beware that these are well registered in PathExpression first* + public PropertyConstruction extractPropertyConstruction( int op, long intid ) throws SQLException, AlignmentException { + Constructor constr = null; + if ( op == AND ) constr = Constructor.AND; + else if ( op == OR ) constr = Constructor.OR; + else if ( op == NOT ) constr = Constructor.NOT; + else if ( op == COMP ) constr = Constructor.COMP; + else throw new AlignmentException( "Invalid operator "+op ); + List<PathExpression> expressions = new Vector<PathExpression>(); + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT id FROM proplist WHERE intid='"+intid+"' ORDER BY id" ); + while ( rs.next() ) { + expressions.add( extractPathExpression( rs.getLong( "id" ) ) ); + } + return new PropertyConstruction( constr, expressions ); + } + } + + public long visit( final PropertyConstruction e ) throws SQLException, AlignmentException { + // Get the constructor + final Constructor op = e.getOperator(); + int type; + if ( op == Constructor.OR ) type = OR; + else if ( op == Constructor.AND ) type = AND; + else if ( op == Constructor.COMP ) type = COMP; + else if ( op == Constructor.NOT ) type = NOT; + else throw new AlignmentException( "Invalid constructor "+op ); + if ((op == Constructor.OR) || (op == Constructor.AND) || (op == Constructor.COMP)) { + // Create the relexpr + long exprres = registerExpression( "propexpr", type, 0 ); + // Iterate on components + try ( Statement st = service.getConnection().createStatement() ) { + for ( final PathExpression re : e.getComponents() ) { + long pres = visit( re ); + st.executeUpdate( "INSERT INTO proplist (intid,id) VALUES ('"+exprres+"','"+pres+"')" ); + } + } + // Return the propexpr + return exprres; + } else { // NOT + final PathExpression re = e.getComponents().iterator().next(); // OK... + // Create the component + long pres = visit( re ); + // Create the relexpr + return registerExpression( "propexpr", type, pres ); + } + } + + public PropertyValueRestriction extractPropertyValueRestriction( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT comp,joinid FROM valuerest WHERE type='"+PROPERTY+"' AND intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot retrieve property value restriction "+intid ); + Comparator comp; + try { + comp = Comparator.getComparator( new URI( rs.getString( "comp" ) ) ); + } catch (URISyntaxException urisex) { + throw new AlignmentException( "Invalid comparator URI : "+rs.getString( "comp" ) ); + } + ValueExpression ve = extractValueExpression( rs.getLong( "joinid" ) ); + return new PropertyValueRestriction( comp, ve ); + } + } + + public long visit( final PropertyValueRestriction c ) throws SQLException, AlignmentException { + // Create the restriction + long val = visit( c.getValue() ); + String uri = c.getComparator().toString(); // what about retrieving? + long res = 0; + // Register it in value rest + try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO valuerest (type,comp,joinid) VALUES (?,?,?)" ) ) { + st2.setInt( 1, PROPERTY ); + st2.setString( 2, uri ); + st2.setLong( 3, val ); + res = executeUpdateWithId( st2, "property value restriction" ); + // Register it finally + return registerExpression( "propexpr", VAL, res ); + } + } + + public PropertyDomainRestriction extractPropertyDomainRestriction( long intid ) throws SQLException, AlignmentException { + return new PropertyDomainRestriction( extractClassExpression( intid ) ); + } + + public long visit( final PropertyDomainRestriction c ) throws SQLException, AlignmentException { + // Create the domain restriction + long dom = visit( c.getDomain() ); + // Register it + return registerExpression( "propexpr", DOM, dom ); + } + + public PropertyTypeRestriction extractPropertyTypeRestriction( long intid ) throws SQLException, AlignmentException { + return new PropertyTypeRestriction( new Datatype( extractDatatype( intid ).toString() ) ); + } + + public long visit( final PropertyTypeRestriction c ) throws SQLException, AlignmentException { + // Create the domain restriction + long typ = visit( c.getType() ); + // Register it + return registerExpression( "propexpr", TYP, typ ); + } + + public RelationExpression extractRelationExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + // Get the relexpr entry (operator,id) + ResultSet rs = st.executeQuery( "SELECT type,joinid FROM relexpr WHERE intid='"+intid+"'" ); + if ( !rs.next() ) throw new AlignmentException( "Cannot find relation expression "+intid ); + int op = rs.getInt( "type" ); + if ( op == ID ) { + return extractRelationId( rs.getLong( "joinid" ) ); + } else if ( op == DOM ) { + return extractRelationDomainRestriction( rs.getLong( "joinid" ) ); + } else if ( op == COD ) { + return extractRelationCoDomainRestriction( rs.getLong( "joinid" ) ); + } else { + return extractRelationConstruction( op, rs.getLong( "joinid" ) ); + } + } + } + + public long visit( RelationExpression e ) throws SQLException, AlignmentException { + if ( e instanceof RelationRestriction ) { + return visit( (RelationRestriction)e ); + } else if ( e instanceof RelationId ) { + return visit( (RelationId)e ); + } else if ( e instanceof RelationConstruction ) { + return visit( (RelationConstruction)e ); // It does the job... + } else throw new AlignmentException( "Invalid relation expression "+e ); + } + + + public RelationId extractRelationId( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT uri FROM relid WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + try { + return new RelationId( new URI( rs.getString( "uri" ) ) ); + } catch (URISyntaxException uriex) { + throw new AlignmentException( "Badly formatted URI "+rs.getString("uri"), uriex ); + } + } else { + throw new AlignmentException( "Cannot retrieve relation "+intid ); + } + } + } + + public long visit( RelationId e ) throws SQLException { + long idres = registerId( e, "relid" ); + return registerExpression( "relexpr", ID, idres ); + } + + public long registerId( Id expr, String tablename ) throws SQLException { + // If it exists do not add: + String uri = expr.getURI().toString(); + //logger.trace( "Register Id: "+"SELECT intid FROM "+tablename+" WHERE uri='"+uri+"'" ); + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT intid FROM "+tablename+" WHERE uri='"+uri+"'" ); + if ( rs.next() ) { + return rs.getLong("intid"); + } else try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO "+tablename+" (uri) VALUES (?)" ) ) { + st2.setString( 1, uri ); + return executeUpdateWithId( st2, tablename ); + } + } + } + + public long registerExpression( String tablename, int type, long join ) throws SQLException { + try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO "+tablename+" (type,joinid) VALUES (?,?)" ) ) { + st2.setInt( 1, type ); + st2.setLong( 2, join ); + return executeUpdateWithId( st2, tablename ); + } + } + + public RelationConstruction extractRelationConstruction( int op, long intid ) throws SQLException, AlignmentException { + Constructor constr = null; + if ( op == AND ) constr = Constructor.AND; + else if ( op == OR ) constr = Constructor.OR; + else if ( op == NOT ) constr = Constructor.NOT; + else if ( op == COMP ) constr = Constructor.COMP; + else if ( op == INV ) constr = Constructor.INVERSE; + else if ( op == SYM ) constr = Constructor.SYMMETRIC; + else if ( op == TRANS ) constr = Constructor.TRANSITIVE; + else if ( op == REFL ) constr = Constructor.REFLEXIVE; + else throw new AlignmentException( "Invalid operator "+op ); + List<RelationExpression> expressions = new Vector<RelationExpression>(); + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT id FROM rellist WHERE intid='"+intid+"' ORDER BY id" ); + while ( rs.next() ) { + expressions.add( extractRelationExpression( rs.getLong( "id" ) ) ); + } + return new RelationConstruction( constr, expressions ); + } + } + + public long visit( final RelationConstruction e ) throws SQLException, AlignmentException { + // Get the constructor + final Constructor op = e.getOperator(); + int type; + if ( op == Constructor.OR ) type = OR; + else if ( op == Constructor.AND ) type = AND; + else if ( op == Constructor.COMP ) type = COMP; + else if ( op == Constructor.NOT ) type = NOT; + else if ( op == Constructor.INVERSE ) type = INV; + else if ( op == Constructor.REFLEXIVE ) type = REFL; + else if ( op == Constructor.TRANSITIVE ) type = TRANS; + else if ( op == Constructor.SYMMETRIC ) type = SYM; + else throw new AlignmentException( "Invalid constructor "+op ); + if ((op == Constructor.OR) || (op == Constructor.AND) || (op == Constructor.COMP)) { + // Create the relexpr + long exprres = registerExpression( "relexpr", type, 0 ); + // Iterate on components + try ( Statement st = service.getConnection().createStatement() ) { + for ( final PathExpression re : e.getComponents() ) { + long pres = visit( re ); + st.executeUpdate( "INSERT INTO rellist (intid,id) VALUES ('"+exprres+"','"+pres+"')" ); + } + } + // Return the relexpr + return exprres; + } else { // NOT + final PathExpression re = e.getComponents().iterator().next(); // OK... + // Create the component + long pres = visit( re ); + // Create the relexpr + return registerExpression( "relexpr", type, pres ); + } + } + + public RelationCoDomainRestriction extractRelationCoDomainRestriction( long intid ) throws SQLException, AlignmentException { + ClassExpression codom = extractClassExpression( intid ); + return new RelationCoDomainRestriction( codom ); + } + + public long visit( final RelationRestriction c ) throws SQLException, AlignmentException { + if ( c instanceof RelationCoDomainRestriction ) return visit( (RelationCoDomainRestriction)c ); + else if ( c instanceof RelationDomainRestriction ) return visit( (RelationDomainRestriction)c ); + else throw new AlignmentException("Creating relation restriction entry failed."); + } + + public long visit( final RelationCoDomainRestriction c ) throws SQLException, AlignmentException { + // Create the codomain restriction + long codom = visit( c.getCoDomain() ); + // Register it + return registerExpression( "relexpr", COD, codom ); + } + + public RelationDomainRestriction extractRelationDomainRestriction( long intid ) throws SQLException, AlignmentException { + ClassExpression dom = extractClassExpression( intid ); + return new RelationDomainRestriction( dom ); + } + + public long visit( final RelationDomainRestriction c ) throws SQLException, AlignmentException { + // Create the domain restriction + long dom = visit( c.getDomain() ); + // Register it + return registerExpression( "relexpr", DOM, dom ); + } + + public ValueExpression extractValueExpression( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type, joinid FROM valueexpr WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + int type = rs.getInt( "type" ); + if ( type == INSTANCE ) return extractInstanceExpression( rs.getLong( "joinid" ) ); + else if ( type == VALUE ) return extractValue( rs.getLong( "joinid" ) ); + else if ( type == PATH ) return extractPathExpression( rs.getLong( "joinid" ) ); + else if ( type == APPLY ) return extractApply( rs.getLong( "joinid" ) ); + else throw new AlignmentException( "Unknown ValueExpression type "+type ); + } else { + throw new AlignmentException( "Cannot retrieve value expression "+intid ); + } + } + } + + public long visit( ValueExpression e ) throws SQLException, AlignmentException { + long idres; + int type; + if ( e instanceof InstanceExpression ) { + idres = visit( (InstanceExpression)e ); + type = INSTANCE; + } else if ( e instanceof Value ) { + idres = visit( (Value)e ); + type = VALUE; + } else if ( e instanceof PathExpression ) { + idres = visit( (PathExpression)e ); + type = PATH; + } else if ( e instanceof Apply ) { + idres = visit( (Apply)e ); + type = APPLY; + } else throw new AlignmentException( "Unknown ValueExpression "+e ); + return registerExpression( "valueexpr", type, idres ); + } + + // (no instance expression table) + public InstanceExpression extractInstanceExpression( long intid ) throws SQLException, AlignmentException { + return extractInstanceId( intid ); + } + + // (no instance expression table: it is dealt with in instanceid) + public long visit( InstanceExpression e ) throws SQLException, AlignmentException { + if ( e instanceof InstanceId ) return visit( (InstanceId)e ); + else throw new AlignmentException( "Unknown InstanceExpression "+e ); + } + + public InstanceId extractInstanceId( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT uri FROM instexpr WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + try { + return new InstanceId( new URI( rs.getString( "uri" ) ) ); + } catch (URISyntaxException uriex) { + throw new AlignmentException( "Badly formatted URI "+rs.getString("uri"), uriex ); + } + } else throw new AlignmentException( "Cannot retrieve instance "+intid ); + } + } + + public long visit( InstanceId e ) throws SQLException { + return registerId( e, "instexpr" ); + } + + // (play with NULL) + public Value extractValue( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,value FROM literal WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + Long typeid = rs.getLong( "type" ); + if ( typeid != 0 ) { + return new Value( rs.getString( "value" ), extractDatatype( typeid ) ); + } else { + return new Value( rs.getString( "value" ) ); + } + } else throw new AlignmentException( "Cannot retrieve value "+intid ); + } + } + + public long visit( final Value e ) throws SQLException, AlignmentException { + String restQuery = ""; + long typid = 0; + if ( e.getType() != null ) { + typid = visitDatatype( e.getType().toString() ); + restQuery = "AND type='"+typid+"'"; + } + // If it exists do not add: + String val = e.getValue(); + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT intid FROM literal WHERE value="+SQLCache.quote( val )+""+restQuery ); + if ( rs.next() ) { + return rs.getLong("intid"); + } else { + String query = "INSERT INTO literal (value) VALUES (?)"; + if ( typid != 0 ) { + query = "INSERT INTO literal (value,type) VALUES (?,'"+typid+"')"; + } + try ( PreparedStatement st2 = createInsertStatement( query ) ) { + st2.setString( 1, val ); + return executeUpdateWithId( st2, "value" ); + } + } + } + } + + // (play with NULL) + public Apply extractApply( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = createStatement().executeQuery( "SELECT operation FROM apply WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + try { + URI opuri = new URI( rs.getString( "operation" ) ); + try ( Statement st2 = service.getConnection().createStatement() ) { + ResultSet rs2 = st2.executeQuery( "SELECT id FROM arglist WHERE intid='"+intid+"'" ); + List<ValueExpression> args = new Vector<ValueExpression>(); + while ( rs2.next() ) { + args.add( extractValueExpression( rs2.getLong( "id" ) ) ); + } + return new Apply( opuri, args ); + } + } catch ( URISyntaxException urisex ) { + throw new AlignmentException( "Invalid operation URI", urisex ); + } + } else throw new AlignmentException( "Cannot retrieve apply "+intid ); + } + } + + public long visit( final Apply e ) throws SQLException, AlignmentException { + // Get the constructor + final URI op = e.getOperation(); + // Create the relexpr + try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO apply (operation) VALUES (?)" ) ) { + st2.setString( 1, op.toString() ); + long exprres = executeUpdateWithId( st2, "apply" ); + // Iterate on arguments + try ( Statement st = service.getConnection().createStatement() ) { + for ( final ValueExpression ve : e.getArguments() ) { + long pres = visit( ve ); + st.executeUpdate( "INSERT INTO arglist (intid,id) VALUES ('"+exprres+"','"+pres+"')" ); + } + } + // Return the expr + return exprres; + } + } + + public URI extractDatatype( long intid ) throws SQLException, AlignmentException { + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT uri FROM typeexpr WHERE intid='"+intid+"'" ); + if ( rs.next() ) { + try { + return new URI( rs.getString("uri") ); + } catch (URISyntaxException uriex) { + throw new AlignmentException( "Badly formatted URI "+rs.getString("uri"), uriex ); + } + } else throw new AlignmentException( "Cannot retrieve datatype "+intid ); + } + } + + // Note: in EDOAL, values have datatypes which simply are URIs! + public long visitDatatype( String uri ) throws SQLException { + // If it exists do not add: + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT intid FROM typeexpr WHERE uri='"+uri+"'" ); + if ( rs.next() ) { + return rs.getLong("intid"); // try getInt on tables + } else { + try ( PreparedStatement st2 = createInsertStatement( "INSERT INTO typeexpr (uri) VALUES (?)" ) ) { + st2.setString( 1, uri ); + return executeUpdateWithId( st2, "typeexpr" ); + } + } + } + } + + public long visit( Datatype e ) throws SQLException { + return visitDatatype( e.getType() ); + } + + // Called for each cell in an edoal alignment + public void extractTransformations( String cellid, EDOALCell cell ) throws SQLException, AlignmentException { + // For all the Linkkeys with cellid as cellid + findTransformation.setString( 1, cellid ); + ResultSet rs = findTransformation.executeQuery(); + // Store the result + while ( rs.next() ) { + int type = rs.getInt( "type" ); + String tp; + if ( type == OO ) tp = "oo"; + else if ( type == O_ ) tp = "o-"; + else if ( type == _O ) tp = "-o"; + else throw new AlignmentException( "Invalid transformation type : "+type ); + cell.addTransformation( new Transformation( tp, + extractValueExpression( rs.getLong( "joinid1" ) ), + extractValueExpression( rs.getLong( "joinid2" ) ) ) ); + } + } + + // Called for each cell in an edoal alignment + public long visit( final Transformation transf, String cellid ) throws SQLException, AlignmentException { + String tp = transf.getType(); + long ob1 = visit( transf.getObject1() ); + long ob2 = visit( transf.getObject2() ); + int type; + if ( tp.equals("oo") ) type = OO; + else if ( tp.equals( "o-" ) ) type = O_; + else if ( tp.equals( "-o" ) ) type = _O; + else throw new AlignmentException( "Invalid transformation type : "+tp ); + PreparedStatement st2 = createInsertStatement( "INSERT INTO transf (cellid,type,joinid1,joinid2) VALUES (?,?,?,?)" ); + st2.setString( 1, cellid ); + st2.setInt( 2, type ); + st2.setLong( 3, ob1 ); + st2.setLong( 4, ob2 ); + return executeUpdateWithId( st2, "transformation" ); + } + + // Called for each cell in an edoal alignment + public void extractLinkkeys( String cellid, EDOALCell cell ) throws SQLException, AlignmentException { + // For all the Linkkeys with cellid as cellid + findLinkkey.setString( 1, cellid ); + ResultSet rs = findLinkkey.executeQuery(); + // Store the result + while ( rs.next() ) { + Linkkey linkkey = new Linkkey(); + extractBindings( rs.getLong( "intid" ), linkkey ); + cell.addLinkkey( linkkey ); + } + } + + public void visit( final Linkkey linkkey, String cellid ) throws SQLException, AlignmentException { + // Add the linkkey to the table + insertLinkkey.setString( 1, cellid ); + long keyid = executeUpdateWithId( insertLinkkey, "linkkey" ); + // For each dinding add the binding + for ( LinkkeyBinding linkkeyBinding : linkkey.bindings() ) { + visit( linkkeyBinding, keyid ); + } + } + + public void extractBindings( long keyid, Linkkey key ) throws SQLException, AlignmentException { + // For all the Linkkeys with cellid as cellid + try ( Statement st = service.getConnection().createStatement() ) { + ResultSet rs = st.executeQuery( "SELECT type,joinid1,joinid2 FROM binding WHERE keyid='"+keyid+"'" ); + // Store the result + while ( rs.next() ) { + PathExpression p1 = extractPathExpression( rs.getLong( "joinid1" ) ); + PathExpression p2 = extractPathExpression( rs.getLong( "joinid1" ) ); + if ( rs.getInt( "type" ) == EQUAL_KEY ) { + key.addBinding( new LinkkeyEquals( p1, p2 ) ); + } else { + key.addBinding( new LinkkeyIntersects( p1, p2 ) ); + } + } + } + } + + private void visit( LinkkeyBinding linkkeyBinding, long keyid ) throws SQLException, AlignmentException { + // Store the two paths + long p1 = visit( linkkeyBinding.getExpression1() ); + long p2 = visit( linkkeyBinding.getExpression2() ); + int type = ( linkkeyBinding instanceof LinkkeyEquals )?EQUAL_KEY:INTER_KEY; + try ( Statement st = service.getConnection().createStatement() ) { + st.executeUpdate( "INSERT INTO binding (keyid,type,joinid1,joinid2) VALUES ("+keyid+","+type+","+p1+","+p2+")" ); + } + } +} + diff --git a/src/fr/inrialpes/exmo/align/service/SQLCache.java b/src/fr/inrialpes/exmo/align/service/SQLCache.java index c0c84cec7d05f7045e3084e34c1b08ff53f04571..0c5286e6272962d0a262d2f3b25b4de6976fc3c4 100644 --- a/src/fr/inrialpes/exmo/align/service/SQLCache.java +++ b/src/fr/inrialpes/exmo/align/service/SQLCache.java @@ -2,7 +2,7 @@ * $Id$ * * Copyright (C) Seungkeun Lee, 2006 - * Copyright (C) INRIA, 2006-2014 + * Copyright (C) INRIA, 2006-2015 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -42,6 +42,11 @@ import fr.inrialpes.exmo.align.impl.BasicOntologyNetwork; import fr.inrialpes.exmo.align.impl.Annotations; import fr.inrialpes.exmo.align.impl.Namespace; import fr.inrialpes.exmo.align.impl.URIAlignment; +import fr.inrialpes.exmo.align.impl.edoal.EDOALAlignment; +import fr.inrialpes.exmo.align.impl.edoal.EDOALCell; +import fr.inrialpes.exmo.align.impl.edoal.Expression; +import fr.inrialpes.exmo.align.impl.edoal.Linkkey; +import fr.inrialpes.exmo.align.impl.edoal.Transformation; import fr.inrialpes.exmo.ontowrap.Ontology; @@ -66,7 +71,7 @@ public class SQLCache extends VolatilCache implements Cache { String port = null; int rights = 1; // writing rights in the database (default is 1) - final int VERSION = 470; // Version of the API to be stored in the database + final int VERSION = 471; // Version of the API to be stored in the database /* 300: initial database format 301: ADDED alignment id as primary key 302: ALTERd cached/stored/ouri tag forms @@ -89,7 +94,8 @@ public class SQLCache extends VolatilCache implements Cache { // URIINdex: ADDED multiple uris for alignments (?) CHANGED the alext namespace - 471: -- nothing for the moment -- + // EDOAL2015: + 471: ADDED management of EDOAL alignments */ DBService service = null; @@ -233,21 +239,32 @@ public class SQLCache extends VolatilCache implements Cache { String value; logger.debug( "Loading alignment {}", id ); - URIAlignment result = new URIAlignment(); + BasicAlignment result; Statement st = null; try { st = createStatement(); String onto1 = "", onto2 = ""; // Get basic ontology metadata rs = st.executeQuery( "SELECT * FROM alignment WHERE id = '" + id +"'" ); - while( rs.next() ) { - result.setLevel(rs.getString("level")); - result.setType(rs.getString("type")); - onto1 = rs.getString("onto1"); - onto2 = rs.getString("onto2"); + if ( ! rs.next() ) logger.debug( "IGNORED cannot find retrieve "+id ); + // EDOAL2015: detect by 2EDOAL as level (beforehand) + String level = rs.getString("level"); + if ( level.contains( "2EDOAL" ) ) { + result = new EDOALAlignment(); + } else { + result = new URIAlignment(); } - - // Get ontologies (could be better) + result.setLevel( level ); + result.setType( rs.getString("type") ); + onto1 = rs.getString( "onto1" ); + onto2 = rs.getString( "onto2" ); + + // Get the ontolologies + retrieveOntology( onto1, result.getOntologyObject1() ); + result.setExtension( SVCNS, OURI1, onto1 ); + retrieveOntology( onto2, result.getOntologyObject2() ); + result.setExtension( SVCNS, OURI2, onto2 ); + /* JE 2015: EOAL rs = st.executeQuery( "SELECT * FROM ontology WHERE uri = '" + onto1 +"'" ); if ( rs.next() ) { result.getOntologyObject1().setURI( new URI(rs.getString("uri")) ); @@ -270,9 +287,10 @@ public class SQLCache extends VolatilCache implements Cache { result.getOntologyObject2().setFormalism( rs.getString("formname") ); result.setExtension( SVCNS, OURI2, rs.getString("uri") ); } + */ // Get dependencies if necessary - + // Get extension metadata rs = st.executeQuery( "SELECT * FROM extension WHERE id = '" + id + "'" ); while(rs.next()) { @@ -280,17 +298,29 @@ public class SQLCache extends VolatilCache implements Cache { value = rs.getString("val"); result.setExtension( rs.getString("uri"), tag, value); } + // has been extracted from the database + //result.setExtension( SVCNS, STORED, "DATE"); + // not yet cached (this instruction should be useless) + result.setExtension( SVCNS, CACHED, (String)null ); + return result; } catch (Exception e) { // URI exception that should not occur logger.debug( "IGNORED unlikely URI exception", e); return null; } finally { try { st.close(); } catch (Exception ex) {}; } - // has been extracted from the database - //result.setExtension( SVCNS, STORED, "DATE"); - // not yet cached (this instruction should be useless) - result.setExtension( SVCNS, CACHED, (String)null ); - return result; + } + + public void retrieveOntology( String uri, Ontology ob ) throws SQLException, AlignmentException, URISyntaxException { + Statement st = createStatement(); + ResultSet rs = st.executeQuery( "SELECT * FROM ontology WHERE uri = '" + uri +"'" ); + if ( rs.next() ) { + ob.setURI( new URI(rs.getString("uri")) ); + // I am really surprised by this + if ( rs.getString("file") != null ) ob.setFile( new URI( rs.getString("file") ) ); + if ( rs.getString("formuri") != null ) ob.setFormURI( new URI( rs.getString("formuri") ) ); + if ( rs.getString("formname") != null ) ob.setFormalism( rs.getString("formname") ); + } else throw new AlignmentException( "Unknown ontology : "+uri ); } /** @@ -304,42 +334,61 @@ public class SQLCache extends VolatilCache implements Cache { */ protected Alignment retrieveAlignment( String uri, Alignment alignment ) throws SQLException, AlignmentException, URISyntaxException { String id = stripAlignmentUri( uri ); - URI ent1 = null, ent2 = null; - alignment.setOntology1( new URI( alignment.getExtension( SVCNS, OURI1 ) ) ); - alignment.setOntology2( new URI( alignment.getExtension( SVCNS, OURI2 ) ) ); + // JE2015 EDOAL + //alignment.setOntology1( new URI( alignment.getExtension( SVCNS, OURI1 ) ) ); + //alignment.setOntology2( new URI( alignment.getExtension( SVCNS, OURI2 ) ) ); // Get cells Statement st = createStatement(); Statement st2 = createStatement(); + EDOALSQLCache esrv = null; ResultSet rs = st.executeQuery( "SELECT * FROM cell WHERE id = '" + id + "'" ); while( rs.next() ) { - ent1 = new URI( rs.getString("uri1") ); - ent2 = new URI( rs.getString("uri2") ); - if ( ent1 == null || ent2 == null ) break; - Cell cell = alignment.addAlignCell(ent1, ent2, rs.getString("relation"), Double.parseDouble(rs.getString("measure"))); + logger.trace( "Loading cell {}", rs.getString( "cell_id" ) ); + try { // To suppress + Cell cell; + if ( alignment instanceof URIAlignment ) { + URI ent1 = new URI( rs.getString("uri1") ); + URI ent2 = new URI( rs.getString("uri2") ); + if ( ent1 == null || ent2 == null ) break; + cell = ((URIAlignment)alignment).addAlignCell( ent1, ent2, rs.getString("relation"), Double.parseDouble(rs.getString("measure")) ); + } else { // EDOAL2015: load the cell + esrv = new EDOALSQLCache( service ); + esrv.init(); + Object ent1 = esrv.extractExpression( Long.parseLong( rs.getString("uri1") ) ); + Object ent2 = esrv.extractExpression( Long.parseLong( rs.getString("uri2") ) ); + if ( ent1 == null || ent2 == null ) break; + cell = ((EDOALAlignment)alignment).addAlignCell( ent1, ent2, rs.getString("relation"), Double.parseDouble(rs.getString("measure")) ); + } String cid = rs.getString( "cell_id" ); if ( cid != null && !cid.equals("") ) { if ( !cid.startsWith("##") ) { cell.setId( cid ); } + if ( cell instanceof EDOALCell ) { // EDOAL2015: load linkkeys and transformations + esrv.extractTransformations( cid, ((EDOALCell)cell) ); + esrv.extractLinkkeys( cid, ((EDOALCell)cell) ); + } ResultSet rse2 = st2.executeQuery("SELECT * FROM extension WHERE id = '" + cid + "'"); - while ( rse2.next() ){ + while ( rse2.next() ) { cell.setExtension( rse2.getString("uri"), rse2.getString("tag"), rse2.getString("val") ); } } cell.setSemantics( rs.getString( "semantics" ) ); + // To suppress + } catch (Exception toto) { toto.printStackTrace(); } } - + // reset resetCacheStamp(alignment); st.close(); return alignment; } - // ONETW: Load an ontology network + // Load an ontology network protected OntologyNetwork retrieveOntologyNetwork( String id ) { logger.debug( "Loading network of ontology {}", id ); BasicOntologyNetwork network = new BasicOntologyNetwork(); @@ -358,8 +407,8 @@ public class SQLCache extends VolatilCache implements Cache { } rs = st.executeQuery( "SELECT * FROM networkalignment WHERE network = '" + id +"'" ); while ( rs.next() ) { - // get the alignment with that URI and set it - network.addAlignment( getAlignment( recoverAlignmentUri( rs.getString("align") ) ) ); + // get the alignment with that URI and set it (only the description of the alignment) + network.addAlignment( getMetadata( recoverAlignmentUri( rs.getString("align") ) ) ); } // Get extension metadata (including URI) @@ -401,6 +450,7 @@ public class SQLCache extends VolatilCache implements Cache { try { return retrieveAlignment( uri, result ); } catch ( SQLException sqlex ) { + logger.trace( "Cache: cannot read from DB", sqlex ); throw new AlignmentException( "getAlignment: SQL exception", sqlex ); } catch ( URISyntaxException urisex ) { logger.trace( "Cache: cannot read from DB", urisex ); @@ -419,7 +469,7 @@ public class SQLCache extends VolatilCache implements Cache { * This function is used here for protecting everything to be entered in * the database */ - public String quote( String s ) { + public static String quote( String s ) { if ( s == null ) return "NULL"; String result = "'"; char[] chars = s.toCharArray(); @@ -447,6 +497,7 @@ public class SQLCache extends VolatilCache implements Cache { } // Suppress it from the cache... + // EDOAL2015: That will be likely more complex for EDOAL public void unstoreAlignment( String uri, Alignment alignment ) throws AlignmentException { try { Statement st = createStatement(); @@ -461,6 +512,7 @@ public class SQLCache extends VolatilCache implements Cache { st.executeUpdate( "DELETE FROM extension WHERE id='"+cid+"'" ); } } + unstoreEDOALAlignment( id, alignment ); // EDOAL2015 st.executeUpdate("DELETE FROM cell WHERE id='"+id+"'"); st.executeUpdate("DELETE FROM extension WHERE id='"+id+"'"); //ontologies do not depend on alignments @@ -482,21 +534,39 @@ public class SQLCache extends VolatilCache implements Cache { } } + public void unstoreEDOALAlignment( String id, Alignment alignment ) throws AlignmentException { + // should seriously think of making it static? + EDOALSQLCache esrv = new EDOALSQLCache( service ); + esrv.init(); + for ( Cell c : alignment ) { + if ( c instanceof EDOALCell ) esrv.erase( (EDOALCell)c ); + } + } + + // EDOAL2015 public void storeAlignment( String uri ) throws AlignmentException { + logger.trace( "Storing alignment "+uri ); String query = null; BasicAlignment alignment = (BasicAlignment)getAlignment( uri ); String id = stripAlignmentUri( uri ); Statement st = null; - // We store stored date + // We store stored date (this is done now for being registered in the database) alignment.setExtension( SVCNS, STORED, new Date().toString()); // We empty cached date alignment.setExtension( SVCNS, CACHED, (String)null ); + EDOALSQLCache esrv = null; + if ( alignment instanceof EDOALAlignment ) { + esrv = new EDOALSQLCache( service ); + esrv.init(); + logger.trace( "EDOAL Alignment: created object" ); + } try { // Try to store at most 3 times. // Otherwise, an exception EOFException will be thrown (relation with Jetty???) // [JE2013: Can we check this?] for( int i=0; i < 3 ; i++ ) { + logger.trace( "Trying to store : "+i ); try { st = createStatement(); logger.debug( "Storing alignment {} as {}", uri, id ); @@ -509,6 +579,7 @@ public class SQLCache extends VolatilCache implements Cache { alignment.getOntology2URI(), alignment.getFile2(), alignment.getOntologyObject2() ); + // This cannot be done in the end because of foreign keys, rollback takes care of it query = "INSERT INTO alignment " + "(id, type, level, onto1, onto2) " + "VALUES (" +quote(id)+","+quote(alignment.getType())+","+quote(alignment.getLevel())+","+quote(alignment.getOntology1URI().toString())+","+quote(alignment.getOntology2URI().toString())+")"; @@ -525,6 +596,7 @@ public class SQLCache extends VolatilCache implements Cache { st.executeUpdate(query); } // Store cells + logger.trace( "Storing cells" ); for( Cell c : alignment ) { String cellid = null; if ( c.getObject1() != null && c.getObject2() != null ){ @@ -533,13 +605,22 @@ public class SQLCache extends VolatilCache implements Cache { if ( cellid.startsWith("#") ) { cellid = alignment.getExtension( Namespace.ALIGNMENT.uri, Annotations.ID ) + cellid; } - } else if ( c.getExtensions() != null ) { - // JE: In case of extensions create an ID + } else if ( ( c.getExtensions() != null ) || + ( ((EDOALCell)c).transformations() != null && !((EDOALCell)c).transformations().isEmpty() ) || + ( ((EDOALCell)c).linkkeys() != null && !((EDOALCell)c).linkkeys().isEmpty() ) ) { + // if no id => generate one. cellid = generateCellId(); } else cellid = ""; - String uri1 = c.getObject1AsURI(alignment).toString(); - String uri2 = c.getObject2AsURI(alignment).toString(); + logger.trace( "Storing cell: "+cellid ); + String uri1, uri2; + if ( c instanceof EDOALCell ) { // EDOAL2015: + uri1 = String.valueOf( esrv.visit( (Expression)((EDOALCell)c).getObject1() ) ); + uri2 = String.valueOf( esrv.visit( (Expression)((EDOALCell)c).getObject2() ) ); + } else { + uri1 = c.getObject1AsURI(alignment).toString(); + uri2 = c.getObject2AsURI(alignment).toString(); + } String strength = c.getStrength() + ""; // crazy Java String sem; if ( !c.getSemantics().equals("first-order") ) @@ -551,6 +632,7 @@ public class SQLCache extends VolatilCache implements Cache { "VALUES (" + quote(id) + "," + quote(cellid) + "," + quote(uri1) + "," + quote(uri2) + "," + quote(strength) + "," + quote(sem) + "," + quote(rel) + ")"; st.executeUpdate(query); } + // Store extensions if ( cellid != null && !cellid.equals("") && c.getExtensions() != null ) { // Store extensions for ( String[] ext : c.getExtensions() ) { @@ -563,6 +645,21 @@ public class SQLCache extends VolatilCache implements Cache { st.executeUpdate(query); } } + logger.trace( "Stored cell: "+cellid ); + // Store transformations and linkkeys + if ( c instanceof EDOALCell ) { // EDOAL2015: store linkkeys and transformations if any + if ( ((EDOALCell)c).transformations() != null && !((EDOALCell)c).transformations().isEmpty() ) { + for ( Transformation transf : ((EDOALCell)c).transformations() ) { + esrv.visit( transf, cellid ); + } + } + if ( ((EDOALCell)c).linkkeys() != null && !((EDOALCell)c).linkkeys().isEmpty() ) { + for ( Linkkey lk : ((EDOALCell)c).linkkeys() ) { + esrv.visit( lk, cellid ); + } + } + } + logger.trace( "Stored trsnformations and linkleys: "+cellid ); } // URIINdex: store alternative URIs for ( Entry<String,Alignment> entry : alignmentURITable.entrySet() ) { @@ -573,15 +670,18 @@ public class SQLCache extends VolatilCache implements Cache { } st.close(); } catch ( SQLException sqlex ) { + // Unstore the date + alignment.setExtension( SVCNS, STORED, ""); logger.warn( "SQLError", sqlex ); - conn.rollback(); + conn.rollback(); // seems to work well! throw new AlignmentException( "SQLException", sqlex ); } finally { conn.setAutoCommit( true ); } - break; + break; // succeeded } } catch (SQLException sqlex) { + logger.trace( "SQLError", sqlex ); throw new AlignmentException( "SQLRollBack issue", sqlex ); } // We reset cached date @@ -623,7 +723,6 @@ public class SQLCache extends VolatilCache implements Cache { } } - // ONETW public void storeOntologyNetwork( String uri ) throws AlignmentException { String query = null; BasicOntologyNetwork network = (BasicOntologyNetwork)getOntologyNetwork( uri ); @@ -726,11 +825,10 @@ public class SQLCache extends VolatilCache implements Cache { host varchar(50), port varchar(5), prefix varchar(50), - edit varchar(5), + edit varchar(5), version VARCHAR(5) ); - # ontology info create table ontology ( @@ -752,6 +850,34 @@ public class SQLCache extends VolatilCache implements Cache { FOREIGN KEY (onto2) REFERENCES ontology (uri) PRIMARY KEY (id)); + # cell info + + create table cell( + id varchar(100), + cell_id varchar(255), + uri1 varchar(255), + uri2 varchar(255), + semantics varchar(30), + measure varchar(20), + relation varchar(255), + FOREIGN KEY (id) REFERENCES alignment (id)); + + # extension info + + CREATE TABLE extension ( + id varchar(100), + uri varchar(200), + tag varchar(50), + val varchar(500)); + + # extension info + + CREATE TABLE alignmenturis ( + id varchar(100), + uri varchar(255), + prefered boolean); + // Implicit constraint, for each id, there is at most one prefered set to true + # network info create table network ( @@ -785,34 +911,134 @@ public class SQLCache extends VolatilCache implements Cache { FOREIGN KEY (dependsOn) REFERENCES alignment (id), PRIMARY KEY (id, dependsOn)); - # cell info - - create table cell( - id varchar(100), - cell_id varchar(255), - uri1 varchar(255), - uri2 varchar(255), - semantics varchar(30), - measure varchar(20), - relation varchar(255), - FOREIGN KEY (id) REFERENCES alignment (id)); + // EDOAL2015: - # extension info - - CREATE TABLE extension ( - id varchar(100), - uri varchar(200), - tag varchar(50), - val varchar(500)); - - # extension info - - CREATE TABLE alignmenturis ( - id varchar(100), - uri varchar(255), - prefered boolean); - // Implicit constraint, for each id, there is at most one prefered set to true + # dependencies info + + st.executeUpdate("CREATE TABLE edoalexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + + # dependencies info + + st.executeUpdate("CREATE TABLE valueexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + + + # dependencies info + + // EDOAL-INST + //-// types id = URI + st.executeUpdate("CREATE TABLE instexpr (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), var VARCHAR(250), PRIMARY KEY (intid))"); + //-// UNUSED + //st.executeUpdate("CREATE TABLE instlist (listid INT NOT NULL, id BIGINT NOT NULL)"); + + # dependencies info + + // EDOAL-LITERAL + st.executeUpdate("CREATE TABLE literal (intid BIGINT NOT NULL AUTO_INCREMENT, type BIGINT, value VARCHAR(500), PRIMARY KEY (intid))") + + # dependencies info + + //-// + st.executeUpdate("CREATE TABLE typeexpr (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + + # dependencies info + + st.executeUpdate("CREATE TABLE apply (intid BIGINT NOT NULL AUTO_INCREMENT, operation VARCHAR(255), PRIMARY KEY (intid))"); + + # dependencies info + + st.executeUpdate("CREATE TABLE arglist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + + // EDOAL-CLASS + # dependencies info + + //-// type = id [ classid ] / and [ classlist] / or [ classlist] / not [ classexpr] / occ-sup / occ-inf / occ-eq / dom / type / value [ classrest ] + + # dependencies info + + st.executeUpdate("CREATE TABLE classexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + //-// + + # dependencies info + + st.executeUpdate("CREATE TABLE classid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + //-// id in classexpr + + # dependencies info + + st.executeUpdate("CREATE TABLE classlist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + //-// type = occ-sup [ int ] / occ-inf [ int ] / occ-eq [ int ] / type [ classexpr ] / val [ litteral ] + + # dependencies info + + st.executeUpdate("CREATE TABLE classrest (intid BIGINT NOT NULL AUTO_INCREMENT, path BIGINT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + + // EDOAL-PATH + # dependencies info + + //-// type = val [ literal ] / prop [ propexpr ] / rel [ relexpr ] + st.executeUpdate("CREATE TABLE pathexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + + // EDOAL-PROP + # dependencies info + + // type = id [ propid ] / and [ proplist] / or [ proplist] / comp [ proplist, relrest ] / not [ propexpr] / dom / type / val [ proprest ] + st.executeUpdate("CREATE TABLE propexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + + # dependencies info + + //-// + st.executeUpdate("CREATE TABLE propid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + + # dependencies info + + //-// id in propexpr + st.executeUpdate("CREATE TABLE proplist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + + # dependencies info + + //-// type = dom [ classexpr ] / type [ typeexpr ] / val [ litteral ] + st.executeUpdate("CREATE TABLE valuerest (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, path BIGINT, comp VARCHAR(250), joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + + // EDOAL-REL + # dependencies info + + //-// type = id [ relid ] / and [ rellist] / comp [ rellist ] / or [ rellist] / not [ relexpr] / sym [ relexpr] / trans [ relexpr] / refl [ relexpr] / inv [ relexpr ] / dom / cod / val [ relrest ] + + # dependencies info + + st.executeUpdate("CREATE TABLE relexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + //-// + + # dependencies info + + st.executeUpdate("CREATE TABLE relid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + //-// id in relexpr + + # dependencies info + + st.executeUpdate("CREATE TABLE rellist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + //-// type = dom [ classexpr ] / cod [ classexpr ] / val [ instexpr ] OBSOLETE + //st.executeUpdate("CREATE TABLE relrest (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + + // EDOAL-TRANSF + # dependencies info + + // type = o- / -o, looks like the id goes to path? + st.executeUpdate("CREATE TABLE transf (intid BIGINT NOT NULL AUTO_INCREMENT, cellid VARCHAR(255), type INT, joinid1 BIGINT, joinid2 BIGINT, PRIMARY KEY (intid))"); + + // EDOAL-LINKKEY + # dependencies info + + // FOREIGN KEY (cellid) REFERENCES cell (cell_id), + st.executeUpdate("CREATE TABLE linkkey (intid BIGINT NOT NULL AUTO_INCREMENT, cellid VARCHAR(255), PRIMARY KEY (intid))"); + + # dependencies info + + //-// type = equal / intersect; bind are from path + // FOREIGN KEY (keyid) REFERENCES linkkey (intid), + st.executeUpdate("CREATE TABLE binding (keyid BIGINT, type INT, joinid1 BIGINT, joinid2 BIGINT)"); + */ public void initDatabase() throws SQLException { @@ -831,20 +1057,8 @@ public class SQLCache extends VolatilCache implements Cache { st.executeUpdate("CREATE TABLE cell (id VARCHAR(100), cell_id VARCHAR(255), uri1 VARCHAR(255), uri2 VARCHAR(255), semantics VARCHAR(30), measure VARCHAR(20), relation VARCHAR(255), FOREIGN KEY (id) REFERENCES alignment (id))"); st.executeUpdate("CREATE TABLE extension (id VARCHAR(100), uri VARCHAR(200), tag VARCHAR(50), val VARCHAR(500))"); st.executeUpdate("CREATE TABLE alignmenturis (id varchar(100), uri varchar(255), prefered boolean);"); - - /* - // EDOAL - st.executeUpdate("CREATE TABLE instexpr (intid VARCHAR(50), id VARCHAR(250), var VARCHAR(250))"); - st.executeUpdate("CREATE TABLE instlist (joinid VARCHAR(50), intid VARCHAR(250))"); //intid in instexpr - - st.executeUpdate("CREATE TABLE classexpr (intid VARCHAR(50), type VARCHAR(10), joinid VARCHAR(250), var VARCHAR(250))"); - // type=uri: joinid = uri - // type=id: joinid = uri - // type\in classconst: joinid = joinid in classlist - // type\in classrest: joinid = id in classrest - st.executeUpdate("CREATE TABLE classlist (joinid VARCHAR(50), intid VARCHAR(250))"); //intid in classexpr - st.executeUpdate("CREATE TABLE classrest (joinid VARCHAR(50), arg1 VARCHAR(250), arg2 VARCHAR(250))"); - */ + // EDOAL2015: + initEDOALTables( st ); st.close(); @@ -859,6 +1073,31 @@ public class SQLCache extends VolatilCache implements Cache { } } + public void initEDOALTables( Statement st ) throws SQLException { + st.executeUpdate("CREATE TABLE edoalexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE valueexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE instexpr (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE literal (intid BIGINT NOT NULL AUTO_INCREMENT, type BIGINT, value VARCHAR(500), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE typeexpr (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE apply (intid BIGINT NOT NULL AUTO_INCREMENT, operation VARCHAR(255), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE arglist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + st.executeUpdate("CREATE TABLE classexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE classid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE classlist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + st.executeUpdate("CREATE TABLE classrest (intid BIGINT NOT NULL AUTO_INCREMENT, path BIGINT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE pathexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE propexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE propid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE proplist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + st.executeUpdate("CREATE TABLE valuerest (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, path BIGINT, comp VARCHAR(250), joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE relexpr (intid BIGINT NOT NULL AUTO_INCREMENT, type INT, joinid BIGINT, var VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE relid (intid BIGINT NOT NULL AUTO_INCREMENT, uri VARCHAR(250), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE rellist (intid BIGINT NOT NULL, id BIGINT NOT NULL)"); + st.executeUpdate("CREATE TABLE transf (intid BIGINT NOT NULL AUTO_INCREMENT, cellid VARCHAR(255), type INT, joinid1 BIGINT, joinid2 BIGINT, PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE linkkey (intid BIGINT NOT NULL AUTO_INCREMENT, cellid VARCHAR(255), PRIMARY KEY (intid))"); + st.executeUpdate("CREATE TABLE binding (keyid BIGINT NOT NULL, type INT, joinid1 BIGINT, joinid2 BIGINT)"); + } + public void resetDatabase( boolean force ) throws SQLException, AlignmentException { Statement st = createStatement(); try { @@ -873,7 +1112,7 @@ public class SQLCache extends VolatilCache implements Cache { throw new AlignmentException("Cannot init database: other processes use it"); } } - // Suppress old database if exists + // Suppress old databases if exists st.executeUpdate("DROP TABLE IF EXISTS alignmenturis"); st.executeUpdate("DROP TABLE IF EXISTS extension"); st.executeUpdate("DROP TABLE IF EXISTS cell"); @@ -884,6 +1123,29 @@ public class SQLCache extends VolatilCache implements Cache { st.executeUpdate("DROP TABLE IF EXISTS alignment"); st.executeUpdate("DROP TABLE IF EXISTS ontology"); st.executeUpdate("DROP TABLE IF EXISTS server"); + // EDOAL2015 + st.executeUpdate("DROP TABLE IF EXISTS edoalexpr"); + st.executeUpdate("DROP TABLE IF EXISTS valueexpr"); + st.executeUpdate("DROP TABLE IF EXISTS instexpr"); + st.executeUpdate("DROP TABLE IF EXISTS literal"); + st.executeUpdate("DROP TABLE IF EXISTS typeexpr"); + st.executeUpdate("DROP TABLE IF EXISTS apply"); + st.executeUpdate("DROP TABLE IF EXISTS arglist"); + st.executeUpdate("DROP TABLE IF EXISTS classexpr"); + st.executeUpdate("DROP TABLE IF EXISTS classid"); + st.executeUpdate("DROP TABLE IF EXISTS classlist"); + st.executeUpdate("DROP TABLE IF EXISTS classrest"); + st.executeUpdate("DROP TABLE IF EXISTS pathexpr"); + st.executeUpdate("DROP TABLE IF EXISTS propexpr"); + st.executeUpdate("DROP TABLE IF EXISTS propid"); + st.executeUpdate("DROP TABLE IF EXISTS proplist"); + st.executeUpdate("DROP TABLE IF EXISTS valuerest"); + st.executeUpdate("DROP TABLE IF EXISTS relexpr"); + st.executeUpdate("DROP TABLE IF EXISTS relid"); + st.executeUpdate("DROP TABLE IF EXISTS rellist"); + st.executeUpdate("DROP TABLE IF EXISTS transf"); + st.executeUpdate("DROP TABLE IF EXISTS linkkey"); + st.executeUpdate("DROP TABLE IF EXISTS binding"); // Redo it initDatabase(); @@ -1121,8 +1383,10 @@ public class SQLCache extends VolatilCache implements Cache { st2.executeUpdate("UPDATE extension SET uri='"+Namespace.ALIGNMENT.uri+"#' WHERE uri='"+Namespace.ALIGNMENT.uri+"'"); st2.executeUpdate("UPDATE extension SET uri='"+Namespace.EXT.uri+"' WHERE uri='"+Namespace.ALIGNMENT.uri+"#' AND (tag='time' OR tag='method' OR tag='pretty')"); } - if ( version < 471 ) { - // EDOAL: usually add tables + if ( version < 471 ) { // EDOAL2015: + logger.info("Upgrading to version 4.71"); + logger.info("Creating EDOAL tables"); + initEDOALTables( createStatement() ); } // ALTER version st.executeUpdate("UPDATE server SET version='"+VERSION+"'"); diff --git a/src/fr/inrialpes/exmo/align/service/msg/CannotStoreAlignment.java b/src/fr/inrialpes/exmo/align/service/msg/CannotStoreAlignment.java new file mode 100644 index 0000000000000000000000000000000000000000..c24647de136934a62a938781b75ede2bc21acb34 --- /dev/null +++ b/src/fr/inrialpes/exmo/align/service/msg/CannotStoreAlignment.java @@ -0,0 +1,48 @@ +/* + * $Id$ + * + * Copyright (C) INRIA, 2015 + * + * 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.service.msg; + +import java.util.Properties; + +/** + * Contains the messages that should be sent according to the protocol + */ + +public class CannotStoreAlignment extends ErrorMsg { + + public CannotStoreAlignment ( int surr, Message rep, String from, String to, String cont, Properties param ) { + super( surr, rep, from, to, cont, param ); + } + + public CannotStoreAlignment ( Properties mess, int surr, String from, String cont ) { + super( mess, surr, from, cont ); + } + + public String HTMLString(){ + return "Cannot store alignment "+content; + } + public String RESTString(){ + return "<CannotStoreAlignment>"+getXMLContent()+"</CannotStoreAlignment>"; + } + public String JSONString(){ + return "{ \"type\" : \"CannotStoreAlignment\",\n \"content\" : \""+getJSONContent()+"\"\n}"; + } +}