Java tutorial
/* * COPYRIGHT (c) 2008-2009 by Institute of Computer Science, * Foundation for Research and Technology - Hellas * Contact: * POBox 1385, Heraklio Crete, GR-700 13 GREECE * Tel:+30-2810-391632 * Fax: +30-2810-391638 * E-mail: isl@ics.forth.gr * http://www.ics.forth.gr/isl * * Authors : Dimitris Andreou, Nelly Vouzoukidou. * * This file is part of SWKM model APIs (see also http://athena.ics.forth.gr:9090/SWKM/). * * SWKM model APIs 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 3 of the License, or * (at your option) any later version. * * SWKM model APIs 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 SWKM model APIs. If not, see <http://www.gnu.org/licenses/>. * * SWKM has been partially supported by EU project KP-Lab (IP IST-27490) kp-lab.org */ package gr.forth.ics.swkm.model2.importer; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; import gr.forth.ics.swkm.model2.Inference; import gr.forth.ics.swkm.model2.Resource; import gr.forth.ics.swkm.model2.Triple; import gr.forth.ics.swkm.model2.Model; import gr.forth.ics.swkm.model2.RdfType; import gr.forth.ics.swkm.model2.vocabulary.Rdf; import gr.forth.ics.swkm.model2.vocabulary.RdfSchema; import gr.forth.ics.swkm.model2.vocabulary.RdfSuite; import gr.forth.ics.swkm.model2.vocabulary.XmlSchema; import gr.forth.ics.swkm.model2.Uri; import gr.forth.ics.swkm.model2.Uri.Delimiter; import gr.forth.ics.swkm.model2.importer.DbSynchronizer.KnownDbState; import gr.forth.ics.swkm.model2.importer.DbSynchronizer.UpdatedLabels; import gr.forth.ics.swkm.model2.labels.Interval; import gr.forth.ics.swkm.model2.labels.Label; import gr.forth.ics.swkm.model2.validation.Validator; import gr.forth.ics.swkm.model2.vocabulary.Owl; import gr.forth.ics.swkm.model2.util.NamespaceDependenciesIndex; import gr.forth.ics.swkm.model2.Triples; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.Iterator; import javax.sql.DataSource; import gr.forth.ics.swkm.model2.LiteralNode; import gr.forth.ics.swkm.model2.event.TripleListener; import java.util.EnumSet; import java.util.Map.Entry; import org.springframework.util.Assert; /** * @author Andreou Dimitris, email: jim.andreou (at) gmail (dot) com */ abstract class AbstractStore implements RdfStore { protected final Jdbc jdbc; protected final Tables commonTables; protected final Configurer conf; private final RdfStores.Representation representation; private final int DEFAULT_GRAPHSET_ID = 200000; public AbstractStore(RdfStores.Representation representation, DataSource dataSource, Configurer conf) { Assert.notNull(representation, "Representation"); Assert.notNull(dataSource, "DataSource"); Assert.notNull(conf, "Configurer"); this.representation = representation; this.jdbc = new Jdbc(dataSource); this.commonTables = new Tables(conf); this.conf = conf; } boolean isSchemaInitialized() { try { Jdbc.execute("SELECT * from %s", commonTables.representation.getName()); return true; } catch (SQLException e) { return false; } } public final void initializeSchemaIfNeeded() throws SQLException { jdbc.doInConnection(new ConnectionTask<Void>() { @Override public Void execute() throws SQLException { Connection connection = Jdbc.connection(); connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); connection.setAutoCommit(true); if (isSchemaInitialized()) { return null; } connection.setAutoCommit(false); initialize(); connection.commit(); return null; } }); } protected String createUpdate(Map<Interval, Interval> oldIntervalToNew, String tabName, String wattName, String... uattNames) { StringBuilder sb = new StringBuilder(); for (Entry<Interval, Interval> e : oldIntervalToNew.entrySet()) { Interval oldInterval = e.getKey(); Interval newInterval = e.getValue(); sb.append("update "); sb.append(tabName); sb.append(" set "); boolean ufirst = true; for (String attName : uattNames) { if (!ufirst) { sb.append(","); } else { ufirst = false; } sb.append(attName); sb.append("="); sb.append(newInterval.getPost()); } sb.append(" where "); sb.append(wattName); sb.append("="); sb.append(oldInterval.getPost()); sb.append(";"); } return sb.toString(); } private void updateClassPropOrMetaclassTable(Map<Interval, Interval> oldIntervalToNew, RdfType type) throws SQLException { if (type == RdfType.CLASS) { StringBuilder t2 = new StringBuilder(); StringBuilder t35 = new StringBuilder(); String t1 = createUpdate(oldIntervalToNew, "t1000000000", "att0", "att0"); t2.append(createUpdate(oldIntervalToNew, "t2000000000", "att3", "att3")); t2.append(createUpdate(oldIntervalToNew, "t2000000000", "att4", "att4")); t35.append(createUpdate(oldIntervalToNew, "t35", "att3", "att3")); t35.append(createUpdate(oldIntervalToNew, "t35", "att4", "att4")); jdbc.execute(t1); jdbc.execute(t2.toString()); jdbc.execute(t35.toString()); // String query = "update t1000000000 set att0=" + newInterval.getPost() + " where att0=" + oldInterval.getPost(); // String t35Att3Query = "update t35 set att3=" + newInterval.getPost() + " where att3=" + oldInterval.getPost(); // String t35Att4Query = "update t35 set att4=" + newInterval.getPost() + " where att4=" + oldInterval.getPost(); // String t2000000000Att3Query = "update t2000000000 set att3=" + newInterval.getPost() + " where att3=" + oldInterval.getPost(); // String t2000000000Att4Query = "update t2000000000 set att4=" + newInterval.getPost() + " where att4=" + oldInterval.getPost(); } if (type == RdfType.PROPERTY) { String upd = createUpdate(oldIntervalToNew, "t2000000000", "att0", "att0"); jdbc.execute(upd); // String query = "update t2000000000 set att0=" + newInterval.getPost() + " where att0=" + oldInterval.getPost(); } if ((type == RdfType.METACLASS) || (type == RdfType.METAPROPERTY)) { String upd = createUpdate(oldIntervalToNew, "metaclass", "att0", "att0"); jdbc.execute(upd); // String query = "update metaclass set att0=" + newInterval.getPost() + " where att0=" + oldInterval.getPost(); } } protected abstract void updateInstanceTable(Map<Interval, Interval> oldIntervalToNew, RdfType type) throws SQLException; private void updateSubclassTable(Map<Interval, Interval> oldIntervalToNew, RdfType type) { String spanTreeTable = null; String nonSpanTreeTable = null; if (type == RdfType.CLASS) { spanTreeTable = "subclass"; nonSpanTreeTable = "class_anc"; } else if (type == RdfType.PROPERTY) { spanTreeTable = "subproperty"; nonSpanTreeTable = "property_anc"; } else if (type == RdfType.METACLASS) { spanTreeTable = "submetaclass"; nonSpanTreeTable = "metaclass_anc"; } else { spanTreeTable = "submetaproperty"; nonSpanTreeTable = "metaproperty_anc"; } String q1 = createUpdate(oldIntervalToNew, spanTreeTable, "att0", "att0", "att2"); String q2 = createUpdate(oldIntervalToNew, spanTreeTable, "att1", "att1"); // String query = "update " + spanTreeTable + " set att0=" + newInterval.getPost() + ", att2=" + newInterval.getIndex() + " where att0=" + oldInterval.getPost(); // String query2 = "update " + spanTreeTable + " set att1=" + newInterval.getPost() + " where att1=" + oldInterval.getPost(); // storageParameters.executeUpdate(query); // storageParameters.executeUpdate(query2); /*** In case of DAGs I have to update the class_anc table***/ // String query3 = "update " + nonSpanTreeTable + " set att0=" + newInterval.getPost() + ", att2=" + newInterval.getIndex() + " where att0=" + oldInterval.getPost(); // storageParameters.executeUpdate(query3); // stmt.execute(query3); // String query4 = "update " + nonSpanTreeTable + " set att1=" + newInterval.getPost() + " where att1=" + oldInterval.getPost(); // storageParameters.executeUpdate(query4); // stmt.execute(query4); String q3 = createUpdate(oldIntervalToNew, nonSpanTreeTable, "att0", "att0", "att2"); String q4 = createUpdate(oldIntervalToNew, nonSpanTreeTable, "att1", "att1"); } class Tables { protected final Namespace namespace; protected final Graphspace graphspace; protected final Graphset graphset; protected final NamespaceDependencies namespaceDependencies; protected final GraphspaceDependencies graphspaceDependencies; protected final Metaclass metaclass; protected final SubMetaclass subMetaclass; protected final SubMetaproperty subMetaproperty; protected final MetaclassAncestry metaclassAncestry; protected final MetapropertyAncestry metapropertyAncestry; //protected final Graph graph; protected final GraphTriples graphTriples; protected final LiteralType literalType; protected final Thesaurus thesaurus; protected final Enumeration enumeration; protected final SubClass subClass; protected final SubProperty subProperty; protected final ClassAncestry classAncestry; protected final PropertyAncestry propertyAncestry; protected final Generator generator; protected final SequenceTable namespaceIdGenerator; protected final SequenceTable graphspaceIdGenerator; protected final SequenceTable graphsetIdGenerator; protected final SequenceTable tripleIdGenerator; protected final SequenceTable anonIdGenerator; protected final Representation representation; protected final MaxPostOrder maxPostOrder; protected final SequenceTypes sequenceTypes; protected final BagTypes bagTypes; protected final AnonIds anonIds; protected final ClassComment classComment; protected final ClassSeeAlso classSeeAlso; protected final ClassLabel classLabel; protected final ClassIsDefinedBy classIsDefinedBy; protected final PropertyComment propertyComment; protected final PropertySeeAlso propertySeeAlso; protected final PropertyLabel propertyLabel; protected final PropertyIsDefinedBy propertyIsDefinedBy; protected final ResourceComment resourceComment; protected final ResourceSeeAlso resourceSeeAlso; protected final ResourceLabel resourceLabel; protected final ResourceIsDefinedBy resourceIsDefinedBy; protected Tables(Configurer conf) { namespace = new Namespace(conf); graphspace = new Graphspace(conf); graphset = new Graphset(conf); namespaceDependencies = new NamespaceDependencies(conf); graphspaceDependencies = new GraphspaceDependencies(conf); metaclass = new Metaclass(conf); subMetaclass = new SubMetaclass(conf); subMetaproperty = new SubMetaproperty(conf); metaclassAncestry = new MetaclassAncestry(conf); metapropertyAncestry = new MetapropertyAncestry(conf); //graph = new Graph(conf); graphTriples = new GraphTriples(conf); literalType = new LiteralType(conf); thesaurus = new Thesaurus(conf); enumeration = new Enumeration(conf); subClass = new SubClass(conf); subProperty = new SubProperty(conf); classAncestry = new ClassAncestry(conf); propertyAncestry = new PropertyAncestry(conf); generator = new Generator(conf); namespaceIdGenerator = new SequenceTable("nsid_generator", 6); graphspaceIdGenerator = new SequenceTable("gsid_generator", 2); graphsetIdGenerator = new SequenceTable("graphsetid_generator", 200001); tripleIdGenerator = new SequenceTable("tripleid_generator", 1); anonIdGenerator = new SequenceTable("anonid_generator", 1); representation = new Representation(conf); maxPostOrder = new MaxPostOrder(conf); sequenceTypes = new SequenceTypes(conf); bagTypes = new BagTypes(conf); anonIds = new AnonIds(conf); classComment = new ClassComment(conf); classSeeAlso = new ClassSeeAlso(conf); classLabel = new ClassLabel(conf); classIsDefinedBy = new ClassIsDefinedBy(conf); propertyComment = new PropertyComment(conf); propertySeeAlso = new PropertySeeAlso(conf); propertyLabel = new PropertyLabel(conf); propertyIsDefinedBy = new PropertyIsDefinedBy(conf); resourceComment = new ResourceComment(conf); resourceSeeAlso = new ResourceSeeAlso(conf); resourceLabel = new ResourceLabel(conf); resourceIsDefinedBy = new ResourceIsDefinedBy(conf); } private void createTablePerClassField() throws SQLException { Table.createAllTablesDeclaredAsFields(this); } //creates all common commonTables private void createCommonTables(RdfStores.Representation repr) throws SQLException { createTablePerClassField(); graphspace.insert(graphspace.id, graphspace.uri).values(1, RdfSuite.DEFAULT_GRAPH_URI.toString(Delimiter.WITH)); Jdbc.execute("INSERT INTO %s (%s, %s) VALUES (%d, ARRAY[1])", graphset.getName(), graphset.id.getName(), graphset.set.getName(), DEFAULT_GRAPHSET_ID); namespace.insert(namespace.id, namespace.uri).values(1, Rdf.NAMESPACE.toString(Uri.Delimiter.WITH)) .insert(namespace.id, namespace.uri).values(2, RdfSchema.NAMESPACE.toString(Uri.Delimiter.WITH)) .insert(namespace.id, namespace.uri).values(3, XmlSchema.NAMESPACE.toString(Uri.Delimiter.WITH)) .insert(namespace.id, namespace.uri).values(4, RdfSuite.NAMESPACE.toString(Uri.Delimiter.WITH)) .insert(namespace.id, namespace.uri).values(5, Owl.NAMESPACE.toString(Uri.Delimiter.WITH)); metaclass.insertRow(RdfSchema.CLASS, 2).insertRow(RdfSuite.DATA_PROPERTY, 1).insertRow(Rdf.PROPERTY, 1) .insertRow(RdfSchema.LITERAL, 4).insertRow(RdfSuite.THESAURUS, 4) .insertRow(RdfSuite.ENUMERATION, 4); subMetaclass.insert(subMetaclass.subClassId, subMetaclass.postOrder) .values(DbConstants.getIdFor(RdfSchema.CLASS), DbConstants.getPostOrderFor(RdfSchema.CLASS)); subMetaproperty.insert(subMetaproperty.subPropertyId, subMetaproperty.postOrder) .values(DbConstants.getIdFor(Rdf.PROPERTY), DbConstants.getPostOrderFor(Rdf.PROPERTY)); generator.insert(generator.namespaceCounter, generator.anonymousCounter, generator.thesaurusCounter) .values(4, 0, DbConstants.MAX_INT); subClass.insert(subClass.subId, subClass.index).values(DbConstants.getIdFor(RdfSchema.RESOURCE), DbConstants.getPostOrderFor(RdfSchema.RESOURCE)); representation.insert(representation.type).values(repr.getCode()); maxPostOrder .insert(maxPostOrder.metaclassPostOrder, maxPostOrder.metapropertyPostOrder, maxPostOrder.classPostOrder, maxPostOrder.propertyPostOrder) .values(DbConstants.INIT_POST_ORDER, DbConstants.MAX_INT / 2 + 2, DbConstants.INIT_POST_ORDER, DbConstants.INIT_POST_ORDER); commonTables.literalType .insert(commonTables.literalType.id, commonTables.literalType.namespaceId, commonTables.literalType.localPart, commonTables.literalType.kind) .values(DbConstants.getIdFor(RdfSuite.GRAPH), 2, "Literal", DbConstants.getIdFor(RdfSuite.GRAPH)); insertXmlTypes(); } private void insertXmlTypes() throws SQLException { for (Uri uri : XmlSchema.getAllTypes()) { literalType.insertXmlType(uri); } } private void createCommonIndexes() throws SQLException { namespace.clusteredIndexOn("ns", namespace.id); namespaceDependencies.indexOn("ns_deps_idx", namespaceDependencies.att0, namespaceDependencies.att1); //graph. // clusteredIndexOn("g1", graph.id); subClass.clusteredIndexOn("cls_sub_idx", subClass.subId).indexOn("cls_super_idx", subClass.superId) .indexOn("cls_index_idx", subClass.index); subProperty.clusteredIndexOn("p_sub_idx", subProperty.subId).indexOn("p_super_idx", subProperty.superId) .indexOn("p_index_idx", subProperty.index); subMetaclass.indexOn("sm_att0", subMetaclass.subClassId).indexOn("sm_att1", subMetaclass.superClassId) .indexOn("sm_att2", subMetaclass.postOrder); subMetaproperty.indexOn("smp_att0", subMetaproperty.subPropertyId) .indexOn("smp_att1", subMetaproperty.superPropertyId) .indexOn("smp_att2", subMetaproperty.postOrder); classAncestry.clusteredIndexOn("ca_att0", classAncestry.classId) .indexOn("ca_att1", classAncestry.namespaceId) .indexOn("ca_att2", classAncestry.ancestorClassId); propertyAncestry.clusteredIndexOn("pa_att0", propertyAncestry.propertyId) .indexOn("pa_att1", propertyAncestry.namespaceId) .indexOn("pa_att2", propertyAncestry.ancestorPropertyId); metaclassAncestry.indexOn("ma_att0", metaclassAncestry.childPostOrder) .indexOn("ma_att1", metaclassAncestry.parentPostOrder) .indexOn("ma_att2", metaclassAncestry.childIndex); metapropertyAncestry.indexOn("mpa_att0", metapropertyAncestry.childPostOrder) .indexOn("mpa_att1", metapropertyAncestry.parentPostOrder) .indexOn("mpa_att2", metapropertyAncestry.childIndex); sequenceTypes.indexOn("seq1_idx", sequenceTypes.att0).indexOn("seq2_idx", sequenceTypes.att1) .indexOn("seq3_idx", sequenceTypes.att2).indexOn("seq4_idx", sequenceTypes.att3); bagTypes.indexOn("bag1_idx", bagTypes.att0).indexOn("bag2_idx", bagTypes.att1).indexOn("bag3_idx", bagTypes.att2); enumeration.indexOn("emum_id_idx", enumeration.att0); } } private void initialize() throws SQLException { commonTables.createCommonTables(representation); commonTables.createCommonIndexes(); initializeRepresentation(); } abstract void initializeRepresentation() throws SQLException; static class Namespace extends Table { public final Attribute id; public final Attribute uri; private Namespace(Configurer conf) { super("NameSpace"); id = newAttribute("att0", "INTEGER PRIMARY KEY"); uri = newAttribute("att1", "VARCHAR(%s) NOT NULL UNIQUE", conf.getMaxPrefixLength()); } private static final Function<Uri, String> toStringWithHash = new Function<Uri, String>() { public String apply(Uri uri) { return uri.toString(Uri.Delimiter.WITH); } }; private Map<Uri, Integer> createNewNamespaceIds(Set<Uri> namespaces) throws SQLException { namespaces = Sets.newHashSet(namespaces); ResultSet rs = Jdbc .prepared("SELECT att1" + " FROM " + getName() + " WHERE att1 = ANY(?)", Jdbc.connection() .createArrayOf("text", Iterables.toArray( Iterables.transform(namespaces, toStringWithHash), String.class))) .executeQuery(); try { while (rs.next()) { final Uri uri = Uri.parse(rs.getString(1)); namespaces.remove(uri); } } finally { rs.close(); } //at this point, namespaces set contain only brand new namespaces InsertHelper insertHelper = new InsertHelper( "INSERT INTO NAMESPACE VALUES(nextval('nsid_generator'), ?)", "nsid_generator"); Map<Uri, Integer> map = Maps.newHashMap(); for (Uri ns : namespaces) { int id = insertHelper.executeAndGetId(ns.toString(Uri.Delimiter.WITH)); map.put(ns, id); } return map; } } static class NamespaceDependencies extends Table { public final Attribute att0; //TODO: clarify attribute public final Attribute att1; //TODO: clarify attribute public NamespaceDependencies(Configurer conf) { super("Namespace_Dependencies"); att0 = newAttribute("att0", "INTEGER"); att1 = newAttribute("att1", "INTEGER"); } } static class Graphspace extends Table { public final Attribute id; public final Attribute uri; private Graphspace(Configurer conf) { super("NamedGraph"); //super("Graphspace"); // used only to run the old importer test id = newAttribute("att0", "INTEGER PRIMARY KEY"); uri = newAttribute("att1", "VARCHAR(%s) NOT NULL UNIQUE", conf.getMaxPrefixLength()); } } static class Graphset extends Table { public final Attribute id; public final Attribute set; private Graphset(Configurer conf) { super("Graphset"); id = newAttribute("att0", "INTEGER PRIMARY KEY"); set = newAttribute("att1", "INTEGER[]"); } } static class GraphspaceDependencies extends Table { public final Attribute att0; //TODO: clarify attribute public final Attribute att1; //TODO: clarify attribute public final Attribute att2; //TODO: clarify attribute public GraphspaceDependencies(Configurer conf) { super("Graphspace_Dependencies"); att0 = newAttribute("att0", "INTEGER"); att1 = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static class Metaclass extends Table { public final Attribute classId; //this is the post order too public final Attribute namespaceId; public final Attribute localPart; public final Attribute kind; public final Attribute att4; //TODO: clarify attribute private Metaclass(Configurer conf) { super("MetaClass"); classId = newAttribute("att0", "INTEGER PRIMARY KEY"); namespaceId = newAttribute("att1", "INTEGER NOT NULL"); localPart = newAttribute("att2", "VARCHAR(%s) NOT NULL", conf.getMaxLocalPartLength()); kind = newAttribute("att3", "INTEGER NOT NULL"); att4 = newAttribute("att4", "INTEGER"); } public Metaclass insertRow(Uri uri, int nsId) throws SQLException { insert(classId, namespaceId, localPart, kind).values(DbConstants.getIdFor(uri), nsId, DbConstants.getNameFor(uri), DbConstants.getRqlKindFor(uri)); return this; } void storeMetaclasses(ImportContext context) throws SQLException { storeMetatypes(context, RdfType.METACLASS); } void storeMetaproperties(ImportContext context) throws SQLException { storeMetatypes(context, RdfType.METAPROPERTY); } private void storeMetatypes(ImportContext context, RdfType metatype) throws SQLException { //this is similar to the code that stores classes, in HybridStore, but no time to consolidate it InsertHelper insertHelper = new InsertHelper( "INSERT INTO " + getName() + " VALUES (?, ?, ?, ?, nextval('tripleid_generator'))", "tripleid_generator"); Map<Uri, Label> newLabels = context.updatedLabels.getNewLabels(metatype); final Uri target; switch (metatype) { case METACLASS: target = RdfSchema.CLASS; break; case METAPROPERTY: target = Rdf.PROPERTY; break; default: throw new AssertionError(); } for (Entry<Uri, Integer> newNamespaceEntry : context.namespaceIds.entrySet()) { Uri namespace = newNamespaceEntry.getKey(); Integer nsId = newNamespaceEntry.getValue(); for (Resource clazz : context.model.findSchemaNodes(namespace, metatype)) { Uri uri = clazz.getUri(); Triples isaTriples = context.model.triples().s(clazz).p(RdfSchema.SUBCLASSOF).o(target).fetch(); if (isaTriples.iterator().hasNext() == false) { //we just need a triple object to associate with a triple id. //for metaclasses/metaproperties, I arbitrarily put <X rdf:type rdfs:Class>, but this //should not be observable by anywhere (and will get cleaned up after the import) context.model.add().g(RdfSuite.IMPORTER_SIDE_EFFECTS).s(clazz).p(Rdf.TYPE).o(target); context.model.add().g(RdfSuite.DEFAULT_GRAPH_URI).s(clazz).p(Rdf.TYPE).o(target); } for (Triple t : isaTriples) { //the triple itself is ignored, it just gets associated with a triple id Integer nodeId = newLabels.get(uri).getTreeLabel().getPost(); int tripleId = insertHelper.executeAndGetId(nodeId, nsId, uri.getLocalName(), metatype == RdfType.METACLASS ? 2 : 3); //bonus points for another pair of magic numbers! //the last part obviously belongs to DbConstants. //But that's a huge mess, Vassilis designed it, Vassilis should clean it up :-) context.tripleIds.put(tripleId, t); } } } } } static class SubMetaclass extends IsaTable { public final Attribute subClassId; public final Attribute superClassId; public final Attribute postOrder; public final Attribute att3; //TODO: clarify attribute private SubMetaclass(Configurer conf) { super("SubMetaClass", RdfType.METACLASS); subClassId = newAttribute("att0", "INTEGER NOT NULL"); superClassId = newAttribute("att1", "INTEGER"); postOrder = newAttribute("att2", "INTEGER NOT NULL"); att3 = newAttribute("att3", "INTEGER"); } } static class SubMetaproperty extends IsaTable { public final Attribute subPropertyId; public final Attribute superPropertyId; public final Attribute postOrder; public final Attribute att3; //TODO: clarify field private SubMetaproperty(Configurer conf) { super("SubMetaProperty", RdfType.METAPROPERTY); subPropertyId = newAttribute("att0", "INTEGER NOT NULL"); superPropertyId = newAttribute("att1", "INTEGER"); postOrder = newAttribute("att2", "INTEGER NOT NULL"); att3 = newAttribute("att3", "INTEGER"); } } static class MetaclassAncestry extends PropagatedIsaTable { public final Attribute childPostOrder; public final Attribute parentPostOrder; public final Attribute childIndex; public final Attribute isDirectChild; public final Attribute att4; //TODO: clarify field private MetaclassAncestry(Configurer conf) { super("Metaclass_Anc", RdfType.METACLASS); childPostOrder = newAttribute("att0", "INTEGER NOT NULL"); parentPostOrder = newAttribute("att1", "INTEGER"); childIndex = newAttribute("att2", "INTEGER NOT NULL"); isDirectChild = newAttribute("att3", "boolean NOT NULL"); att4 = newAttribute("att4", "INTEGER"); } } static class MetapropertyAncestry extends PropagatedIsaTable { public final Attribute childPostOrder; public final Attribute parentPostOrder; public final Attribute childIndex; public final Attribute isDirectChild; public final Attribute att4; //TODO: clarify field private MetapropertyAncestry(Configurer conf) { super("MetaProperty_Anc", RdfType.METAPROPERTY); childPostOrder = newAttribute("att0", "INTEGER NOT NULL"); parentPostOrder = newAttribute("att1", "INTEGER"); childIndex = newAttribute("att2", "INTEGER NOT NULL"); isDirectChild = newAttribute("att3", "boolean NOT NULL"); att4 = newAttribute("att4", "INTEGER"); } } static class Graph extends Table { public final Attribute uri; public final Attribute id; private Graph(Configurer conf) { super("Graph"); uri = newAttribute("att0", "VARCHAR(%s) NOT NULL", conf.getMaxPrefixLength()); id = newAttribute("att1", "INTEGER NOT NULL"); } } static class GraphTriples extends Table { //public final Attribute uri; public final Attribute graphsetId; public final Attribute tripleId; private GraphTriples(Configurer conf) { super("GraphTriples"); graphsetId = newAttribute("att0", "INTEGER NOT NULL"); tripleId = newAttribute("att1", "INTEGER NOT NULL"); } } static class LiteralType extends Table { public final Attribute id; public final Attribute namespaceId; public final Attribute localPart; public final Attribute kind; private LiteralType(Configurer conf) { super("t" + DbConstants.getIdFor(RdfSchema.LITERAL)); id = newAttribute("att0", "INTEGER PRIMARY KEY"); namespaceId = newAttribute("att1", "INTEGER NOT NULL"); localPart = newAttribute("att2", "VARCHAR(%s) NOT NULL", conf.getMaxLocalPartLength()); kind = newAttribute("att3", "INTEGER UNIQUE"); } public LiteralType insertXmlType(Uri uri) throws SQLException { insert(id, namespaceId, localPart, kind).values(DbConstants.getIdFor(uri), 3, uri.getLocalName(), DbConstants.getRqlKindFor(uri)); return this; } } static class Thesaurus extends Table { public final Attribute id; public final Attribute att1; //TODO: clarify field public final Attribute att2; //TODO: clarify field private Thesaurus(Configurer conf) { super("t" + DbConstants.getIdFor(RdfSuite.THESAURUS)); id = newAttribute("att0", "INTEGER PRIMARY KEY"); att1 = newAttribute("att1", "INTEGER NOT NULL"); att2 = newAttribute("att2", "INTEGER NOT NULL"); } } static class Enumeration extends Table { public final Attribute att0; //TODO: clarify field public final Attribute att1; //TODO: clarify field private Enumeration(Configurer conf) { super("t" + DbConstants.getIdFor(RdfSuite.ENUMERATION)); att0 = newAttribute("att0", "INTEGER NOT NULL"); att1 = newAttribute("att1", "VARCHAR(%s) NOT NULL", conf.getMaxLiteralLength()); } } static abstract class IsaTable extends Table { private final RdfType type; public IsaTable(String name, RdfType type) { super(name); this.type = type; } void storeIsaRelationships(ImportContext context) throws SQLException { UpdatedLabels labels = context.updatedLabels; InsertHelper insertHelper = new InsertHelper( "INSERT INTO " + getName() + " VALUES (?, ?, ?, nextval('tripleid_generator'))", "tripleid_generator"); System.out.println("storeISaRelationships: RDF TYPE = " + type); String findUriTablename = ""; String triplePredicate = ""; // I don' t like the following check but... if (type.equals(RdfType.CLASS)) { findUriTablename = "t1000000000"; triplePredicate = RdfSchema.SUBCLASSOF.toString(); } else if (type.equals(RdfType.PROPERTY)) { findUriTablename = "t2000000000"; triplePredicate = RdfSchema.SUBPROPERTYOF.toString(); } else if (type.equals(RdfType.METACLASS)) { findUriTablename = "metaclass"; triplePredicate = RdfSchema.SUBCLASSOF.toString(); } else if (type.equals(RdfType.METAPROPERTY)) { findUriTablename = "metaclass"; triplePredicate = RdfSchema.SUBPROPERTYOF.toString(); } Map<Uri, Label> labelsToStore = labels.getNewLabels(type); Map<Integer, Integer> kidsToParents = labels.getNewKidsToParents(type); for (Entry<Uri, Label> labelEntry : labels.getNewLabels(type).entrySet()) { Uri uri = labelEntry.getKey(); if (!context.isNewNamespace(uri.getNamespaceUri())) { continue; } Label label = labelEntry.getValue(); System.out .println("storeIsaRelationships: Uri = " + uri.toString() + " Label = " + label.toString()); final Interval interval = label.getTreeLabel(); System.out.println("Saving in " + this.getName() + " the ISA relationship between " + interval.getPost() + " and " + kidsToParents.get(interval.getPost())); Map<Integer, Integer> map = Maps.newHashMap(); map.put(interval.getPost(), kidsToParents.get(interval.getPost())); Triple relationshipTriple = labels.getRelationshipTriple(map); if (relationshipTriple == null) { System.out.println("Not found triple for the ISA relationship between " + interval.getPost() + " and " + kidsToParents.get(interval.getPost())); if (kidsToParents.get(interval.getPost()) != null) { Uri parentUri = context.findSchemaUrifromDB(findUriTablename, kidsToParents.get(interval.getPost()).intValue()); for (Uri namedGraph : new Uri[] { RdfSuite.IMPORTER_SIDE_EFFECTS, RdfSuite.DEFAULT_GRAPH_URI }) context.model.add().g(namedGraph).s(uri).p(triplePredicate).o(parentUri); Iterator triplesIterator = context.model.triples().g(RdfSuite.DEFAULT_GRAPH_URI).s(uri) .p((type.equals(RdfType.CLASS)) ? RdfSchema.SUBCLASSOF : RdfSchema.SUBPROPERTYOF) .o(parentUri).fetch().iterator(); relationshipTriple = (Triple) triplesIterator.next(); System.out.println("ADDED triple: " + relationshipTriple); } } else System.out.println("FOUND triple: " + relationshipTriple); int id = insertHelper.executeAndGetId(interval.getPost(), kidsToParents.get(interval.getPost()), interval.getIndex()); context.tripleIds.put(id, relationshipTriple); for (Interval directDagInterval : label.getPropagatedLabels(true)) { //also store direct propagated labels System.out.println("Saving in " + this.getName() + " the propagated ISA relationship between " + directDagInterval.getPost() + " and " + interval.getPost()); Map<Integer, Integer> map2 = Maps.newHashMap(); map2.put(directDagInterval.getPost(), interval.getPost()); Triple relationshipTripleProp = labels.getRelationshipTriple(map2); if (relationshipTripleProp == null) { System.out.println("DIRECT: Not found triple for the ISA relationship between " + directDagInterval.getPost() + " and " + interval.getPost()); if (directDagInterval.getPost() != 0) { Uri childUri = context.findSchemaUrifromDB(findUriTablename, directDagInterval.getPost()); for (Uri namedGraph : new Uri[] { RdfSuite.IMPORTER_SIDE_EFFECTS, RdfSuite.DEFAULT_GRAPH_URI }) context.model.add().g(namedGraph).s(childUri).p(triplePredicate).o(uri); Iterator triplesIterator = context.model.triples().g(RdfSuite.DEFAULT_GRAPH_URI) .s(childUri).p((type.equals(RdfType.CLASS)) ? RdfSchema.SUBCLASSOF : RdfSchema.SUBPROPERTYOF) .o(uri).fetch().iterator(); relationshipTripleProp = (Triple) triplesIterator.next(); System.out.println("DIRECT - ADDED triple: " + relationshipTripleProp); } } else System.out.println("DIRECT: FOUND triple: " + relationshipTripleProp); int id2 = insertHelper.executeAndGetId(directDagInterval.getPost(), interval.getPost(), directDagInterval.getIndex()); context.tripleIds.put(id2, relationshipTripleProp); } } } } static abstract class PropagatedIsaTable extends Table { private final RdfType type; PropagatedIsaTable(String name, RdfType type) { super(name); this.type = type; } void storePropagated(ImportContext context) throws SQLException { UpdatedLabels labels = context.updatedLabels; InsertHelper insertHelper = new InsertHelper( "INSERT INTO " + getName() + " VALUES (?, ?, ?, ?, nextval('tripleid_generator'))", "tripleid_generator"); Map<Uri, Label> newLabels = labels.getNewLabels(type); for (boolean direct : new boolean[] { true, false }) { for (Entry<Uri, Label> labelEntry : newLabels.entrySet()) { Uri uri = labelEntry.getKey(); Label parentLabel = labelEntry.getValue(); Interval parentInterval = parentLabel.getTreeLabel(); for (Interval interval : parentLabel.getPropagatedLabels(direct)) { Map<Integer, Integer> map = Maps.newHashMap(); map.put(interval.getPost(), parentInterval.getPost()); Triple relationshipTriple = labels.getRelationshipTriple(map); if (relationshipTriple == null) { //Uri childUri = context.findSchemaUrifromDB(type == RdfType.CLASS ? "t1000000000" : "t2000000000", interval.getPost()); System.out.println( "PROPAGATED: Not found triple for the Propagated ISA relationship between " + interval.getPost() + " and " + parentInterval.getPost()); /*for (Uri namedGraph : new Uri[] { RdfSuite.IMPORTER_SIDE_EFFECTS, RdfSuite.DEFAULT_GRAPH_URI} ) context.model.add().g(namedGraph).s(childUri).p((type.equals(RdfType.CLASS))? RdfSchema.SUBCLASSOF : RdfSchema.SUBPROPERTYOF ).o(uri); Iterator triplesIterator = context.model.triples().g(RdfSuite.DEFAULT_GRAPH_URI).s(childUri).p((type.equals(RdfType.CLASS))? RdfSchema.SUBCLASSOF : RdfSchema.SUBPROPERTYOF ).o(uri).fetch().iterator(); relationshipTriple = (Triple)triplesIterator.next();*/ } else System.out.println("PROPAGATED: FOUND triple: " + relationshipTriple); int id = insertHelper.executeAndGetId(interval.getPost(), parentInterval.getPost(), interval.getIndex(), direct); context.tripleIds.put(id, relationshipTriple); } } } } } static abstract class RdfSchemaDocumentationTable extends Table { private final RdfType type; private final Uri schemaUri; public RdfSchemaDocumentationTable(String name, RdfType type, Uri uri) { super(name); this.type = type; this.schemaUri = uri; } void storeRdfSchemaDocumentationTriples(ImportContext context) throws SQLException { InsertHelper insertHelper = null; boolean boolCaseResource = false; String att0 = ""; System.out.println("storeRdfSchemaDocumentationTriples: type = " + type.toString() + ", schemaUri = " + this.schemaUri.toString()); if (type.equals(RdfType.CLASS) || type.equals(RdfType.PROPERTY)) { insertHelper = new InsertHelper( "INSERT INTO " + getName() + " VALUES (?, ?, nextval('tripleid_generator'))", "tripleid_generator"); } else { insertHelper = new InsertHelper( "INSERT INTO " + getName() + " VALUES (?, ?, nextval('tripleid_generator'), ?)", "tripleid_generator"); boolCaseResource = true; } for (Triple triple : context.model.triples().p(schemaUri).fetch()) { System.out.println("storeRdfSchemaDocumentationTriples: triple.subject = " + triple.subject().getIdentifier() + ", triple.predicate = " + triple.predicate().getIdentifier() + ", triple.object = " + (triple.object().isResource() ? ((Resource) triple.object()).getUri().toString() : ((LiteralNode) triple.object()).getLiteral().getValue())); String att1 = ""; int newTripleId = 0; if (!triple.subject().type().equals(type)) { continue; } if (boolCaseResource) { att0 = ((gr.forth.ics.swkm.model2.Resource) triple.subject()).getUri().toString(); } else { att0 = String.valueOf(context.updatedLabels .getLabel(type, ((gr.forth.ics.swkm.model2.Resource) triple.subject()).getUri()) .getTreeLabel().getPost()); } if (triple.object().type().equals(RdfType.CLASS) || triple.object().type().equals(RdfType.PROPERTY)) att1 = String.valueOf(context.updatedLabels .getLabel(triple.object().type(), ((gr.forth.ics.swkm.model2.Resource) triple.object()).getUri()) .getTreeLabel().getPost()); else if (triple.object().type().equals(RdfType.INDIVIDUAL)) att1 = ((gr.forth.ics.swkm.model2.Resource) triple.object()).getUri().toString(); else att1 = ((LiteralNode) triple.object()).getLiteral().getValue(); if (!checkExistenceDocumentationDB(this.getName(), boolCaseResource, att0, att1)) { if (!boolCaseResource) { newTripleId = insertHelper.executeAndGetId(Integer.parseInt(att0), triple.object().type().equals(RdfType.CLASS) || triple.object().type().equals(RdfType.PROPERTY) ? Integer.parseInt(att1) : ((LiteralNode) triple.object()).getLiteral().getValue()); context.tripleIds.put(newTripleId, triple); } else { Triples resourceTypeTriples = context.model.triples() .s((gr.forth.ics.swkm.model2.Resource) triple.subject()).p(Rdf.TYPE).fetch(); if (!resourceTypeTriples.iterator().hasNext()) { context.model.add().g(RdfSuite.IMPORTER_SIDE_EFFECTS) .s((gr.forth.ics.swkm.model2.Resource) triple.subject()).p(Rdf.TYPE) .o(RdfSchema.RESOURCE); context.model.add().g(RdfSuite.DEFAULT_GRAPH_URI) .s((gr.forth.ics.swkm.model2.Resource) triple.subject()).p(Rdf.TYPE) .o(RdfSchema.RESOURCE); } for (Triple t : resourceTypeTriples) { newTripleId = insertHelper.executeAndGetId(att0, att1, context.updatedLabels .getLabel(RdfType.CLASS, ((gr.forth.ics.swkm.model2.Resource) t.object()).getUri()) .getTreeLabel().getPost()); context.tripleIds.put(newTripleId, triple); } } } } } private boolean checkExistenceDocumentationDB(String tablename, boolean boolAtt0String, String att0, String att1) throws SQLException { java.sql.PreparedStatement pstmt = Jdbc .prepared(String.format("SELECT 1 FROM %s where att0 = ? and att1 = ?", tablename)); if (boolAtt0String) pstmt.setString(1, att0); else pstmt.setInt(1, Integer.parseInt(att0)); pstmt.setString(2, att1); //String sql = "SELECT 1 FROM %s WHERE att0 = "; //sql += boolAtt0String ? "'%s'" : "%d"; //sql += " AND att1 = '%s'"; //ResultSet rs = Jdbc.query(String.format(sql, tablename, boolAtt0String ? att0 : Integer.parseInt(att0), att1)); ResultSet rs = pstmt.executeQuery(); try { return rs.next(); } finally { rs.close(); } } } static class SubClass extends IsaTable { public final Attribute subId; public final Attribute superId; public final Attribute index; public final Attribute tripleId; private SubClass(Configurer conf) { super("SubClass", RdfType.CLASS); subId = newAttribute("att0", "INTEGER NOT NULL"); superId = newAttribute("att1", "INTEGER"); index = newAttribute("att2", "INTEGER NOT NULL"); tripleId = newAttribute("att3", "INTEGER"); } } static class SubProperty extends IsaTable { public final Attribute subId; public final Attribute superId; public final Attribute index; public final Attribute tripleId; private SubProperty(Configurer conf) { super("SubProperty", RdfType.PROPERTY); subId = newAttribute("att0", "INTEGER NOT NULL"); superId = newAttribute("att1", "INTEGER"); index = newAttribute("att2", "INTEGER NOT NULL"); tripleId = newAttribute("att3", "INTEGER"); } } static class ClassAncestry extends PropagatedIsaTable { public final Attribute classId; public final Attribute namespaceId; public final Attribute ancestorClassId; public final Attribute isDirectChild; public final Attribute tripleId; private ClassAncestry(Configurer conf) { super("Class_Anc", RdfType.CLASS); classId = newAttribute("att0", "INTEGER NOT NULL"); namespaceId = newAttribute("att1", "INTEGER"); ancestorClassId = newAttribute("att2", "INTEGER NOT NULL"); isDirectChild = newAttribute("att3", "boolean NOT NULL"); tripleId = newAttribute("att4", "INTEGER"); } } static class PropertyAncestry extends PropagatedIsaTable { public final Attribute propertyId; public final Attribute namespaceId; public final Attribute ancestorPropertyId; public final Attribute isDirectChild; public final Attribute tripleId; private PropertyAncestry(Configurer conf) { super("Property_Anc", RdfType.PROPERTY); propertyId = newAttribute("att0", "INTEGER NOT NULL"); namespaceId = newAttribute("att1", "INTEGER"); ancestorPropertyId = newAttribute("att2", "INTEGER NOT NULL"); isDirectChild = newAttribute("att3", "boolean NOT NULL"); tripleId = newAttribute("att4", "INTEGER"); } } static class Generator extends Table { public final Attribute namespaceCounter; public final Attribute anonymousCounter; public final Attribute thesaurusCounter; private Generator(Configurer conf) { super("Generator"); namespaceCounter = newAttribute("att0", "INTEGER NOT NULL"); anonymousCounter = newAttribute("att1", "INTEGER NOT NULL"); thesaurusCounter = newAttribute("att2", "INTEGER NOT NULL"); } } static class Representation extends Table { public final Attribute type; private Representation(Configurer conf) { super("REPRESENTATION"); type = newAttribute("att0", "INTEGER NOT NULL"); } } static class MaxPostOrder extends Table { public final Attribute metaclassPostOrder; public final Attribute metapropertyPostOrder; public final Attribute classPostOrder; public final Attribute propertyPostOrder; private MaxPostOrder(Configurer conf) { super("max_postorder"); metaclassPostOrder = newAttribute("att0", "INTEGER NOT NULL"); metapropertyPostOrder = newAttribute("att1", "INTEGER NOT NULL"); classPostOrder = newAttribute("att2", "INTEGER NOT NULL"); propertyPostOrder = newAttribute("att3", "INTEGER NOT NULL"); } } static class SequenceTypes extends Table { public final Attribute att0; //TODO: clarify attribute public final Attribute att1; //TODO: clarify attribute public final Attribute att2; //TODO: clarify attribute public final Attribute att3; //TODO: clarify attribute private SequenceTypes(Configurer conf) { super("seqtypes"); att0 = newAttribute("att0", "INTEGER"); att1 = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); att3 = newAttribute("att3", "INTEGER"); } } static class BagTypes extends Table { public final Attribute att0; //TODO: clarify attribute public final Attribute att1; //TODO: clarify attribute public final Attribute att2; //TODO: clarify attribute private BagTypes(Configurer conf) { super("bagtypes"); att0 = newAttribute("att0", "INTEGER"); att1 = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static abstract class ClassNote extends RdfSchemaDocumentationTable { public final Attribute classId; private ClassNote(String name, Uri uri) { super(name, RdfType.CLASS, uri); classId = newAttribute("att0", "INTEGER"); } } static abstract class PropertyNote extends RdfSchemaDocumentationTable { public final Attribute propertyId; private PropertyNote(String name, Uri uri) { super(name, RdfType.PROPERTY, uri); propertyId = newAttribute("att0", "INTEGER"); } } static abstract class ResourceNote extends RdfSchemaDocumentationTable { public final Attribute resourceUri; private ResourceNote(String name, Uri uri, Configurer conf) { super(name, RdfType.INDIVIDUAL, uri); resourceUri = newAttribute("att0", "VARCHAR(%d)", conf.getMaxUriLength()); } } static class ClassComment extends ClassNote { public final Attribute comment; public final Attribute att2; //TODO: clarify attribute private ClassComment(Configurer conf) { super("ClassComment", RdfSchema.COMMENT); comment = newAttribute("att1", "TEXT"); att2 = newAttribute("att2", "INTEGER"); } } static class PropertyComment extends PropertyNote { public final Attribute comment; public final Attribute att2; //TODO: clarify attribute private PropertyComment(Configurer conf) { super("PropertyComment", RdfSchema.COMMENT); comment = newAttribute("att1", "TEXT"); att2 = newAttribute("att2", "INTEGER"); } } static class ResourceComment extends ResourceNote { public final Attribute comment; public final Attribute att2; //TODO: clarify attribute public final Attribute att3; //TODO: clarify attribute private ResourceComment(Configurer conf) { super("ResourceComment", RdfSchema.COMMENT, conf); comment = newAttribute("att1", "TEXT"); att2 = newAttribute("att2", "INTEGER"); att3 = newAttribute("att3", "INTEGER"); } } static class ClassLabel extends ClassNote { public final Attribute label; public final Attribute att2; //TODO: clarify attribute private ClassLabel(Configurer conf) { super("ClassLabel", RdfSchema.LABEL); label = newAttribute("att1", "VARCHAR(%d)", conf.getSmallMaxLiteralLength()); att2 = newAttribute("att2", "INTEGER"); } } static class PropertyLabel extends PropertyNote { public final Attribute label; public final Attribute att2; //TODO: clarify attribute private PropertyLabel(Configurer conf) { super("PropertyLabel", RdfSchema.LABEL); label = newAttribute("att1", "VARCHAR(%d)", conf.getSmallMaxLiteralLength()); att2 = newAttribute("att2", "INTEGER"); } } static class ResourceLabel extends ResourceNote { public final Attribute label; public final Attribute att2; //TODO: clarify attribute public final Attribute att3; //TODO: clarify attribute private ResourceLabel(Configurer conf) { super("ResourceLabel", RdfSchema.LABEL, conf); label = newAttribute("att1", "VARCHAR(%d)", conf.getSmallMaxLiteralLength()); att2 = newAttribute("att2", "INTEGER"); att3 = newAttribute("att3", "INTEGER"); } } static class ClassSeeAlso extends ClassNote { public final Attribute seeAlso; public final Attribute att2; //TODO: clarify attribute private ClassSeeAlso(Configurer conf) { super("ClassSeeAlso", RdfSchema.SEEALSO); seeAlso = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static class PropertySeeAlso extends PropertyNote { public final Attribute seeAlso; public final Attribute att2; //TODO: clarify attribute private PropertySeeAlso(Configurer conf) { super("PropertySeeAlso", RdfSchema.SEEALSO); seeAlso = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static class ResourceSeeAlso extends ResourceNote { public final Attribute seeAlso; public final Attribute att2; //TODO: clarify attribute public final Attribute att3; //TODO: clarify attribute private ResourceSeeAlso(Configurer conf) { super("ResourceSeeAlso", RdfSchema.SEEALSO, conf); seeAlso = newAttribute("att1", "VARCHAR(%d)", conf.getSmallMaxLiteralLength()); att2 = newAttribute("att2", "INTEGER"); att3 = newAttribute("att3", "INTEGER"); } } static class ClassIsDefinedBy extends ClassNote { public final Attribute isDefinedBy; public final Attribute att2; //TODO: clarify attribute private ClassIsDefinedBy(Configurer conf) { super("ClassIsDefinedBy", RdfSchema.ISDEFINEDBY); isDefinedBy = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static class PropertyIsDefinedBy extends PropertyNote { public final Attribute isDefinedBy; public final Attribute att2; //TODO: clarify field private PropertyIsDefinedBy(Configurer conf) { super("PropertyIsDefinedBy", RdfSchema.ISDEFINEDBY); isDefinedBy = newAttribute("att1", "INTEGER"); att2 = newAttribute("att2", "INTEGER"); } } static class ResourceIsDefinedBy extends ResourceNote { public final Attribute isDefinedBy; public final Attribute att2; //TODO: clarify attribute public final Attribute att3; //TODO: clarify attribute private ResourceIsDefinedBy(Configurer conf) { super("ResourceIsDefinedBy", RdfSchema.ISDEFINEDBY, conf); isDefinedBy = newAttribute("att1", "VARCHAR(%d)", conf.getSmallMaxLiteralLength()); att2 = newAttribute("att2", "INTEGER"); att3 = newAttribute("att3", "INTEGER"); } } static class AnonIds extends Table { public final Attribute att0; //TODO: clarify attribute private AnonIds(Configurer conf) { super("AnonIds"); att0 = newAttribute("att0", "INTEGER PRIMARY KEY"); } } public void store(final Model model) throws SQLException { jdbc.doInConnection(new ConnectionTask<Void>() { public Void execute() throws SQLException { Jdbc.connection().setAutoCommit(false); storeImpl(model); Jdbc.connection().commit(); return null; } }); } private void storeImpl(Model model) throws SQLException { final Multimap<Resource, Triple> triples = HashMultimap.create(); TripleListener listener = new TripleListener() { public void onTripleAddition(Resource namedGraph, Triple triple) { } public void onTripleDeletion(Resource namedGraph, Triple triple) { //System.out.println(triple); triples.put(namedGraph, triple); } }; model.addTripleListener(listener); try { Inference.reduce(model); try { DbSynchronizer synchronizer = DbSynchronizer.forModel(model); KnownDbState dbState = synchronizer.synchronize(RdfSuite.IMPORTER_SIDE_EFFECTS); System.out.println("MODEL INSIDE STORE: " + model); Validator.defaultValidator().validateAndFailOnFirstError(model); UpdatedLabels labels = dbState.recalculateLabels(); storeModel(model, labels); } catch (Throwable t) { throw new RuntimeException(t); } finally { for (Triple t : model.triples().g(RdfSuite.IMPORTER_SIDE_EFFECTS).fetch()) { t.delete(); } } } finally { model.removeTripleListener(listener); for (Entry<Resource, Triple> entry : triples.entries()) { Triple t = entry.getValue(); model.add(entry.getKey(), t.subject(), t.predicate(), t.object()); } } } protected final void storeModel(Model model, UpdatedLabels labels) throws SQLException { ImportContext context = new ImportContext(model, labels); updateExistingLabels(context); storeClasses(context); storeClassHierarchy(context); storeProperties(context); storePropertyHierarchy(context); storeMetaclasses(context); storeMetaclassHierarchy(context); storeMetaproperties(context); storeMetapropertyHierarchy(context); storeNamespaceDependencies(context); storePropertyInstances(context); storeRdfSchemaComment(context); storeRdfSchemaIsDefinedBy(context); storeRdfSchemaLabel(context); storeRdfSchemaSeeAlso(context); storeResources(context); storeNamedGraphs(context); } private void updateExistingLabels(ImportContext context) throws SQLException { UpdatedLabels updatedLabels = context.updatedLabels; Map<Interval, Interval> oldIntervalToNew = Maps.newHashMap(); Map<Interval, RdfType> oldIntervalToType = Maps.newHashMap(); final SetMultimap<RdfType, Interval> typeToOldInterval = HashMultimap.create(); //Two cases: //1) Nodes for which we have their URI. for (Uri oldResource : updatedLabels.getOldLabels().getResourcesWithPredefinedLabels()) { RdfType type = context.model.mapResource(oldResource).type(); Label oldLabel = updatedLabels.getOldLabels().predefinedLabelOf(oldResource); //Do we have a new label for this URI? Label newLabel = updatedLabels.getNewLabels(type).get(oldResource); if (newLabel != null) { oldIntervalToNew.put(oldLabel.getTreeLabel(), newLabel.getTreeLabel()); oldIntervalToType.put(oldLabel.getTreeLabel(), type); typeToOldInterval.put(type, oldLabel.getTreeLabel()); } } //2) Nodes for which we only know their old tree interval: all of them need to be updated for (RdfType type : EnumSet.of(RdfType.CLASS, RdfType.METACLASS, RdfType.PROPERTY, RdfType.METAPROPERTY)) { Map<Interval, Label> map = updatedLabels.getUpdatedLabelsByInterval(type); for (Entry<Interval, Label> entry : map.entrySet()) { Interval oldLabel = entry.getKey(); Label newLabel = entry.getValue(); oldIntervalToNew.put(oldLabel, newLabel.getTreeLabel()); oldIntervalToType.put(oldLabel, type); typeToOldInterval.put(type, oldLabel); } } for (final RdfType type : EnumSet.of(RdfType.CLASS, RdfType.METACLASS, RdfType.PROPERTY, RdfType.METAPROPERTY)) { Predicate<Interval> predicate = new Predicate<Interval>() { public boolean apply(Interval interval) { return typeToOldInterval.get(type).contains(interval); } }; Map<Interval, Interval> filtered = Maps.filterKeys(oldIntervalToNew, predicate); if (!filtered.isEmpty()) { updateResourceLabels(filtered, type); } } } protected void updateResourceLabels(Map<Interval, Interval> oldIntervalToNew, RdfType type) throws SQLException { updateClassPropOrMetaclassTable(oldIntervalToNew, type); updateSubclassTable(oldIntervalToNew, type); if ((type == RdfType.CLASS) || (type == RdfType.PROPERTY)) { updateInstanceTable(oldIntervalToNew, type); } } protected void storeClassHierarchy(ImportContext context) throws SQLException { commonTables.subClass.storeIsaRelationships(context); commonTables.classAncestry.storePropagated(context); } protected void storeClasses(ImportContext context) throws SQLException { throw new UnsupportedOperationException(); } protected void storePropertyHierarchy(ImportContext context) throws SQLException { commonTables.subProperty.storeIsaRelationships(context); commonTables.propertyAncestry.storePropagated(context); } protected void storeProperties(ImportContext context) throws SQLException { throw new UnsupportedOperationException(); } protected void storeMetaclassHierarchy(ImportContext context) throws SQLException { commonTables.subMetaclass.storeIsaRelationships(context); commonTables.metaclassAncestry.storePropagated(context); } protected void storeMetaclasses(ImportContext context) throws SQLException { commonTables.metaclass.storeMetaclasses(context); } protected void storeMetapropertyHierarchy(ImportContext context) throws SQLException { commonTables.subMetaproperty.storeIsaRelationships(context); commonTables.metapropertyAncestry.storePropagated(context); } protected void storeMetaproperties(ImportContext context) throws SQLException { commonTables.metaclass.storeMetaproperties(context); } protected void storeNamedGraphs(ImportContext context) throws SQLException { int graphsetId = 0; int graphId = 0; Map<Uri, Integer> mapNamedGraphToGraphsetId = Maps.newHashMap(); InsertHelper insertHelper = new InsertHelper("INSERT INTO " + this.commonTables.graphset.getName() + " VALUES (nextval('graphsetid_generator'), ARRAY[?])", "graphsetid_generator"); InsertHelper insertHelperNamedGraph = new InsertHelper( "INSERT INTO " + this.commonTables.graphspace.getName() + " VALUES (nextval('gsid_generator'), ?)", "gsid_generator"); //System.out.println("storeNamedGraphs: context.tripleids = " + context.tripleIds.size()); for (gr.forth.ics.swkm.model2.Resource resource : context.model.namedGraphs()) { //System.out.println("storeNamedGraphs: Named Graph = " + resource.getUri().toString(Uri.Delimiter.WITH)); if (!resource.is(RdfSuite.IMPORTER_SIDE_EFFECTS)) { Iterator triplesIterator = context.model.triples().g(resource).fetch().iterator(); if (resource.equals(context.model.defaultNamedGraph())) { graphId = 1; graphsetId = DEFAULT_GRAPHSET_ID; } else { if (!checkExistenceNamedGraphDB(resource.getUri())) //this.commonTables.graphspace.insert(this.commonTables.graphspace.id, this.commonTables.graphspace.uri).values(this.commonTables.graphspaceIdGenerator.nextValue(), resource.getUri().toString(Uri.Hash.WITH)); { graphId = insertHelperNamedGraph .executeAndGetId(resource.getUri().toString(Uri.Delimiter.WITH)); } else { graphId = findNamedGraphIDfromDB(resource.getUri()); } if (triplesIterator.hasNext() && !checkExistenceGraphsetDB(graphId)) { graphsetId = insertHelper.executeAndGetId(graphId); } } mapNamedGraphToGraphsetId.put(resource.getUri(), graphsetId); } } Iterator contextTriples = context.tripleIds.keySet().iterator(); while (contextTriples.hasNext()) { int tripleId = (Integer) contextTriples.next(); Triple triple = context.tripleIds.get(tripleId); if (triple != null) { for (gr.forth.ics.swkm.model2.Resource resource : triple.graphs()) if (!resource.is(RdfSuite.IMPORTER_SIDE_EFFECTS)) this.commonTables.graphTriples .insert(this.commonTables.graphTriples.graphsetId, this.commonTables.graphTriples.tripleId) .values(mapNamedGraphToGraphsetId.get(resource.getUri()), tripleId); } else this.commonTables.graphTriples .insert(this.commonTables.graphTriples.graphsetId, this.commonTables.graphTriples.tripleId) .values(DEFAULT_GRAPHSET_ID, tripleId); } } protected void storeNamespaceDependencies(ImportContext context) throws SQLException { NamespaceDependenciesIndex index = new NamespaceDependenciesIndex(context.model); Iterator nsIterator = context.model.namespaces().iterator(); while (nsIterator.hasNext()) { Uri ns = (Uri) nsIterator.next(); Iterator nsDependencies = index.getDependencies(ns, gr.forth.ics.swkm.model2.Transitively.NO) .iterator(); while (nsDependencies.hasNext()) { Uri nsDependency = (Uri) nsDependencies.next(); System.out.println("storeNamespaceDependencies: namespace = " + ns.toString(Uri.Delimiter.WITH) + ", dependent on namespace = " + nsDependency.toString(Uri.Delimiter.WITH)); if (context.namespaceIds.containsKey(ns)) { // the examined namespace is a new namespace... if (context.namespaceIds.containsKey(nsDependency)) // the namespace nsDependency which the ns namespace depends on is a new namespace too.. { this.commonTables.namespaceDependencies .insert(this.commonTables.namespaceDependencies.att0, this.commonTables.namespaceDependencies.att1) .values(context.namespaceIds.get(ns), context.namespaceIds.get(nsDependency)); } else // the namespace nsDependency which the ns namespace depends on is NOT a new namespace.. // I must search it in the DB { this.commonTables.namespaceDependencies .insert(this.commonTables.namespaceDependencies.att0, this.commonTables.namespaceDependencies.att1) .values(context.namespaceIds.get(ns), findNamespaceIDfromDB(nsDependency)); } } else { // the examined namespace is NOT a new namespace int nsId = findNamespaceIDfromDB(ns); if (context.namespaceIds.containsKey(nsDependency)) // the namespace nsDependency which the ns namespace depends on is a new namespace.. { this.commonTables.namespaceDependencies .insert(this.commonTables.namespaceDependencies.att0, this.commonTables.namespaceDependencies.att1) .values(nsId, context.namespaceIds.get(nsDependency)); } else { // the namespace nsDependency which the ns namespace depends on is NOT a new namespace.. // I must search it in the DB int nsDependencyId = findNamespaceIDfromDB(nsDependency); // save the dependency only if it doesnt' already exist in DB if (!checkExistenceNamespaceDependencyDB(nsId, nsDependencyId)) { this.commonTables.namespaceDependencies .insert(this.commonTables.namespaceDependencies.att0, this.commonTables.namespaceDependencies.att1) .values(nsId, nsDependencyId); } } } } } } protected void storePropertyInstances(ImportContext context) throws SQLException { throw new UnsupportedOperationException(); } protected void storeResources(ImportContext context) throws SQLException { throw new UnsupportedOperationException(); } protected void storeRdfSchemaComment(ImportContext context) throws SQLException { commonTables.classComment.storeRdfSchemaDocumentationTriples(context); commonTables.propertyComment.storeRdfSchemaDocumentationTriples(context); commonTables.resourceComment.storeRdfSchemaDocumentationTriples(context); } protected void storeRdfSchemaIsDefinedBy(ImportContext context) throws SQLException { commonTables.classIsDefinedBy.storeRdfSchemaDocumentationTriples(context); commonTables.propertyIsDefinedBy.storeRdfSchemaDocumentationTriples(context); commonTables.resourceIsDefinedBy.storeRdfSchemaDocumentationTriples(context); } protected void storeRdfSchemaLabel(ImportContext context) throws SQLException { commonTables.classLabel.storeRdfSchemaDocumentationTriples(context); commonTables.propertyLabel.storeRdfSchemaDocumentationTriples(context); commonTables.resourceLabel.storeRdfSchemaDocumentationTriples(context); } protected void storeRdfSchemaSeeAlso(ImportContext context) throws SQLException { commonTables.classSeeAlso.storeRdfSchemaDocumentationTriples(context); commonTables.propertySeeAlso.storeRdfSchemaDocumentationTriples(context); commonTables.resourceSeeAlso.storeRdfSchemaDocumentationTriples(context); } private boolean checkExistenceNamedGraphDB(Uri uri) throws SQLException { ResultSet rs = Jdbc.query(String.format("SELECT 1 FROM %s WHERE att1 = '%s'", this.commonTables.graphspace.getName(), uri.toString(Uri.Delimiter.WITH))); try { return rs.next(); } finally { rs.close(); } } private boolean checkExistenceGraphsetDB(int graphId) throws SQLException { ResultSet rs = Jdbc.query(String.format("SELECT 1 FROM %s WHERE att1 = ARRAY[%d]", this.commonTables.graphset.getName(), graphId)); try { return rs.next(); } finally { rs.close(); } } private boolean checkExistenceNamespaceDependencyDB(int nsID, int nsDependentID) throws SQLException { ResultSet rs = Jdbc.query(String.format("SELECT 1 FROM %s WHERE att0 = %d AND att1 = %d", this.commonTables.namespaceDependencies.getName(), nsID, nsDependentID)); try { return rs.next(); } finally { rs.close(); } } private int findNamespaceIDfromDB(Uri uri) throws SQLException { ResultSet rs = Jdbc.query(String.format("SELECT att0 FROM %s WHERE att1 = '%s'", this.commonTables.namespace.getName(), uri.toString(Uri.Delimiter.WITH))); try { rs.next(); return rs.getInt(1); } finally { rs.close(); } } private int findNamedGraphIDfromDB(Uri uri) throws SQLException { ResultSet rs = Jdbc.query(String.format("SELECT att0 FROM %s WHERE att1 = '%s'", this.commonTables.graphspace.getName(), uri.toString(Uri.Delimiter.WITH))); try { rs.next(); return rs.getInt(1); } finally { rs.close(); } } protected class ImportContext { protected final Model model; protected final Map<Integer, Triple> tripleIds = Maps.newHashMap(); protected final UpdatedLabels updatedLabels; /** * Only contains the namespace to-be-stored ids, not existing ones. * Importer should not store into preexisting namespaces (all universe will break). */ protected final Map<Uri, Integer> namespaceIds; protected ImportContext(Model model, UpdatedLabels updatedLabels) throws SQLException { this.model = model; this.updatedLabels = updatedLabels; this.namespaceIds = commonTables.namespace.createNewNamespaceIds(model.namespaces()); } protected boolean isNewNamespace(Uri namespace) { return namespaceIds.containsKey(namespace); } protected Uri findSchemaUrifromDB(String tablename, int id) throws SQLException { ResultSet rs = Jdbc.query(String.format( "SELECT tb1.att2, tb2.att1 FROM %s tb1, %s tb2 WHERE tb1.att0 = %d and tb1.att1 = tb2.att0", tablename, commonTables.namespace.getName(), id)); try { rs.next(); return Uri.parse(rs.getString(2) + rs.getString(1)); } finally { rs.close(); } } } }