001/** 002 * Copyright (C) 2007 - 2016, Jens Lehmann 003 * 004 * This file is part of DL-Learner. 005 * 006 * DL-Learner is free software; you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation; either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * DL-Learner is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.dllearner.algorithms.pattern; 020 021import com.google.common.collect.HashMultiset; 022import com.google.common.collect.Multiset; 023import joptsimple.OptionParser; 024import joptsimple.OptionSet; 025import joptsimple.OptionSpec; 026import org.apache.commons.io.FileUtils; 027import org.dllearner.kb.dataset.OWLOntologyDataset; 028import org.dllearner.kb.repository.LocalDirectoryOntologyRepository; 029import org.dllearner.kb.repository.OntologyRepository; 030import org.dllearner.kb.repository.OntologyRepositoryEntry; 031import org.dllearner.utilities.ProgressBar; 032import org.dllearner.utilities.owl.ManchesterOWLSyntaxOWLObjectRendererImplExt; 033import org.ini4j.IniPreferences; 034import org.semanticweb.owlapi.apibinding.OWLManager; 035import org.semanticweb.owlapi.functional.renderer.FunctionalSyntaxObjectRenderer; 036import org.semanticweb.owlapi.io.OWLObjectRenderer; 037import org.semanticweb.owlapi.io.ToStringRenderer; 038import org.semanticweb.owlapi.io.UnparsableOntologyException; 039import org.semanticweb.owlapi.model.*; 040import org.semanticweb.owlapi.model.parameters.Imports; 041import org.semanticweb.owlapi.reasoner.ConsoleProgressMonitor; 042import org.slf4j.Logger; 043import org.slf4j.LoggerFactory; 044 045import java.io.*; 046import java.net.URI; 047import java.sql.*; 048import java.util.*; 049import java.util.concurrent.ExecutorService; 050import java.util.concurrent.Executors; 051import java.util.concurrent.TimeUnit; 052import java.util.concurrent.atomic.AtomicInteger; 053import java.util.prefs.Preferences; 054import java.util.stream.Collectors; 055 056public class OWLAxiomPatternFinder { 057 058 private static final Logger LOGGER = LoggerFactory.getLogger(OWLAxiomPatternFinder.class); 059 060 private OntologyRepository repository; 061 private OWLOntologyManager manager; 062 private OWLDataFactory dataFactory; 063 064 private Connection conn; 065 private PreparedStatement selectOntologyIdPs; 066 private PreparedStatement insertOntologyPs; 067 private PreparedStatement insertOntologyImportPs; 068 private PreparedStatement insertOntologyErrorPs; 069 070 private PreparedStatement selectPatternIdPs; 071 private PreparedStatement insertPatternIdPs; 072 private PreparedStatement insertOntologyPatternPs; 073 074 private PreparedStatement insertPatternGeneralizationPs; 075 private PreparedStatement insertPatternToPatternGeneralizationPs; 076 private PreparedStatement selectGeneralizedPatternIdPs; 077 078 private OWLObjectRenderer axiomRenderer = new ManchesterOWLSyntaxOWLObjectRendererImplExt(); 079 080 private boolean randomOrder = false; 081 082 private boolean multithreadedEnabled = false; 083 private int numThreads = 4;//Runtime.getRuntime().availableProcessors() - 1 084 085 public OWLAxiomPatternFinder(OWLOntologyDataset dataset) { 086 087 } 088 089 public OWLAxiomPatternFinder(OntologyRepository repository) { 090 this.repository = repository; 091 manager = OWLManager.createOWLOntologyManager(); 092 dataFactory = manager.getOWLDataFactory(); 093 094 initDBConnection(); 095 prepare(); 096 } 097 098 public OWLAxiomPatternFinder(OntologyRepository repository, Connection conn) { 099 this.repository = repository; 100 this.conn = conn; 101 manager = OWLManager.createOWLOntologyManager(); 102 dataFactory = manager.getOWLDataFactory(); 103 104 prepare(); 105 } 106 107 /** 108 * Start the pattern detection. 109 */ 110 public void start() { 111 final ExecutorService tp = Executors.newFixedThreadPool(multithreadedEnabled ? numThreads : 1); 112 113 Collection<OntologyRepositoryEntry> entries = repository.getEntries(); 114 if(randomOrder){ 115 List<OntologyRepositoryEntry> entryList = new ArrayList<>(repository.getEntries()); 116 Collections.shuffle(entryList); 117 entries = entryList; 118 } 119 120 final Multiset<OWLAxiom> allAxiomPatterns = HashMultiset.create(); 121 122 AtomicInteger i = new AtomicInteger(0); 123 124 manager = OWLManager.createConcurrentOWLOntologyManager(); 125 126 entries = entries.stream().filter(e -> e.getOntologyShortName().equals("NIDM-RESULTS")).collect(Collectors.toList()); 127 128 for (OntologyRepositoryEntry entry : entries) { 129 tp.execute(() -> { 130 OWLAxiomRenamer renamer = new OWLAxiomRenamer(dataFactory); 131 132 URI uri = entry.getPhysicalURI(); 133 LOGGER.info(i.incrementAndGet() + ": " + entry.getOntologyShortName() + " (" + 134 FileUtils.byteCountToDisplaySize(new File(uri).length()) + ")"); 135// if(uri.toString().startsWith("http://rest.bioontology.org/bioportal/ontologies/download/42764")){ 136 if (true) {//!ontologyProcessed(uri)) { 137 LOGGER.info("Loading \"" + entry.getOntologyShortName() + "\" from " + uri + " ..."); 138 try { 139 140 OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); 141 142 OWLOntology ontology = manager.loadOntology(IRI.create(uri)); 143 Set<OWLLogicalAxiom> logicalAxioms = ontology.getLogicalAxioms(Imports.EXCLUDED); 144 LOGGER.info(" finished loading \"" + entry.getOntologyShortName() + "\". #Axioms: " + logicalAxioms.size()); 145 addOntology(uri, ontology, Imports.EXCLUDED); 146 147 LOGGER.info("Running pattern detection for \"" + entry.getOntologyShortName() + "\" ..."); 148 Multiset<OWLAxiom> axiomPatterns = HashMultiset.create(); 149 int cnt = 0; 150 ProgressBar mon = new ProgressBar(); 151 for (OWLAxiom axiom : logicalAxioms) { 152// if(axiom.isOfType(AxiomType.SUBCLASS_OF)) { 153// System.out.println(MaximumModalDepthDetector.getMaxModalDepth(axiom)); 154// System.out.println(((OWLSubClassOfAxiom)axiom).getSuperClass()); 155// OWLClassExpression sup = ((OWLSubClassOfAxiom) axiom).getSuperClass(); 156// if(sup instanceof OWLObjectIntersectionOf) { 157// List<OWLClassExpression> operands = ((OWLObjectIntersectionOf) sup).getOperandsAsList(); 158// System.out.println("OPs: " + operands.size()); 159// if(operands.get(0).toString().equals("Oxidative-Phosphorylation")) { 160// manager.createOntology(Sets.newHashSet(axiom)).saveOntology( 161// new RDFXMLDocumentFormat(), 162// new FileOutputStream("/tmp/longaxiom.owl")); 163// System.exit(0); 164// } 165// } 166// } 167 168 OWLAxiom renamedAxiom = renamer.rename(axiom); 169 axiomPatterns.add(renamedAxiom); 170 cnt++; 171 if(cnt % 100 == 0) { 172 mon.update(cnt, logicalAxioms.size()); 173 } 174 } 175 176 LOGGER.info(" finished pattern detection for \"" + entry.getOntologyShortName() + "\". #Patterns: " + 177 axiomPatterns.elementSet().size()); 178// allAxiomPatterns.addAll(axiomPatterns); 179 addOntologyPatterns(uri, ontology, axiomPatterns); 180// for (OWLAxiom owlAxiom : Multisets.copyHighestCountFirst(allAxiomPatterns).elementSet()) { 181// System.out.println(owlAxiom + ": " + allAxiomPatterns.count(owlAxiom)); 182// } 183 184 // process the imports separately 185 Set<OWLOntology> imports = ontology.getImports(); 186 if(!imports.isEmpty()) { 187 LOGGER.info("Processing the imports of \"" + entry.getOntologyShortName() + "\" ..."); 188 } 189 imports.stream().forEach(importedOntology -> { 190 IRI iri = importedOntology.getOntologyID().getOntologyIRI().or(manager.getOntologyDocumentIRI(importedOntology)); 191 System.out.println(iri.toString()); 192 193 // check if it was already processed before 194 if(!ontologyProcessed(iri.toURI())) { 195 addOntology(iri.toURI(), importedOntology, Imports.INCLUDED); 196 LOGGER.info("Running pattern detection for import from " + iri + " ..."); 197 axiomPatterns.clear(); 198 importedOntology.getLogicalAxioms(Imports.INCLUDED).stream().forEach(axiom -> { 199 OWLAxiom renamedAxiom = renamer.rename(axiom); 200 axiomPatterns.add(renamedAxiom); 201 }); 202 addOntologyPatterns(iri.toURI(), importedOntology, axiomPatterns); 203 addOntologyImport(uri, ontology, iri.toURI(), importedOntology); 204 LOGGER.info(" finished pattern detection for import from " + iri + ". #Patterns: " + 205 axiomPatterns.elementSet().size()); 206 } else { 207 LOGGER.info("Import " + iri + " already processed."); 208 } 209 210 }); 211 212 213 214 manager.removeOntology(ontology); 215 } catch (OWLOntologyAlreadyExistsException e) { 216 e.printStackTrace(); 217 } catch (UnloadableImportException e) { 218 LOGGER.error("Import loading failed.", e.getMessage()); 219 addOntologyError(uri, e); 220 } catch(UnparsableOntologyException e) { 221 e.printStackTrace(); 222 LOGGER.error("Parsing of ontology failed.", e.getMessage()); 223 addOntologyError(uri, e); 224 } catch (Exception e) { 225 e.printStackTrace(); 226 LOGGER.error("Ontology processing failed", e); 227 addOntologyError(uri, e); 228 } 229 } else { 230 LOGGER.info("Already processed."); 231 } 232 }); 233 } 234 235 try { 236 tp.shutdown(); 237 tp.awaitTermination(600, TimeUnit.MINUTES); 238 } catch (InterruptedException e) { 239 System.err.println("tasks interrupted"); 240 241 // Preserve interrupt status 242 Thread.currentThread().interrupt(); 243 } finally { 244 if (!tp.isTerminated()) { 245 System.err.println("cancel non-finished tasks"); 246 } 247 tp.shutdownNow(); 248 System.out.println("shutdown finished"); 249 } 250 251 252 computeAndAddGeneralizedPatterns(); 253 254 try { 255 conn.close(); 256 } catch (SQLException e) { 257 LOGGER.error("Failed to close DB connection.", e); 258 } 259 } 260 261 public void setMultithreadedEnabled(boolean multithreadedEnabled) { 262 this.multithreadedEnabled = multithreadedEnabled; 263 } 264 265 public void setNumThreads(int numThreads) { 266 this.numThreads = numThreads; 267 if(numThreads < 0) { 268 numThreads = Runtime.getRuntime().availableProcessors() - 1; 269 } 270 } 271 272 private void prepare(){ 273 createTables(); 274 try { 275 selectOntologyIdPs = conn.prepareStatement("SELECT id FROM Ontology WHERE url=?"); 276 insertOntologyPs = conn.prepareStatement("INSERT INTO Ontology (url, iri, repository, logical_axioms, tbox_axioms, rbox_axioms" + 277 ", abox_axioms, classes, object_properties, data_properties, individuals) VALUES(?,?,?,?,?,?,?,?,?,?,?)"); 278 279 insertOntologyImportPs = conn.prepareStatement("INSERT INTO Ontology_Import (ontology_id1, ontology_id2) VALUES(?,?)"); 280 insertOntologyErrorPs = conn.prepareStatement("INSERT INTO Ontology_Error (url, repository, error) VALUES(?,?,?)"); 281 282 selectPatternIdPs = conn.prepareStatement("SELECT id FROM Pattern WHERE pattern=?"); 283 insertPatternIdPs = conn.prepareStatement("INSERT INTO Pattern (pattern,pattern_pretty,axiom_type) VALUES(?,?,?)"); 284 insertOntologyPatternPs = conn.prepareStatement("INSERT INTO Ontology_Pattern (ontology_id, pattern_id, occurrences) VALUES(?,?,?)"); 285 286 insertPatternGeneralizationPs = conn.prepareStatement("INSERT INTO Pattern_Generalized (pattern,pattern_pretty,axiom_type) VALUES(?,?,?)"); 287 insertPatternToPatternGeneralizationPs = conn.prepareStatement("INSERT INTO Pattern_Pattern_Generalized (pattern_id, generalized_pattern_id) VALUES(?,?)"); 288 selectGeneralizedPatternIdPs = conn.prepareStatement("SELECT id FROM Pattern_Generalized WHERE pattern=?"); 289 290 } catch (SQLException e) { 291 e.printStackTrace(); 292 } 293 } 294 295 private String render(OWLAxiom axiom){ 296 try { 297 OWLOntologyManager man = OWLManager.createOWLOntologyManager(); 298 OWLOntology ontology = man.createOntology(); 299 man.addAxiom(ontology, axiom); 300 StringWriter sw = new StringWriter(); 301 FunctionalSyntaxObjectRenderer r = new FunctionalSyntaxObjectRenderer(ontology, sw); 302 axiom.accept(r); 303 return sw.toString(); 304 } catch (OWLOntologyCreationException e) { 305 e.printStackTrace(); 306 } 307 return null; 308 } 309 310 private void initDBConnection() { 311 try { 312 InputStream is = this.getClass().getClassLoader().getResourceAsStream( 313 "org/dllearner/algorithms/pattern/db_settings.ini"); 314 Preferences prefs = new IniPreferences(is); 315 String dbServer = prefs.node("database").get("server", null); 316 String dbName = prefs.node("database").get("name", null); 317 String dbUser = prefs.node("database").get("user", null); 318 String dbPass = prefs.node("database").get("pass", null); 319 320 String url = "jdbc:mysql://" + dbServer + "/" + dbName; 321 conn = DriverManager.getConnection(url, dbUser, dbPass); 322 } catch (IOException e) { 323 LOGGER.error("Failed to settings.", e); 324 } catch (SQLException e) { 325 LOGGER.error("Failed to setup database connection.", e); 326 } 327 } 328 329 private void createTables(){ 330 try (Statement statement = conn.createStatement()){ 331 statement.execute("CREATE TABLE IF NOT EXISTS Pattern (" 332 + "id MEDIUMINT NOT NULL AUTO_INCREMENT," 333 + "pattern TEXT NOT NULL," 334 + "pattern_pretty TEXT NOT NULL," 335 + "axiom_type VARCHAR(15) NOT NULL," 336 + "PRIMARY KEY(id)," 337 + "INDEX(pattern(1000))) DEFAULT CHARSET=utf8"); 338 339 statement.execute("CREATE TABLE IF NOT EXISTS Ontology (" 340 + "id MEDIUMINT NOT NULL AUTO_INCREMENT," 341 + "url VARCHAR(1000) NOT NULL," 342 + "iri VARCHAR(2000) NOT NULL," 343 + "repository VARCHAR(200) NOT NULL," 344 + "logical_axioms MEDIUMINT DEFAULT 0," 345 + "tbox_axioms MEDIUMINT DEFAULT 0," 346 + "rbox_axioms MEDIUMINT DEFAULT 0," 347 + "abox_axioms MEDIUMINT DEFAULT 0," 348 + "classes MEDIUMINT DEFAULT 0," 349 + "object_properties MEDIUMINT DEFAULT 0," 350 + "data_properties MEDIUMINT DEFAULT 0," 351 + "individuals MEDIUMINT DEFAULT 0," 352 + "PRIMARY KEY(id)," 353 + "INDEX(url)) DEFAULT CHARSET=utf8"); 354 355 statement.execute("CREATE TABLE IF NOT EXISTS Ontology_Import (" 356 + "ontology_id1 MEDIUMINT NOT NULL," 357 + "ontology_id2 MEDIUMINT NOT NULL," 358 + "PRIMARY KEY(ontology_id1, ontology_id2))" 359 ); 360 361 statement.execute("CREATE TABLE IF NOT EXISTS Ontology_Error (" 362 + "url VARCHAR(1000) NOT NULL," 363 + "repository VARCHAR(200) NOT NULL," 364 + "error VARCHAR(2000) NOT NULL," 365 + "PRIMARY KEY(url, repository))" 366 ); 367 368 statement.execute("CREATE TABLE IF NOT EXISTS Ontology_Pattern (" 369 + "ontology_id MEDIUMINT NOT NULL," 370 + "pattern_id MEDIUMINT NOT NULL," 371 + "occurrences INTEGER(8) NOT NULL," 372 + "FOREIGN KEY (ontology_id) REFERENCES Ontology(id) ON DELETE CASCADE," 373 + "FOREIGN KEY (pattern_id) REFERENCES Pattern(id) ON DELETE CASCADE," 374 + "PRIMARY KEY(ontology_id, pattern_id)) DEFAULT CHARSET=utf8"); 375 376 statement.execute("CREATE TABLE IF NOT EXISTS Pattern_Generalized (" 377 + "id MEDIUMINT NOT NULL AUTO_INCREMENT," 378 + "pattern TEXT NOT NULL," 379 + "pattern_pretty TEXT NOT NULL," 380 + "axiom_type VARCHAR(15) NOT NULL," 381 + "PRIMARY KEY(id)," 382 + "INDEX(pattern(1000))) DEFAULT CHARSET=utf8"); 383 384 statement.execute("CREATE TABLE IF NOT EXISTS Pattern_Pattern_Generalized (" 385 + "pattern_id MEDIUMINT NOT NULL," 386 + "generalized_pattern_id MEDIUMINT NOT NULL," 387 + "FOREIGN KEY (pattern_id) REFERENCES Pattern(id) ON DELETE CASCADE," 388 + "FOREIGN KEY (generalized_pattern_id) REFERENCES Pattern_Generalized(id) ON DELETE CASCADE," 389 + "PRIMARY KEY(pattern_id, generalized_pattern_id)) DEFAULT CHARSET=utf8"); 390 391 392 } catch (SQLException e) { 393 LOGGER.error("Failed to setup database tables.", e); 394 } 395 } 396 397 OWLAxiomGeneralizer generalizer = new OWLAxiomGeneralizer(); 398 399 private void computeAndAddGeneralizedPatterns() { 400 // get all patterns from DB 401 String sql = "SELECT id, pattern FROM Pattern"; 402 try(Statement stmt = conn.createStatement()) { 403 try(ResultSet rs = stmt.executeQuery(sql)){ 404 while(rs.next()) { 405 int id = rs.getInt(1); 406 String patternStr = rs.getString(2); 407 408 // parse to OWLAxiom 409 OWLAxiom axiom = parse(patternStr); 410 411 // compute generalizations 412 System.out.println(axiom); 413 Set<OWLAxiom> generalizations = generalizer.generalize(axiom); 414 415 // add to DB 416 generalizations.forEach(gen -> { 417 // add generalized pattern if not exist and get ID 418 int genID = addGeneralizedPattern(gen); 419 420 // add mapping from pattern to generalized pattern 421 try { 422 insertPatternToPatternGeneralizationPs.setInt(1, id); 423 insertPatternToPatternGeneralizationPs.setInt(2, genID); 424 insertPatternToPatternGeneralizationPs.addBatch(); 425 } catch (SQLException e) { 426 LOGGER.error("Failed to insert pattern to gen. pattern mapping.", e); 427 } 428 }); 429 insertPatternToPatternGeneralizationPs.executeBatch(); 430 } 431 } catch(SQLException e) { 432 LOGGER.error("Failed to get patterns from DB.", e); 433 } 434 } catch (SQLException e) { 435 LOGGER.error("Failed to create statement.", e); 436 } 437 438 } 439 440 private OWLAxiom parse(String axiomStr) { 441 String ontologyStr = "Ontology (" + axiomStr + ")"; 442 try { 443 OWLOntology ont = manager 444 .loadOntologyFromOntologyDocument(new ByteArrayInputStream(ontologyStr.getBytes())); 445 return ont.getLogicalAxioms().iterator().next(); 446 } catch (OWLOntologyCreationException e) { 447 LOGGER.error("Failed to parse axiom from " + axiomStr, e); 448 } 449 return null; 450 } 451 452 private int addGeneralizedPattern(OWLAxiom axiom){ 453 String axiomString = render(axiom); 454 455 // check for existing entry 456 Integer patternID = getGeneralizedPatternID(axiom); 457 if(patternID != null) { 458 return patternID; 459 } 460 461 // otherwise, add pattern entry 462 try { 463 insertPatternGeneralizationPs.setString(1, axiomString); 464 insertPatternGeneralizationPs.setString(2, axiomRenderer.render(axiom)); 465 insertPatternGeneralizationPs.setString(3, getAxiomType(axiom)); 466 insertPatternGeneralizationPs.execute(); 467 } catch (SQLException e) { 468 LOGGER.error("Failed to insert pattern. Maybe too long with a length of " + axiomString.length() + "?", e); 469 } 470 471 // get the pattern ID after insertion 472 return getGeneralizedPatternID(axiom); 473 } 474 475 private Integer getGeneralizedPatternID(OWLAxiom axiom) { 476 try { 477 selectGeneralizedPatternIdPs.setString(1, render(axiom)); 478 try(ResultSet rs = selectGeneralizedPatternIdPs.executeQuery()){ 479 if(rs.next()){ 480 return rs.getInt(1); 481 } 482 } 483 } catch (SQLException e) { 484 LOGGER.error("Failed to get pattern ID.", e); 485 } 486 return null; 487 } 488 489 490 private int addPattern(OWLAxiom axiom){ 491 String axiomString = render(axiom); 492 493 // check for existing entry 494 Integer patternID = getPatternID(axiom); 495 if(patternID != null) { 496 return patternID; 497 } 498 499 // otherwise, add pattern entry 500 try { 501 insertPatternIdPs.setString(1, axiomString); 502 insertPatternIdPs.setString(2, axiomRenderer.render(axiom)); 503 insertPatternIdPs.setString(3, getAxiomType(axiom)); 504 insertPatternIdPs.execute(); 505 } catch (SQLException e) { 506 LOGGER.error("Failed to insert pattern. Maybe too long with a length of " + axiomString.length() + "?", e); 507 } 508 509 // get the pattern ID after insertion 510 return getPatternID(axiom); 511 } 512 513 private Integer getPatternID(OWLAxiom axiom) { 514 try { 515 selectPatternIdPs.setString(1, render(axiom)); 516 try(ResultSet rs = selectPatternIdPs.executeQuery()) { 517 if(rs.next()){ 518 return rs.getInt(1); 519 } 520 } 521 } catch (SQLException e) { 522 LOGGER.error("Failed to get pattern ID.", e); 523 } 524 return null; 525 } 526 527 private String getAxiomType(OWLAxiom axiom) { 528 AxiomType<?> type = axiom.getAxiomType(); 529 String s; 530 if (AxiomType.TBoxAxiomTypes.contains(type)) { 531 s = "TBox"; 532 } else if (AxiomType.RBoxAxiomTypes.contains(type)) { 533 s = "RBox"; 534 } else if (AxiomType.ABoxAxiomTypes.contains(type)) { 535 s = "ABox"; 536 } else { 537 System.out.println(axiom + "-" + type); 538 //should not happen 539 s = "Non-Logical"; 540 } 541 return s; 542 } 543 544 private synchronized boolean ontologyProcessed(URI uri){ 545 //check if ontology was already processed 546 try { 547 selectOntologyIdPs.setString(1, uri.toString()); 548 try(ResultSet rs = selectOntologyIdPs.executeQuery()) { 549 return rs.next(); 550 } 551 } catch (SQLException e) { 552 e.printStackTrace(); 553 } 554 return false; 555 } 556 557 private synchronized void addOntologyError(URI physicalURI, Exception ex){ 558 String url = physicalURI.toString(); 559 //add ontology loading/parsing/... error entry 560 try { 561 insertOntologyErrorPs.setString(1, url); 562 String errorMessage = "ERROR:" + ex.getClass().getSimpleName(); 563 if(!(ex instanceof UnparsableOntologyException)){ 564 errorMessage += (ex.getMessage() != null ? ("->" + ex.getMessage()) : ""); 565 } 566 if(errorMessage.length() > 1900){ 567 errorMessage = errorMessage.substring(0, 1900); 568 } 569 insertOntologyErrorPs.setString(2, repository.getName()); 570 insertOntologyErrorPs.setString(3, errorMessage); 571 insertOntologyErrorPs.execute(); 572 } catch (SQLException e) { 573 LOGGER.error("Failed to insert ontology error statement.", e); 574 } 575 } 576 577 private synchronized int addOntology(URI physicalURI, OWLOntology ontology, Imports imports){ 578 String url = physicalURI.toString(); 579 String ontologyIRI = "Anonymous"; 580 if(!ontology.getOntologyID().isAnonymous()){ 581 ontologyIRI = ontology.getOntologyID().getOntologyIRI().get().toString(); 582 } 583 // check for existing entry 584 Integer ontologyID = getOntologyID(physicalURI, ontology); 585 if(ontologyID != null) { 586 return ontologyID; 587 } 588 589 // add ontology entry 590 try { 591 insertOntologyPs.setString(1, url); 592 insertOntologyPs.setString(2, ontologyIRI); 593 insertOntologyPs.setString(3, repository.getName()); 594 Set<OWLAxiom> tbox = ontology.getTBoxAxioms(imports); 595 Set<OWLAxiom> rbox = ontology.getRBoxAxioms(imports); 596 Set<OWLAxiom> abox = ontology.getABoxAxioms(imports); 597 598 insertOntologyPs.setInt(4, tbox.size() + rbox.size() + abox.size()); 599 insertOntologyPs.setInt(5, tbox.size()); 600 insertOntologyPs.setInt(6, rbox.size()); 601 insertOntologyPs.setInt(7, abox.size()); 602 insertOntologyPs.setInt(8, ontology.getClassesInSignature(Imports.INCLUDED).size()); 603 insertOntologyPs.setInt(9, ontology.getObjectPropertiesInSignature(Imports.INCLUDED).size()); 604 insertOntologyPs.setInt(10, ontology.getDataPropertiesInSignature(Imports.INCLUDED).size()); 605 insertOntologyPs.setInt(11, ontology.getIndividualsInSignature(Imports.INCLUDED).size()); 606 insertOntologyPs.execute(); 607 } catch (SQLException e) { 608 LOGGER.error("Failed to insert ontology.", e); 609 } 610 611 // get and return the auto generated ID 612 return getOntologyID(physicalURI, ontology); 613 } 614 615 private synchronized void addOntologyImport(URI physicalURI1, OWLOntology ontology1, URI physicalURI2, OWLOntology ontology2){ 616 // get ID of first ontology 617 Integer ontologyID1 = getOntologyID(physicalURI1, ontology1); 618 619 // get ID of second ontology 620 Integer ontologyID2 = getOntologyID(physicalURI2, ontology2); 621 622 // add ontology entry 623 try { 624 insertOntologyImportPs.setInt(1, ontologyID1); 625 insertOntologyImportPs.setInt(2, ontologyID2); 626 627 insertOntologyImportPs.execute(); 628 } catch (SQLException e) { 629 LOGGER.error("Failed to insert ontology.", e); 630 } 631 } 632 633 private Integer getOntologyID(OWLOntology ontology) { 634 String ontologyIRI = "Anonymous"; 635 if(!ontology.getOntologyID().isAnonymous()){ 636 ontologyIRI = ontology.getOntologyID().getOntologyIRI().toString(); 637 } 638 //check for existing entry 639 try { 640 selectOntologyIdPs.setString(1, ontologyIRI); 641 try(ResultSet rs = selectOntologyIdPs.executeQuery()) { 642 if(rs.next()){ 643 return rs.getInt(1); 644 } 645 } 646 } catch (SQLException e) { 647 LOGGER.error("Failed to get ontology ID.", e); 648 } 649 return null; 650 } 651 652 private Integer getOntologyID(URI physicalURI, OWLOntology ontology) { 653 String url = physicalURI.toString(); 654 String ontologyIRI = "Anonymous"; 655 if(!ontology.getOntologyID().isAnonymous()){ 656 ontologyIRI = ontology.getOntologyID().getOntologyIRI().toString(); 657 } 658 //check for existing entry 659 try { 660 selectOntologyIdPs.setString(1, url); 661 try(ResultSet rs = selectOntologyIdPs.executeQuery()) { 662 if(rs.next()){ 663 return rs.getInt(1); 664 } 665 } 666 } catch (SQLException e) { 667 LOGGER.error("Failed to get ontology ID.", e); 668 } 669 return null; 670 } 671 672 private synchronized void addOntologyPatterns(URI physicalURI, OWLOntology ontology, Multiset<OWLAxiom> patterns){ 673 int ontologyId = getOntologyID(physicalURI, ontology); 674 for (OWLAxiom pattern : patterns.elementSet()) { 675 try { 676 int patternId = addPattern(pattern); 677 int occurrences = patterns.count(pattern); 678 insertOntologyPatternPs.setInt(1, ontologyId); 679 insertOntologyPatternPs.setInt(2, patternId); 680 insertOntologyPatternPs.setInt(3, occurrences); 681 insertOntologyPatternPs.addBatch(); 682 } catch (SQLException e) { 683 LOGGER.error("Failed to insert pattern\n" + pattern + "\"", e); 684 } 685 } 686 try { 687 insertOntologyPatternPs.executeBatch(); 688 } catch (BatchUpdateException e) { 689 LOGGER.error("Failed to insert some pattern. Reason: {}", e.getMessage()); 690 } catch (SQLException e) { 691 LOGGER.error("Failed to insert patterns.", e); 692 } 693 } 694 695 public static void main(String[] args) throws Exception { 696// ManchesterOWLSyntaxOWLObjectRendererImplExt renderer = new ManchesterOWLSyntaxOWLObjectRendererImplExt( 697// true, true); 698// ToStringRenderer.getInstance().setRenderer(renderer); 699 // create Options object 700 OptionParser parser = new OptionParser(); 701 702 OptionSpec<File> dir = 703 parser.accepts( "dir" ).withRequiredArg().ofType( File.class ).required(); 704 705 OptionSpec<Long> maxFileSize = 706 parser.accepts( "maxFileSize" ).withRequiredArg().ofType(Long.class).defaultsTo(Long.MAX_VALUE); 707 708 OptionSpec<Boolean> multiThreadedEnabledOpt = 709 parser.accepts( "multiThreadedEnabled" ).withOptionalArg().ofType(Boolean.class).defaultsTo(false); 710 711 OptionSpec<Integer> numThreadsOpt = 712 parser.accepts( "numThreads" ).availableIf(multiThreadedEnabledOpt).withRequiredArg().ofType(Integer.class).defaultsTo(4); 713 714 parser.printHelpOn( System.out ); 715 716 OptionSet options = parser.parse(args); 717 718 boolean multiThreadedEnabled = options.has(multiThreadedEnabledOpt) && 719 (!options.hasArgument(multiThreadedEnabledOpt) || options.valueOf(multiThreadedEnabledOpt)); 720 int numThreads = options.valueOf(numThreadsOpt); 721 722 OntologyRepository repository = new LocalDirectoryOntologyRepository(options.valueOf(dir), options.valueOf(maxFileSize)); 723 repository.initialize(); 724 725 OWLAxiomPatternFinder patternFinder = new OWLAxiomPatternFinder(repository); 726 patternFinder.setMultithreadedEnabled(multiThreadedEnabled); 727 patternFinder.setNumThreads(numThreads); 728 patternFinder.start(); 729 730// String ontologyURL = "ontologyURL"; 731// OWLOntologyManager man = OWLManager.createOWLOntologyManager(); 732// OWLDataFactory dataFactory = man.getOWLDataFactory(); 733// OWLFunctionalDataPropertyAxiom axiom = dataFactory.getOWLFunctionalDataPropertyAxiom(dataFactory.getOWLDataProperty(IRI.create("http://ex.org/p"))); 734// OWLOntology ontology = man.createOntology(); 735// man.addAxiom(ontology, axiom); 736// StringWriter sw = new StringWriter(); 737// FunctionalSyntaxObjectRenderer r = new FunctionalSyntaxObjectRenderer(ontology, sw); 738// axiom.accept(r); 739// System.out.println(sw.toString()); 740// StringDocumentSource s = new StringDocumentSource("Ontology(<http://www.pattern.org>" + sw.toString() + ")"); 741// OWLFunctionalSyntaxOWLParser p = new OWLFunctionalSyntaxOWLParser(); 742// OWLOntology newOntology = man.createOntology(); 743// p.parse(s, newOntology, new OWLOntologyLoaderConfiguration()); 744// System.out.println(newOntology.getLogicalAxioms()); 745 746 } 747}