Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,21 @@ The `time` object should contain the following parameters:
- "first" (furthest back time value in RDB)
Defaults to "now".

The `trajectory` object should contain the following parameters, more descriptions of the file contents are given in [here](#trajectory-queries):
For clarification, the `limit` value supports both positive and negative integers. For reference types of `now` and `latest` it is multiplied by **-1** then **added** to the reference time during the calculation of retrieval times. For references of `first` is is simply **added** to the reference time.

For example, a value of `24` with a reference of `now` will provide all values generated within the last real-world day. Whereas a value of `24` with a reference of `first` will return all values generated between the first data point and one real-world day afterwards.

The `trajectory` should be an array of JSON objects, where each of these objects should contain the following parameters:

- Required:
- `pointIriQuery`: Location of file with SPARQL query used to get point IRIs containing time series (relative to configuration file).
- `featureIriQuery`: Location of file with SQL/SPARQL query to obtain the intersected feature IRIs (relative to configuration file).
- `metaQuery`: Location of file with SPARQL query to obtain metadata of the intersected features (relative to configuration file).
- `database`: Database containing time series data of the points.

For clarification, the `limit` value supports both positive and negative integers. For reference types of `now` and `latest` it is multiplied by **-1** then **added** to the reference time during the calculation of retrieval times. For references of `first` is is simply **added** to the reference time.

For example, a value of `24` with a reference of `now` will provide all values generated within the last real-world day. Whereas a value of `24` with a reference of `first` will return all values generated between the first data point and one real-world day afterwards.
More descriptions of the file contents are given in [here](#trajectory-queries).

Within the [samples/fia/fia-config.json](./samples/fia/fia-config.json) file, a mock configuration can be found.
Within the [sample/fia/fia-config.json](./sample/fia/fia-config.json) file, a mock configuration can be found.

### Expected query formats

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,18 @@ public JSONObject processRequest(Request request, HttpServletResponse response)
result.put("time", timedata);
}
if (trajectoryData != null && !trajectoryData.isEmpty()) {
result.put("meta", trajectoryData);
if (result.has("meta")) {
// append to existing metadata object
trajectoryData.keySet().forEach(k -> {
if (metadata.has(k)) {
LOGGER.warn("Trajectory data and metadata has the same label: {}", k);
} else {
metadata.put(k, trajectoryData.get(k));
}
});
} else {
result.put("meta", trajectoryData);
}
}

return result;
Expand All @@ -149,7 +160,7 @@ public JSONObject processRequest(Request request, HttpServletResponse response)
* and which
* configuration entries match said classes.
*
* @param iri feature IRI.
* @param iri feature IRI.
*
* @return Set of matching configuration entries.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;

import com.google.common.base.Objects;

Expand Down Expand Up @@ -74,13 +77,7 @@ public class ConfigEntry {
*/
private String timeDatabase;

private String pointIriQueryFile;
private String pointIriQueryContent;
private String featureIriQueryFile;
private String featureIriQueryContent;
private String trajectoryMetaFile;
private String trajectoryMetaContent;
private String trajectoryDatabase;
private List<TrajectoryConfigEntry> trajectoryConfigEntryList;

/**
* Initialise a new ConfigEntry instance.
Expand Down Expand Up @@ -172,20 +169,8 @@ public String getTimeDatabase() {
return this.timeDatabase;
}

public String getPointIriQuery() {
return pointIriQueryContent;
}

public String getFeatureIriQuery() {
return featureIriQueryContent;
}

public String getTrajectoryMetaQuery() {
return trajectoryMetaContent;
}

public String getTrajectoryDatabase() {
return trajectoryDatabase;
public List<TrajectoryConfigEntry> getTrajectoryConfigEntries() {
return trajectoryConfigEntryList;
}

/**
Expand All @@ -204,10 +189,6 @@ public int hashCode() {
hash = prime * hash + (this.timeLimitValue);
hash = prime * hash + (this.timeLimitUnit != null ? this.timeLimitUnit.hashCode() : 0);
hash = prime * hash + (this.timeDatabase != null ? this.timeDatabase.hashCode() : 0);
hash = prime * hash + (this.pointIriQueryFile != null ? this.pointIriQueryFile.hashCode() : 0);
hash = prime * hash + (this.featureIriQueryFile != null ? this.featureIriQueryFile.hashCode() : 0);
hash = prime * hash + (this.trajectoryMetaFile != null ? this.trajectoryMetaFile.hashCode() : 0);
hash = prime * hash + (this.trajectoryDatabase != null ? this.trajectoryDatabase.hashCode() : 0);
return hash;
}

Expand Down Expand Up @@ -241,14 +222,6 @@ public boolean equals(Object object) {
return false;
if (!Objects.equal(this.timeDatabase, that.timeDatabase))
return false;
if (!Objects.equal(this.pointIriQueryFile, that.pointIriQueryFile))
return false;
if (!Objects.equal(this.featureIriQueryFile, that.featureIriQueryFile))
return false;
if (!Objects.equal(this.trajectoryMetaFile, that.trajectoryMetaFile))
return false;
if (!Objects.equal(this.trajectoryDatabase, that.trajectoryDatabase))
return false;

return true;
}
Expand Down Expand Up @@ -294,7 +267,7 @@ public ConfigEntry build(
String classIRI,
String metaQueryFile) throws IllegalArgumentException, IOException {

return build(id, classIRI, metaQueryFile, null, null, 0, null, null);
return build(id, classIRI, metaQueryFile, null, null, 0, null, null, new JSONArray());
}

/**
Expand Down Expand Up @@ -322,7 +295,8 @@ public ConfigEntry build(
String timeLimitUnit,
String timeDatabase) throws IllegalArgumentException, IOException {

return build(id, classIRI, null, timeQueryFile, timeReference, timeLimitValue, timeLimitUnit, timeDatabase);
return build(id, classIRI, null, timeQueryFile, timeReference, timeLimitValue, timeLimitUnit, timeDatabase,
new JSONArray());
}

/**
Expand Down Expand Up @@ -350,7 +324,8 @@ public ConfigEntry build(
String timeReference,
int timeLimitValue,
String timeLimitUnit,
String timeDatabase) throws IllegalArgumentException, IOException {
String timeDatabase,
JSONArray trajectoryConfig) throws IllegalArgumentException, IOException {

// Check for valid parameters
if (timeQueryFile != null && !timeQueryFile.isEmpty() && (timeDatabase == null || timeDatabase.isEmpty())) {
Expand Down Expand Up @@ -397,37 +372,18 @@ public ConfigEntry build(

entry.timeDatabase = timeDatabase;

// Populate query contents
readQueryContent(entry);
return entry;
}

/**
* special case for trajectory query
*
* @param id
* @param classIRI
* @param trajectoryQuery
* @param featureIriQuery
* @param metaQuery
* @return
* @throws IOException
*/
public ConfigEntry build(
String id,
String classIRI,
String pointIriQuery,
String featureIriQuery,
String metaQuery,
String database) throws IOException {

// Create and return ConfigEntry instance.
ConfigEntry entry = new ConfigEntry(id);
entry.classIRI = classIRI;
entry.pointIriQueryFile = pointIriQuery;
entry.featureIriQueryFile = featureIriQuery;
entry.trajectoryMetaFile = metaQuery;
entry.trajectoryDatabase = database;
// trajectory stuff
entry.trajectoryConfigEntryList = new ArrayList<>();
for (int i = 0; i < trajectoryConfig.length(); i++) {
TrajectoryConfigEntry trajectoryConfigEntry = new TrajectoryConfigEntry();
trajectoryConfigEntry.pointIriQueryFile = trajectoryConfig.getJSONObject(i).getString("pointIriQuery");
trajectoryConfigEntry.featureIriQueryFile = trajectoryConfig.getJSONObject(i)
.getString("featureIriQuery");
trajectoryConfigEntry.trajectoryMetaFile = trajectoryConfig.getJSONObject(i).getString("metaQuery");
trajectoryConfigEntry.trajectoryDatabase = trajectoryConfig.getJSONObject(i).getString("database");

entry.trajectoryConfigEntryList.add(trajectoryConfigEntry);
}

// Populate query contents
readQueryContent(entry);
Expand Down Expand Up @@ -462,20 +418,51 @@ private void readQueryContent(ConfigEntry entry) throws IOException {
}

// Parse trajectory query
if (entry.pointIriQueryFile != null && !entry.pointIriQueryFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(entry.pointIriQueryFile));
entry.pointIriQueryContent = Files.readString(file);
}
if (entry.featureIriQueryFile != null && !entry.featureIriQueryFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(entry.featureIriQueryFile));
entry.featureIriQueryContent = Files.readString(file);
}
if (entry.trajectoryMetaFile != null && !entry.trajectoryMetaFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(entry.trajectoryMetaFile));
entry.trajectoryMetaContent = Files.readString(file);
for (TrajectoryConfigEntry trajectoryConfigEntry : entry.trajectoryConfigEntryList) {
if (trajectoryConfigEntry.pointIriQueryFile != null
&& !trajectoryConfigEntry.pointIriQueryFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(trajectoryConfigEntry.pointIriQueryFile));
trajectoryConfigEntry.pointIriQueryContent = Files.readString(file);
}
if (trajectoryConfigEntry.featureIriQueryFile != null
&& !trajectoryConfigEntry.featureIriQueryFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(trajectoryConfigEntry.featureIriQueryFile));
trajectoryConfigEntry.featureIriQueryContent = Files.readString(file);
}
if (trajectoryConfigEntry.trajectoryMetaFile != null
&& !trajectoryConfigEntry.trajectoryMetaFile.isEmpty()) {
Path file = this.configDirectory.resolve(Paths.get(trajectoryConfigEntry.trajectoryMetaFile));
trajectoryConfigEntry.trajectoryMetaContent = Files.readString(file);
}
}
}
}

public static class TrajectoryConfigEntry {
private String pointIriQueryFile;
private String pointIriQueryContent;
private String featureIriQueryFile;
private String featureIriQueryContent;
private String trajectoryMetaFile;
private String trajectoryMetaContent;
private String trajectoryDatabase;

public String getPointIriQuery() {
return pointIriQueryContent;
}

public String getFeatureIriQuery() {
return featureIriQueryContent;
}

public String getTrajectoryMetaQuery() {
return trajectoryMetaContent;
}

public String getTrajectoryDatabase() {
return trajectoryDatabase;
}
}

}
// End of class.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private ConfigEntry parseEntry(Path configDir, JSONObject jsonEntry)
// Initialise a new builder
ConfigEntryBuilder builder = new ConfigEntryBuilder(configDir);

if (jsonEntry.has("meta") || jsonEntry.has("time")) {
if (jsonEntry.has("meta") || jsonEntry.has("time") || jsonEntry.has("trajectory")) {
// New format entry
String id = jsonEntry.getString("id");
String clazz = jsonEntry.getString("class");
Expand Down Expand Up @@ -139,22 +139,18 @@ private ConfigEntry parseEntry(Path configDir, JSONObject jsonEntry)
timeDatabase = timeEntry.optString("database");
}

// Build
return builder.build(id, clazz, metaFile, timeFile, timeReference, timeLimit, timeUnit, timeDatabase);
} else if (jsonEntry.has("trajectory")) { // special trajectory case
// TODO: in futrue, it would be best to do tragectory calculations all in a
// single sparql query. This requires the time series being kg accessible.
String id = jsonEntry.getString("id");
String clazz = jsonEntry.getString("class");

// trajectory details
JSONObject trajectoryEntry = jsonEntry.getJSONObject("trajectory");
String pointIriQuery = trajectoryEntry.getString("pointIriQuery");
String featureIriQuery = trajectoryEntry.getString("featureIriQuery");
String metaQuery = trajectoryEntry.getString("metaQuery");
String timeDatabase = trajectoryEntry.optString("database");
// Trajectory
JSONArray trajectoryConfig;
if (jsonEntry.has("trajectory")) {
LOGGER.info("Detected trajectory config for {}", clazz);
trajectoryConfig = jsonEntry.getJSONArray("trajectory");
} else {
trajectoryConfig = new JSONArray();
}

return builder.build(id, clazz, pointIriQuery, featureIriQuery, metaQuery, timeDatabase);
// Build
return builder.build(id, clazz, metaFile, timeFile, timeReference, timeLimit, timeUnit, timeDatabase,
trajectoryConfig);
} else {
// Assume old format entry
String id = "entry-" + (entries.size() + 1);
Expand All @@ -171,7 +167,8 @@ private ConfigEntry parseEntry(Path configDir, JSONObject jsonEntry)
String timeDatabase = jsonEntry.optString("databaseName");

// Build
return builder.build(id, clazz, metaFile, timeFile, timeReference, timeLimit, timeUnit, timeDatabase);
return builder.build(id, clazz, metaFile, timeFile, timeReference, timeLimit, timeUnit, timeDatabase,
new JSONArray());
}

}
Expand Down
Loading