package tempo.vdm;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.overture.interpreter.values.CharacterValue;
import org.overture.interpreter.values.MapValue;
import org.overture.interpreter.values.NaturalOneValue;
import org.overture.interpreter.values.SeqValue;
import org.overture.interpreter.values.SetValue;
import org.overture.interpreter.values.Value;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import nl.west.rme.common.util.Streams;
import nl.west.rme.common.util.Text;
public class RoadIO {
public static class World {
public Map<Integer, Node> id2node;
public Map<Integer, Edge> id2edge;
@Override
public String toString() {
return "World[nodes=" + id2node.values() + ", edges=" + id2edge.values() + "]";
}
}
public static class Node {
public final int id;
public Node(int id) {
this.id = id;
}
@Override
public String toString() {
return "Node#" + id;
}
}
public static class Edge {
public final int id;
public final Node src, dst;
public int length;
public int speedLimit;
public int capacity;
public Edge(int id, Node src, Node dst) {
if (src == null)
throw new NullPointerException();
if (dst == null)
throw new NullPointerException();
this.id = id;
this.src = src;
this.dst = dst;
}
@Override
public String toString() {
return "Edge#" + id + "[" + src.id + " --> " + dst.id + "]";
}
}
private Set<Integer> nodeIds;
private Map<Integer, List<Integer>> edge2srcAndDst;
private Map<Integer, Integer> edge2length;
private Map<Integer, Integer> edge2speedLimit;
private Map<Integer, Integer> edge2capacity;
private class WorldDeserializer implements JsonDeserializer<World> {
private final World world;
public WorldDeserializer(World world) {
this.world = world;
}
@Override
public World deserialize(JsonElement elem, Type type, JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = (JsonObject) elem;
world.id2node = new HashMap<>();
for (JsonElement item : obj.getAsJsonArray("nodes")) {
Node node = context.deserialize(item, Node.class);
if (world.id2node.put(node.id, node) != null) {
throw new IllegalStateException("duplicate " + node);
}
}
world.id2edge = new HashMap<>();
for (JsonElement item : obj.getAsJsonArray("edges")) {
Edge edge = context.deserialize(item, Edge.class);
if (world.id2edge.put(edge.id, edge) != null) {
throw new IllegalStateException("duplicate " + edge);
}
}
return world;
}
}
private class NodeDeserializer implements JsonDeserializer<Node> {
@Override
public Node deserialize(JsonElement elem, Type type, JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = (JsonObject) elem;
Node node = new Node(obj.get("id").getAsInt());
return node;
}
}
private class EdgeDeserializer implements JsonDeserializer<Edge> {
private final World world;
public EdgeDeserializer(World world) {
this.world = world;
}
@Override
public Edge deserialize(JsonElement elem, Type type, JsonDeserializationContext context)
throws JsonParseException {
JsonObject obj = (JsonObject) elem;
int id = obj.get("id").getAsInt();
int srcNodeId = obj.get("src").getAsInt();
int dstNodeId = obj.get("dst").getAsInt();
Node srcNode = world.id2node.get(srcNodeId);
Node dstNode = world.id2node.get(dstNodeId);
Edge edge = new Edge(id, srcNode, dstNode);
edge.length = obj.get("length").getAsInt();
edge.speedLimit = obj.get("speedLimit").getAsInt();
edge.capacity = obj.get("capacity").getAsInt();
return edge;
}
}
public Value load(Value pathValue) {
try {
String path = fromCharSeq((SeqValue) pathValue);
System.out.println("Loading data from path: '" + path + "'");
World world = new World();
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(World.class, new WorldDeserializer(world));
gson.registerTypeAdapter(Edge.class, new EdgeDeserializer(world));
gson.registerTypeAdapter(Node.class, new NodeDeserializer());
InputStream in = RoadIO.class.getResourceAsStream(path);
String json = Text.utf8(Streams.readFully(in));
gson.create().fromJson(json, World.class);
// convert objects to data structures of primitives
nodeIds = new HashSet<>();
edge2srcAndDst = new HashMap<>();
edge2length = new HashMap<>();
edge2speedLimit = new HashMap<>();
edge2capacity = new HashMap<>();
for (Node node : world.id2node.values()) {
nodeIds.add(node.id);
}
for (Edge edge : world.id2edge.values()) {
edge2srcAndDst.put(edge.id, Arrays.asList(edge.src.id, edge.dst.id));
edge2length.put(edge.id, edge.length);
edge2speedLimit.put(edge.id, edge.speedLimit);
edge2capacity.put(edge.id, edge.capacity);
}
assert edge2srcAndDst.size() == edge2length.size();
assert edge2srcAndDst.size() == edge2speedLimit.size();
assert edge2srcAndDst.size() == edge2capacity.size();
// return dummy value
return toNat1(1);
} catch (Exception e) {
e.printStackTrace(System.out);
throw new IllegalStateException(e);
}
}
public Value getNodeIds() {
if (nodeIds == null)
throw new IllegalStateException();
return toNat1Set(nodeIds);
}
public Value getEdgeIdSrcAndDsts() {
if (nodeIds == null)
throw new IllegalStateException();
return toNat1Nat1sMap(edge2srcAndDst);
}
public Value getEdgeIdLengths() {
if (edge2length == null)
throw new IllegalStateException();
return toNat1Nat1Map(edge2length);
}
public Value getEdgeIdSpeedLimits() {
if (edge2speedLimit == null)
throw new IllegalStateException();
return toNat1Nat1Map(edge2speedLimit);
}
public Value getEdgeIdCapacities() {
if (edge2capacity == null)
throw new IllegalStateException();
return toNat1Nat1Map(edge2capacity);
}
//
private static String fromCharSeq(SeqValue seq) {
StringBuilder sb = new StringBuilder();
for (Value item : seq.values) {
sb.append(((CharacterValue) item).unicode);
}
return sb.toString();
}
private static SeqValue toCharSeq(String text) {
SeqValue seq = new SeqValue();
for (char chr : text.toCharArray())
seq.values.add(new CharacterValue(chr));
return seq;
}
//
private static SetValue toNat1Set(Set<Integer> values) {
SetValue set = new SetValue();
for (Integer value : values) {
set.values.add(toNat1(value.intValue()));
}
return set;
}
//
private static SeqValue toNat1Seq(List<Integer> values) {
SeqValue seq = new SeqValue();
for (Integer value : values) {
seq.values.add(toNat1(value.intValue()));
}
return seq;
}
//
private static MapValue toNat1Nat1Map(Map<Integer, Integer> mapping) {
MapValue map = new MapValue();
for (Entry<Integer, Integer> entry : mapping.entrySet()) {
map.values.put(toNat1(entry.getKey().intValue()), toNat1(entry.getValue().intValue()));
}
return map;
}
private static MapValue toNat1Nat1sMap(Map<Integer, List<Integer>> mapping) {
MapValue map = new MapValue();
for (Entry<Integer, List<Integer>> entry : mapping.entrySet()) {
map.values.put(toNat1(entry.getKey().intValue()), toNat1Seq(entry.getValue()));
}
return map;
}
//
private static NaturalOneValue toNat1(long v) {
try {
return new NaturalOneValue(v);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}
¤ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet)
¤
|
Haftungshinweis
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.
|