Skip to content

Commit 993a600

Browse files
committed
Feature: Can now ingest .csv. When correlated with a valid graph, can generate instance-level RDFXML.
2 parents a0edd7d + a077fe8 commit 993a600

16 files changed

Lines changed: 680 additions & 87 deletions

lib/commons-csv-1.6.jar

41.4 KB
Binary file not shown.

src/controller/AbstractDataSharingController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* An abstract Controller that faciliitates the passing of data to and from the Controller class.
77
* @param <T> the type of data passed between the classes.
88
*/
9-
public abstract class AbstractDataSharingController<T> {
9+
abstract class AbstractDataSharingController<T> {
1010
public abstract void setData(ArrayList<T> data);
1111
public abstract ArrayList<T> getData();
1212
}

src/controller/Controller.java

Lines changed: 87 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
import javafx.fxml.FXMLLoader;
44
import javafx.scene.Parent;
55
import javafx.scene.Scene;
6-
import javafx.scene.shape.StrokeType;
76
import javafx.stage.Modality;
87
import javafx.stage.Stage;
98
import model.conceptual.Edge;
109
import model.conceptual.Vertex;
1110
import model.conceptual.Vertex.OutsideElementException;
1211
import model.conversion.gat.FromGatConverter;
1312
import model.conversion.gat.ToGatConverter;
14-
import model.conversion.ttl.Converter;
13+
import model.conversion.rdfxml.RDFXMLGenerator;
1514
import model.graph.Arrow;
15+
import model.conversion.ttl.Converter;
1616
import javafx.embed.swing.SwingFXUtils;
1717
import javafx.fxml.FXML;
1818
import javafx.geometry.BoundingBox;
@@ -33,16 +33,18 @@
3333
import javafx.scene.shape.Rectangle;
3434
import javafx.scene.text.Text;
3535
import javafx.stage.FileChooser;
36+
import org.apache.commons.csv.CSVFormat;
37+
import org.apache.commons.csv.CSVParser;
38+
import org.apache.commons.csv.CSVRecord;
3639

3740
import javax.imageio.ImageIO;
3841
import java.awt.*;
3942
import java.awt.image.RenderedImage;
4043
import java.io.*;
4144
import java.lang.reflect.InvocationTargetException;
4245
import java.lang.reflect.Method;
43-
import java.util.ArrayList;
44-
import java.util.Arrays;
45-
import java.util.Optional;
46+
import java.util.*;
47+
import java.util.List;
4648
import java.util.logging.Level;
4749
import java.util.logging.Logger;
4850

@@ -55,18 +57,22 @@ public final class Controller {
5557
@FXML protected BorderPane root;
5658
@FXML protected Pane drawPane;
5759
@FXML protected ScrollPane scrollPane;
58-
@FXML protected Button prefixBtn, saveGraphBtn, loadGraphBtn, exportTllBtn, exportPngBtn, instrBtn, optionsBtn;
60+
@FXML protected Button prefixBtn, saveGraphBtn, loadGraphBtn, exportTllBtn, exportPngBtn, eatCsvBtn, rdfXmlBtn,
61+
instrBtn, optionsBtn;
5962
@FXML protected Label statusLbl;
6063
private ArrayList<Boolean> config = new ArrayList<>(Arrays.asList(false, false, false));
6164

62-
private ArrayList<String> prefixes = new ArrayList<>();
65+
private Map<String, String> prefixes = new HashMap<>();
6366
private final ArrayList<Edge> properties = new ArrayList<>();
6467
private final ArrayList<Vertex> classes = new ArrayList<>();
6568

6669
private Arrow arrow;
6770
private Vertex subject;
6871
private boolean srcClick = true;
6972

73+
private List<CSVRecord> csv;
74+
private Map<String, Integer> headers;
75+
7076
/**
7177
* Method invoked on any key press in the main application.
7278
* @param keyEvent the key that invoked the method.
@@ -124,8 +130,12 @@ private <C extends AbstractDataSharingController<T>, T> ArrayList<T> showWindow(
124130
* Shows the Prefixes menu, updating the prefixes if they have been modified in the menu.
125131
*/
126132
@FXML void showPrefixMenuAction() {
127-
ArrayList<String> updatedPrefixes = showWindow("/view/prefixmenu.fxml", "Prefixes Menu", prefixes);
128-
if (updatedPrefixes != null) prefixes = updatedPrefixes;
133+
ArrayList<Map<String, String>> data = new ArrayList<>();
134+
data.add(prefixes);
135+
136+
ArrayList<Map<String, String>> updatedData = showWindow("/view/prefixmenu.fxml", "Prefixes Menu", data);
137+
138+
if (updatedData != null) prefixes = updatedData.get(0);
129139
}
130140

131141
/**
@@ -135,12 +145,12 @@ private <C extends AbstractDataSharingController<T>, T> ArrayList<T> showWindow(
135145
@FXML public void saveGraphAction() {
136146
File saveFile = showSaveFileDialog("graph.gat", "Save Graph As", null);
137147
if (saveFile != null){
138-
String filetext = ToGatConverter.traverseCanvas(
148+
ToGatConverter converter = new ToGatConverter(
139149
drawPane.getWidth(),
140150
drawPane.getHeight(),
141-
classes,
142-
properties
151+
classes, properties
143152
);
153+
String filetext = converter.traverseCanvas();
144154
try {
145155
FileWriter writer = new FileWriter(saveFile);
146156
writer.write(filetext);
@@ -158,15 +168,15 @@ private <C extends AbstractDataSharingController<T>, T> ArrayList<T> showWindow(
158168
* into elements of a graph. It then binds the visual elements into meaningful java-friendly elements.
159169
*/
160170
@FXML public void loadGraphAction() {
161-
File loadFile = showLoadFileDialog();
171+
File loadFile = showLoadFileDialog("Load Graph File");
162172
if (loadFile != null){
163173
drawPane.getChildren().clear();
164174
prefixes.clear();
165175
classes.clear();
166176
properties.clear();
167177

168178
try (FileReader reader = new FileReader(loadFile)){
169-
char[] rawGraph = new char[10000];
179+
char[] rawGraph = new char[10000]; //needs to be arbitrary
170180
if (reader.read(rawGraph) == 0 ) {
171181
statusLbl.setText("Read failed: nothing in graph file.");
172182
LOGGER.warning("Nothing in graph file.");
@@ -445,21 +455,15 @@ private void addElementSubaction(MouseEvent mouseEvent) {
445455
double textWidth = elementName.getBoundsInLocal().getWidth();
446456

447457
if (isClass){
448-
Ellipse elementType = new Ellipse();
449-
elementType.setCenterX(x);
450-
elementType.setCenterY(y);
451-
elementType.setRadiusX(textWidth / 2 > 62.5 ? textWidth / 2 + 10 : 62.5);
452-
elementType.setRadiusY(37.5);
458+
Ellipse elementType = new Ellipse(x, y, textWidth / 2 > 62.5 ? textWidth / 2 + 10 : 62.5, 37.5);
453459
elementType.setFill(Color.web("f4f4f4"));
454460
elementType.setStroke(Color.BLACK);
455461
compiledElement.getChildren().addAll(elementType, elementName);
456462

457463
} else {
458-
Rectangle elementType = new Rectangle();
464+
Rectangle elementType = new Rectangle(textWidth > 125 ? textWidth + 15 : 125, 75);
459465
String name = elementName.getText();
460466

461-
elementType.setHeight(75);
462-
elementType.setWidth(textWidth > 125 ? textWidth + 15 : 125);
463467
elementType.setFill(Color.web("f4f4f4"));
464468
elementType.setStroke(Color.BLACK);
465469
if (name.matches(instanceLiteralRegex) && !name.matches(globalLiteralRegex))
@@ -553,9 +557,9 @@ private File showSaveFileDialog(String fileName, String windowTitle, FileChooser
553557
* Creates a load file dialog, which prompts the user to load from a specific file.
554558
* @return the file that will be loaded from.
555559
*/
556-
private File showLoadFileDialog(){
560+
private File showLoadFileDialog(String title){
557561
FileChooser fileChooser = new FileChooser();
558-
fileChooser.setTitle("Load Graph File");
562+
fileChooser.setTitle(title);
559563
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
560564

561565
return fileChooser.showOpenDialog(root.getScene().getWindow());
@@ -588,4 +592,63 @@ private void showOptionsDialog() {
588592
ArrayList<Boolean> updatedConfig = showWindow("/view/optionsmenu.fxml", "Options for the Current Project", config);
589593
if (updatedConfig != null) config = updatedConfig;
590594
}
595+
596+
@FXML protected void ingestCsvAction(){
597+
File loadFile = showLoadFileDialog("Load .csv for RDF/XML generation");
598+
if (loadFile != null){
599+
csv = null;
600+
headers = null;
601+
try (Reader reader = new BufferedReader(new FileReader(loadFile))){
602+
CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);
603+
headers = parser.getHeaderMap();
604+
csv = parser.getRecords();
605+
statusLbl.setText(".csv ingested. Yum.");
606+
LOGGER.info("Ingested " + loadFile.getName() + ".\nFound csv headers: " + headers);
607+
rdfXmlBtn.setDisable(false);
608+
parser.close();
609+
} catch (IOException e) {
610+
e.printStackTrace();
611+
}
612+
}
613+
}
614+
615+
@FXML protected void rdfXmlGenAction() {
616+
String rdfxml;
617+
RDFXMLGenerator rdfxmlGenerator = new RDFXMLGenerator(headers, csv, classes, prefixes);
618+
rdfxmlGenerator.attemptCorrelationOfHeaders();
619+
620+
LOGGER.info("BEFORE Correlation:\nCorrelated: " + rdfxmlGenerator.getCorrelations().toString() +
621+
"\nUncorrelated: " + rdfxmlGenerator.uncorrelatedToString());
622+
623+
if (rdfxmlGenerator.getUncorrelated() != null && rdfxmlGenerator.getUncorrelated().getKey().size() != 0)
624+
showManualCorrelationDialog(rdfxmlGenerator);
625+
if (rdfxmlGenerator.getUncorrelated() != null && rdfxmlGenerator.getUncorrelated().getKey().size() != 0){
626+
LOGGER.info("Cancelled Manual Correlations. ");
627+
return;
628+
}
629+
630+
LOGGER.info("AFTER Correlation:" +
631+
"\nCorrelated: " + rdfxmlGenerator.getCorrelations().toString() +
632+
"\nUncorrelated (assumed constant): " + rdfxmlGenerator.uncorrelatedClassesToString());
633+
634+
rdfxml = rdfxmlGenerator.generate();
635+
File saveFile = showSaveFileDialog("rdf.rdf", "Save RDF/XML Document", null);
636+
if (saveFile != null){
637+
try {
638+
FileWriter writer = new FileWriter(saveFile);
639+
writer.write(rdfxml);
640+
writer.flush();
641+
writer.close();
642+
statusLbl.setText("RDF/XML saved.");
643+
} catch (IOException e) {
644+
e.printStackTrace();
645+
}
646+
}
647+
}
648+
649+
private void showManualCorrelationDialog(RDFXMLGenerator generator){
650+
ArrayList<RDFXMLGenerator> data = new ArrayList<>();
651+
data.add(generator);
652+
showWindow("/view/correlateDialog.fxml", "Set Manual Correlations", data);
653+
}
591654
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package controller;
2+
3+
import javafx.beans.binding.BooleanBinding;
4+
import javafx.beans.property.BooleanProperty;
5+
import javafx.beans.property.SimpleBooleanProperty;
6+
import javafx.collections.FXCollections;
7+
import javafx.fxml.FXML;
8+
import javafx.fxml.Initializable;
9+
import javafx.scene.control.Button;
10+
import javafx.scene.control.ListView;
11+
import javafx.stage.Stage;
12+
import javafx.util.Pair;
13+
import model.conceptual.Vertex;
14+
import model.conversion.rdfxml.Correlation;
15+
import model.conversion.rdfxml.RDFXMLGenerator;
16+
17+
import java.net.URL;
18+
import java.util.ArrayList;
19+
import java.util.ResourceBundle;
20+
import java.util.stream.Collectors;
21+
22+
public class CorrelateDialogController extends AbstractDataSharingController<RDFXMLGenerator> implements Initializable {
23+
@FXML Button addManualCorrBtn, addHeaderBtn, commitBtn, cancelBtn;
24+
@FXML ListView<String> csvHeaderList;
25+
@FXML ListView<String> csvTtlCorrelationList;
26+
@FXML ListView<String> ttlHeaderList;
27+
28+
private BooleanProperty isSelectionFromCsvList = new SimpleBooleanProperty(false);
29+
private BooleanProperty isSelectionFromTtlList = new SimpleBooleanProperty(false);
30+
private BooleanBinding isSelectionFromBothLists = isSelectionFromCsvList.and(isSelectionFromTtlList);
31+
32+
private BooleanProperty isCsvListEmpty = new SimpleBooleanProperty(false);
33+
private BooleanProperty isTtlListEmpty = new SimpleBooleanProperty(false);
34+
35+
private ArrayList<Correlation> correlations = new ArrayList<>();
36+
private ArrayList<String> uncorrelatedCsvHeaders;
37+
private ArrayList<Vertex> uncorrelatedTtlClasses;
38+
private ArrayList<String> uncorrelatedTtlClassNames;
39+
40+
private RDFXMLGenerator rdfxmlGenerator;
41+
42+
@Override public void initialize(URL location, ResourceBundle resources) {
43+
isSelectionFromBothLists.addListener((observable, oldV, newV) -> {
44+
if (observable.getValue().booleanValue()) addManualCorrBtn.setDisable(false);
45+
else addManualCorrBtn.setDisable(true);
46+
});
47+
48+
isCsvListEmpty.addListener(((observable, oldV, newV) -> {
49+
if (observable.getValue().booleanValue()) commitBtn.setDisable(false);
50+
else commitBtn.setDisable(true);
51+
}));
52+
53+
csvHeaderList.getSelectionModel().selectedItemProperty().addListener((observable, oldV, newV) -> {
54+
if (csvHeaderList.getItems().isEmpty()) isCsvListEmpty.setValue(true);
55+
if (oldV == null) isSelectionFromCsvList.setValue(true);
56+
else if (newV == null) isSelectionFromCsvList.setValue(false);
57+
});
58+
59+
ttlHeaderList.getSelectionModel().selectedItemProperty().addListener(((observable, oldV, newV) -> {
60+
if (ttlHeaderList.getItems().isEmpty()) isTtlListEmpty.setValue(true);
61+
if (oldV == null) isSelectionFromTtlList.setValue(true);
62+
else if (newV == null) isSelectionFromTtlList.setValue(false);
63+
}));
64+
}
65+
66+
@FXML void addManualCorrelationAction() {
67+
String selectedCsvHeader = csvHeaderList.getSelectionModel().getSelectedItem();
68+
int index = Integer.parseInt(selectedCsvHeader.split(" ")[0]);
69+
String csvAttribute = selectedCsvHeader.split(" ")[1];
70+
String selectedTtlClass = ttlHeaderList.getSelectionModel().getSelectedItem();
71+
Vertex ttlClass = null;
72+
for (Vertex klass : uncorrelatedTtlClasses) {
73+
String klassName = klass.getName().toLowerCase();
74+
String selectedKlass = selectedTtlClass.toLowerCase();
75+
76+
if (klassName.equals(selectedKlass)) {
77+
ttlClass = klass;
78+
uncorrelatedTtlClasses.remove(klass);
79+
uncorrelatedTtlClassNames.remove(selectedTtlClass);
80+
uncorrelatedCsvHeaders.remove(selectedCsvHeader);
81+
ttlHeaderList.getItems().remove(selectedTtlClass);
82+
csvHeaderList.getItems().remove(selectedCsvHeader);
83+
ttlHeaderList.getSelectionModel().clearSelection();
84+
csvHeaderList.getSelectionModel().clearSelection();
85+
break;
86+
}
87+
}
88+
89+
correlations.add(new Correlation(index, csvAttribute, ttlClass));
90+
ArrayList<String> correlationStrList = correlations
91+
.stream()
92+
.map(Correlation::toString)
93+
.collect(Collectors.toCollection(ArrayList::new));
94+
csvTtlCorrelationList.setItems(FXCollections.observableArrayList(correlationStrList));
95+
}
96+
97+
@FXML void addHeaderAction() {
98+
99+
}
100+
101+
@FXML void commitCorrelationBtn() {
102+
rdfxmlGenerator.setCorrelations(correlations);
103+
rdfxmlGenerator.setUncorrelated(new Pair<>(uncorrelatedCsvHeaders, uncorrelatedTtlClasses));
104+
Stage stage = (Stage) commitBtn.getScene().getWindow();
105+
stage.close();
106+
}
107+
108+
@FXML void cancelCorrelationBtn() {
109+
Stage stage = (Stage) cancelBtn.getScene().getWindow();
110+
stage.close();
111+
}
112+
113+
@Override
114+
public void setData(ArrayList<RDFXMLGenerator> data) {
115+
RDFXMLGenerator generator = data.get(0);
116+
117+
rdfxmlGenerator = generator;
118+
correlations = rdfxmlGenerator.getCorrelations();
119+
ArrayList<String> correlationStrings = correlations
120+
.stream()
121+
.map(Correlation::toString)
122+
.collect(Collectors.toCollection(ArrayList::new));
123+
124+
csvTtlCorrelationList.setItems(FXCollections.observableArrayList(correlationStrings));
125+
126+
uncorrelatedCsvHeaders = rdfxmlGenerator.getUncorrelated().getKey();
127+
csvHeaderList.setItems(FXCollections.observableArrayList(uncorrelatedCsvHeaders));
128+
uncorrelatedTtlClasses = generator.getUncorrelated().getValue();
129+
uncorrelatedTtlClassNames = uncorrelatedTtlClasses
130+
.stream()
131+
.map(Vertex::getName)
132+
.collect(Collectors.toCollection(ArrayList::new));
133+
ttlHeaderList.setItems(FXCollections.observableArrayList(uncorrelatedTtlClassNames));
134+
}
135+
136+
@Override
137+
public ArrayList<RDFXMLGenerator> getData() {
138+
ArrayList<RDFXMLGenerator> data = new ArrayList<>();
139+
data.add(rdfxmlGenerator);
140+
return data;
141+
}
142+
}

src/controller/OptionsMenuController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ public class OptionsMenuController extends AbstractDataSharingController<Boolean
1414
@FXML Button cancelBtn, commitBtn;
1515
@FXML CheckBox collectionsCbx, blankCbx, ontologyCbx;
1616

17-
private ArrayList<Boolean> commit_config = new ArrayList<>();
17+
private ArrayList<Boolean> commit_config;
1818

1919
/**
2020
* Commits the changes to the base Controller.
2121
*/
2222
@FXML void commitConfigBtn() {
23+
commit_config = new ArrayList<>();
2324
commit_config.add(collectionsCbx.isSelected());
2425
commit_config.add(blankCbx.isSelected());
2526
commit_config.add(ontologyCbx.isSelected());

0 commit comments

Comments
 (0)