-
Notifications
You must be signed in to change notification settings - Fork 4
/
TarqlModule.java
171 lines (132 loc) · 6.53 KB
/
TarqlModule.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package cz.cvut.spipes.modules;
import cz.cvut.spipes.constants.AppConstants;
import cz.cvut.spipes.constants.KBSS_MODULE;
import cz.cvut.spipes.constants.SML;
import cz.cvut.spipes.engine.ExecutionContext;
import cz.cvut.spipes.engine.ExecutionContextFactory;
import cz.cvut.spipes.modules.annotations.SPipesModule;
import cz.cvut.spipes.registry.StreamResource;
import cz.cvut.spipes.registry.StreamResourceRegistry;
import org.apache.jena.ext.com.google.common.io.Files;
import org.apache.jena.query.Query;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.util.FileUtils;
import org.deri.tarql.tarql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.topbraid.spin.arq.ARQFactory;
import org.topbraid.spin.model.Construct;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
// TODO merge with ModuleTarql functionality
@SPipesModule(label = "tarql", comment = "\"Runs one or more TARQL Construct queries on the input triples. The output RDF " +
"will consist of the constructed triples and (unless sml:replace is true) the input triples.\"")
public class TarqlModule extends AbstractModule {
private static final Logger LOG = LoggerFactory.getLogger(TarqlModule.class);
//tarql [options] query.sparql [table.csv [...]]
private static final String TARQL_PROGRAM = AppConstants.BIN_DIR + "/tarql";
//sml:constructQuery
@Parameter(urlPrefix = SML.uri, name = "constructQuery", comment = "The TARQL Construct queries that deliver the triples that shall be added.")
private List<Resource> constructQueries;
// TODO not used field
private String tableFilePath;
//sml:replace
@Parameter(urlPrefix = SML.uri, name = "replace", comment = "If set to true, the output triples will only contain the " +
"constructed triples. If no values or false are specified, the output will be the union of the input triples " +
"and the constructed triples.")
private boolean isReplace;
//sml:sourceFilePath
@Parameter(urlPrefix = SML.uri, name = "sourceFilePath", comment = "Source CSV file.")
private String sourceFilePath;
public TarqlModule() {
//SPINModuleRegistry.get().init(); // TODO move elsewhere
}
@Override
public ExecutionContext executeSelf() {
//Model defaultInputModel = context.getDefaultModel();
// TODO full external context support
// set variable binding
// TODO implement support for input graph
// (naive solution would be to create s,p,o columns in new CSV file),
// but this has problems with blank nodes
Path p = Paths.get("/home/blcha/s-pipes-log.txt");
Model mergedModel = ModelFactory.createDefaultModel();
if (! isReplace) { // TODO mozno sa mozu zmenit blank nody (asi by som mal mergovat do defaultneho modelu ?)
if (executionContext.getDefaultModel() != null) {
mergedModel.add(executionContext.getDefaultModel());
}
}
StreamResource res = StreamResourceRegistry.getInstance().getResourceByUrl(sourceFilePath);
String tabularDataFilePath = null;
if (res != null) {
try {
File tabularDataFile = File.createTempFile("output", ".tabular.txt");
Files.write(res.getContent(), tabularDataFile);
tabularDataFilePath = tabularDataFile.getAbsolutePath();
} catch (IOException e) {
throw new RuntimeException("Could not write tabular data stream to temporary file: {}", e);
}
} else {
tabularDataFilePath = sourceFilePath;
}
LOG.debug("Processing tabular data from file path {}.", tabularDataFilePath);
// set up variable bindings
for (Resource constructQueryRes : constructQueries) {
Construct spinConstructRes = constructQueryRes.as(Construct.class);
Query query = ARQFactory.get().createQuery(spinConstructRes);
try {
// save string query to temporary file
final File queryFile = File.createTempFile("query", ".tarql");
final String queryString = query.toString();
//final String queryString = query.toString().replaceAll("\\?__FN__", "\"" + ontologyIRI + "\"");
Files.append(query.toString(), queryFile, Charset.defaultCharset());
//java.nio.file.Files.write(Paths.get(queryFile.toURI()), queryString.getBytes());
// execute tarql query.sparql table.csv
final File outputFile = File.createTempFile("output", ".ttl");
try (PrintStream s = new PrintStream(new FileOutputStream(outputFile))) {
final PrintStream origStream = System.out;
System.setOut(s);
tarql.main(
// "--ntriples",
// noHeader ? "-H" : "",
queryFile.getAbsolutePath(),
tabularDataFilePath
);
System.setOut(origStream);
// merge output to model
mergedModel.read(new FileInputStream(outputFile), null, FileUtils.langTurtle);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//newModel.write(System.out, FileUtils.langTurtle);
//TODO should return only Model ???
ExecutionContext ec = ExecutionContextFactory.createContext(mergedModel);
return ec;
}
@Override
public String getTypeURI() {
return KBSS_MODULE.getURI()+"tarql";
}
@Override
public void loadConfiguration() {
// TODO load default values from configuration
// TODO does not work with string query as object is not RDF resource ???
constructQueries = resource
.listProperties(SML.constructQuery)
.toList().stream()
.map(st -> st.getObject().asResource())
.collect(Collectors.toList());
LOG.debug("Loaded {} spin construct queries.", constructQueries.size());
//TODO default value must be taken from template definition
isReplace = this.getPropertyValue(SML.replace, false);
sourceFilePath = getEffectiveValue(SML.sourceFilePath).asLiteral().toString(); // TODO should be Path
}
}