Skip to content
Snippets Groups Projects
Commit c6acddbc authored by Jesper Zedlitz's avatar Jesper Zedlitz
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Pipeline #168 passed
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
cache:
paths:
- .m2/repository
stages:
- build
build:
stage: build
image: maven:3-openjdk-11
script: "mvn clean package -B"
artifacts:
paths:
- target/*.jar
pom.xml 0 → 100644
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.landsh.opendata</groupId>
<artifactId>data-proxy</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>data-proxy</name>
<description>Ein Proxy zum Bereitstellen von Daten</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jena.version>4.2.0</jena.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>4.5</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>de.landsh.opendata.dataproxy.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version>
</dependency>
<dependency>
<groupId>org.nanohttpd</groupId>
<artifactId>nanohttpd</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.nanohttpd</groupId>
<artifactId>nanohttpd-nanolets</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.5</version>
</dependency>
</dependencies>
</project>
/** Grammars always start with a grammar header. This grammar is called
* ArrayInit and must match the filename: ArrayInit.g4
*/
grammar CoronaData;
/** A rule called init that matches comma-separated values between {...}. */
data : 'var data = {' (entry ',' ) * '}' ;
entry : QUOTE ARS QUOTE ':' '{' pair (',' pair)* '}' ;
pair: NAME ':' VALUE ;
NAME: [a-z_]+ ;
WS : [ \t\r\n]+ -> skip ; // Define whitespace rule, toss it out
QUOTE: [\'\"] ;
ARS: '010' [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ;
VALUE: [0-9]+ '.'? [0-9]* ;
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.router.RouterNanoHTTPD;
import fi.iki.elonen.util.ServerRunner;
public class App extends RouterNanoHTTPD {
public static final int PORT = 8080;
@Override
public void addMappings() {
super.addMappings();
addRoute("/strassen-sh.geojson", StrassenSH2Geojson.class);
addRoute("/corona-rd-eck.json", CoronaRdEck.class);
}
public App() {
super(PORT);
addMappings();
System.out.println("\nRunning! Point your browser to http://localhost:" + PORT + "/ \n");
}
public static void main(String[] args) {
ServerRunner.run(App.class);
}
}
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import java.io.IOException;
public abstract class CachingDataConverter extends RouterNanoHTTPD.DefaultHandler {
/**
* Return the update interval in milliseconds;
*/
abstract int getUpdateInterval();
abstract String loadData() throws IOException;
}
package de.landsh.opendata.dataproxy;
import de.landsh.opendata.coronardeck.CoronaDataLexer;
import de.landsh.opendata.coronardeck.CoronaDataParser;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.util.Map;
public class CoronaRdEck implements RouterNanoHTTPD.UriResponder {
public static final int UPDATE_INTERVAL = 600000; // 10 minutes
private static String data = "{}";
private static long lastUpdate = -1;
private static NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
String loadData() throws IOException {
InputStream inputStream = new URL("https://covid19dashboardrdeck.aco/daten/daten.js").openStream();
final ANTLRInputStream input = new ANTLRInputStream(inputStream);
final CoronaDataLexer lexer = new CoronaDataLexer(input);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final CoronaDataParser parser = new CoronaDataParser(tokens);
final ParseTree tree = parser.data();
final ParseTreeWalker walker = new ParseTreeWalker();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos);
walker.walk(new CoronaRdEckWalker(out), tree);
out.close();
inputStream.close();
return baos.toString();
}
@Override
public NanoHTTPD.Response get(RouterNanoHTTPD.UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) {
if (System.currentTimeMillis() - UPDATE_INTERVAL > lastUpdate) {
System.out.println("Loading data for " + getClass().getName());
try {
data = loadData();
status = NanoHTTPD.Response.Status.OK;
} catch (IOException e) {
data = "{}";
status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
}
lastUpdate = System.currentTimeMillis();
}
return NanoHTTPD.newFixedLengthResponse(status, "application/json", data);
}
@Override
public NanoHTTPD.Response put(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response post(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response delete(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response other(String s, RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
}
package de.landsh.opendata.dataproxy;
import de.landsh.opendata.coronardeck.CoronaDataBaseListener;
import de.landsh.opendata.coronardeck.CoronaDataParser;
import java.io.PrintStream;
public class CoronaRdEckWalker extends CoronaDataBaseListener {
private final PrintStream out;
public CoronaRdEckWalker(PrintStream out) {
super();
this.out = out;
}
@Override
public void enterData(CoronaDataParser.DataContext ctx) {
out.println("{");
boolean firstEntry = true;
for (CoronaDataParser.EntryContext entry : ctx.entry()) {
if (firstEntry) {
firstEntry = false;
} else {
out.println(",");
}
out.print("\"" + entry.ARS() + "\": {");
boolean firstPair = true;
for (CoronaDataParser.PairContext pair : entry.pair()) {
if (firstPair) {
firstPair = false;
} else {
out.print(",");
}
out.print("\"" + pair.NAME() + "\" : ");
out.print(pair.VALUE());
}
out.print("}");
}
out.println(" }");
}
}
package de.landsh.opendata.dataproxy;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
public class StrassenSH2Geojson implements RouterNanoHTTPD.UriResponder {
public static final int UPDATE_INTERVAL = 180000; // 3 minutes
private static String data = "{}";
private static long lastUpdate = -1;
private static NanoHTTPD.Response.Status status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
String loadData() throws IOException {
System.out.println("Loading data from strassen-sh.de...");
final JSONObject featureCollection = new JSONObject();
featureCollection.put("type", "FeatureCollection");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/2/100").openStream(), "frei");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/6/100").openStream(), "gestaut");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/4/100").openStream(), "dicht");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/5/100").openStream(), "zähfließend");
processQuery(featureCollection, new URL("https://strassen-sh.de/proxy/geojson/los/9/100").openStream(), "Datenausfall");
return featureCollection.toString();
}
private void processQuery(JSONObject featureCollection, InputStream in, String status) {
if (!featureCollection.has("features")) {
featureCollection.put("features", new JSONArray());
}
final JSONObject json = new JSONObject(new JSONTokener(in));
final JSONArray featuresOut = featureCollection.getJSONArray("features");
final JSONArray featuresIn = json.getJSONArray("features");
for (int i = 0; i < featuresIn.length(); i++) {
final JSONObject featureIn = featuresIn.getJSONObject(i);
final JSONObject featureOut = convertFeature(featureIn);
featureOut.getJSONObject("properties").put("status", status);
featuresOut.put(featureOut);
}
if (json.has("properties")) {
featureCollection.put("properties", json.getJSONObject("properties"));
}
}
JSONObject convertFeature(JSONObject feature) {
final JSONObject result = new JSONObject();
result.put("type", "Feature");
final JSONObject geometry = new JSONObject();
final JSONObject properties = feature.getJSONObject("properties");
final String type = feature.getString("type");
final JSONArray coordinates = feature.getJSONArray("coordinates");
result.put("properties", properties);
result.put("id", coordinates.hashCode());
geometry.put("type", type);
geometry.put("coordinates", coordinates);
result.put("geometry", geometry);
return result;
}
@Override
public NanoHTTPD.Response get(RouterNanoHTTPD.UriResource uriResource, Map<String, String> urlParams, NanoHTTPD.IHTTPSession session) {
if (System.currentTimeMillis() - UPDATE_INTERVAL > lastUpdate) {
System.out.println("Loading data for " + getClass().getName());
try {
data = loadData();
status = NanoHTTPD.Response.Status.OK;
} catch (IOException e) {
data = "{}";
status = NanoHTTPD.Response.Status.INTERNAL_ERROR;
}
lastUpdate = System.currentTimeMillis();
}
return NanoHTTPD.newFixedLengthResponse(status, "application/geo+json", data);
}
@Override
public NanoHTTPD.Response put(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response post(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response delete(RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
@Override
public NanoHTTPD.Response other(String s, RouterNanoHTTPD.UriResource uriResource, Map<String, String> map, NanoHTTPD.IHTTPSession ihttpSession) {
return NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.METHOD_NOT_ALLOWED, "text/plain", "method not allowed");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment