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}