001package conexp.fx.gui.dataset; 002 003/* 004 * #%L 005 * Concept Explorer FX 006 * %% 007 * Copyright (C) 2010 - 2019 Francesco Kriegel 008 * %% 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as 011 * published by the Free Software Foundation, either version 3 of the 012 * License, or (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public 020 * License along with this program. If not, see 021 * <http://www.gnu.org/licenses/gpl-3.0.html>. 022 * #L% 023 */ 024 025import java.io.File; 026import java.util.List; 027import java.util.Set; 028import java.util.stream.Collectors; 029 030import org.openrdf.model.Statement; 031import org.openrdf.query.BindingSet; 032import org.openrdf.query.MalformedQueryException; 033import org.openrdf.query.QueryEvaluationException; 034import org.openrdf.query.QueryLanguage; 035import org.openrdf.query.TupleQuery; 036import org.openrdf.query.TupleQueryResult; 037import org.openrdf.repository.Repository; 038import org.openrdf.repository.RepositoryConnection; 039import org.openrdf.repository.RepositoryException; 040import org.openrdf.repository.sail.SailRepository; 041import org.openrdf.sail.memory.MemoryStore; 042import org.semanticweb.owlapi.model.IRI; 043 044import conexp.fx.core.builder.Requests; 045import conexp.fx.core.dl.deprecated.OWLInterpretation; 046import conexp.fx.core.importer.RDFImporter; 047import conexp.fx.core.util.FileFormat; 048import conexp.fx.gui.ConExpFX; 049import conexp.fx.gui.assistent.ModelAssistent; 050import conexp.fx.gui.task.TimeTask; 051import info.aduna.iteration.Iterations; 052import javafx.beans.property.ReadOnlyStringWrapper; 053import javafx.collections.FXCollections; 054import javafx.collections.ObservableList; 055import javafx.scene.control.Button; 056import javafx.scene.control.TableColumn; 057import javafx.scene.control.TableView; 058import javafx.scene.control.TextArea; 059import javafx.scene.layout.BorderPane; 060import javafx.scene.layout.Pane; 061import javafx.scene.text.Font; 062 063public class RDFDataset extends Dataset { 064 065 private final Repository repository = new SailRepository(new MemoryStore()); 066 private final ObservableList<Statement> statements = FXCollections.observableArrayList(); 067 068 public RDFDataset(final File file, final FileFormat format) { 069 super(null, file, format); 070 try { 071 repository.initialize(); 072 } catch (RepositoryException e) { 073 throw new RuntimeException(e); 074 } 075 views.add(new DatasetView<Repository>("Triples", createTriplesView(), repository)); 076 views.add(new DatasetView<Repository>("Query", createQueryView(), repository)); 077 defaultActiveViews.add("Triples"); 078 actions.add(new DatasetAction("New SPARQL Context...", () -> { 079 return; 080 })); 081 actions.add(new DatasetAction("New DL Model...", () -> new ModelAssistent(this).showAndWait())); 082 initialize(); 083 } 084 085 public final void initialize() { 086 if (format.equals(FileFormat.CSVT)) 087 ConExpFX.execute(TimeTask.create(this, "Importing RDF Dataset", () -> RDFImporter.readCSV(repository, file))); 088 else 089 ConExpFX.execute(TimeTask.create(this, "Importing RDF Dataset", () -> RDFImporter.read(repository, file))); 090 ConExpFX.execute(TimeTask.create(this, "Preparing Statements View", () -> { 091 try { 092 RepositoryConnection connection = repository.getConnection(); 093 Iterations.addAll(connection.getStatements(null, null, null, true), statements); 094 connection.close(); 095 096 } catch (RepositoryException e) { 097 throw new RuntimeException(e); 098 } 099 })); 100 } 101 102 private final TableView<Statement> createTriplesView() { 103 TableView<Statement> table = new TableView<>(statements); 104 final TableColumn<Statement, String> subjectColumn = new TableColumn<Statement, String>("Subject"); 105 final TableColumn<Statement, String> predicateColumn = new TableColumn<Statement, String>("Predicate"); 106 final TableColumn<Statement, String> objectColumn = new TableColumn<Statement, String>("Object"); 107 subjectColumn.setCellValueFactory(f -> new ReadOnlyStringWrapper(f.getValue().getSubject().stringValue())); 108 predicateColumn.setCellValueFactory(f -> new ReadOnlyStringWrapper(f.getValue().getPredicate().stringValue())); 109 objectColumn.setCellValueFactory(f -> new ReadOnlyStringWrapper(f.getValue().getObject().stringValue())); 110 table.getColumns().addAll(subjectColumn, predicateColumn, objectColumn); 111 return table; 112 } 113 114 private final Pane createQueryView() { 115 final BorderPane repositoryView = new BorderPane(); 116 final TextArea queryArea = new TextArea(); 117 queryArea.setFont(Font.font(java.awt.Font.MONOSPACED, 14)); 118 final Button queryButton = new Button("Query"); 119 repositoryView.setTop(new BorderPane(queryArea, null, queryButton, null, null)); 120 final TableView<BindingSet> table = new TableView<BindingSet>(FXCollections.observableArrayList()); 121 repositoryView.setCenter(table); 122 queryButton.setOnAction(__ -> { 123 try { 124 final RepositoryConnection connection = repository.getConnection(); 125 final TupleQuery query = connection.prepareTupleQuery(QueryLanguage.SPARQL, queryArea.getText()); 126 final TupleQueryResult result = query.evaluate(); 127 table.getColumns().clear(); 128 result.getBindingNames().forEach(b -> { 129 final TableColumn<BindingSet, String> column = new TableColumn<BindingSet, String>(b); 130 column.setCellValueFactory(f -> new ReadOnlyStringWrapper(f.getValue().getValue(b).stringValue())); 131 table.getColumns().add(column); 132 }); 133 table.getItems().clear(); 134 while (result.hasNext()) 135 table.getItems().add(result.next()); 136 result.close(); 137 connection.close(); 138 } catch (RepositoryException | MalformedQueryException | QueryEvaluationException e) { 139 throw new RuntimeException(e); 140 } 141 }); 142 return repositoryView; 143 } 144 145 public final ObservableList<Statement> getTriples() { 146 return statements; 147 } 148 149 public final Set<IRI> getRoles() { 150 return statements.parallelStream().map(s -> IRI.create(s.getPredicate().stringValue())).collect(Collectors.toSet()); 151 } 152 153 public final void createFormalContextFromSPARQLQuery(final String query) { 154 ConExpFX.execute(TimeTask.create(this, "Extracting SPARQL Context", () -> { 155 ConExpFX.instance.treeView.addDataset( 156 new FCADataset<>(RDFDataset.this, new Requests.Import.ImportSPARQLFromRepository(repository, query))); 157 })); 158 } 159 160 public final void 161 createDLModel(List<IRI> selectedConceptNames, List<IRI> selectedRoleNames, IRI selectedIsARoleName) { 162 ConExpFX.execute(TimeTask.create(this, "Extracting DL Model", () -> { 163 final OWLInterpretation i = 164 RDFImporter.extractInterpretation(statements, selectedConceptNames, selectedRoleNames, selectedIsARoleName); 165 ConExpFX.instance.treeView.addDataset(new DLDataset(RDFDataset.this, i)); 166 })); 167 } 168 169 @Override 170 public void save() { 171 // TODO Auto-generated method stub 172 173 } 174 175 @Override 176 public void saveAs() { 177 // TODO Auto-generated method stub 178 179 } 180 181 @Override 182 public void export() { 183 // TODO Auto-generated method stub 184 185 } 186 187 @Override 188 public void close() { 189 // TODO Auto-generated method stub 190 191 } 192 193}