diff --git a/pom.xml b/pom.xml
index b061892..93c3e9f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.1.0
+ 0.2.0
Web4Rail
Java Model Railway Control
https://github.com/StephanRichter/Web4Rail
diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java
index e86d474..bff7dce 100644
--- a/src/main/java/de/srsoftware/web4rail/Application.java
+++ b/src/main/java/de/srsoftware/web4rail/Application.java
@@ -41,7 +41,7 @@ public class Application {
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.start();
try {
- plan = Plan.load("default.plan");
+ plan = Plan.load("default");
} catch (FileNotFoundException e) {
plan = new Plan();
}
diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java
index d97c4e3..b91fa85 100644
--- a/src/main/java/de/srsoftware/web4rail/Plan.java
+++ b/src/main/java/de/srsoftware/web4rail/Plan.java
@@ -39,6 +39,7 @@ import de.srsoftware.web4rail.tiles.EndS;
import de.srsoftware.web4rail.tiles.EndW;
import de.srsoftware.web4rail.tiles.Eraser;
import de.srsoftware.web4rail.tiles.Shadow;
+import de.srsoftware.web4rail.tiles.Signal;
import de.srsoftware.web4rail.tiles.SignalE;
import de.srsoftware.web4rail.tiles.SignalN;
import de.srsoftware.web4rail.tiles.SignalS;
@@ -46,6 +47,7 @@ import de.srsoftware.web4rail.tiles.SignalW;
import de.srsoftware.web4rail.tiles.StraightH;
import de.srsoftware.web4rail.tiles.StraightV;
import de.srsoftware.web4rail.tiles.Tile;
+import de.srsoftware.web4rail.tiles.Turnout;
import de.srsoftware.web4rail.tiles.Turnout.State;
import de.srsoftware.web4rail.tiles.TurnoutLE;
import de.srsoftware.web4rail.tiles.TurnoutLN;
@@ -114,13 +116,10 @@ public class Plan {
for (HashMap column: tiles.values()) {
for (Tile tile : column.values()) tile.routes().clear();
}
- for (Route route : routes) {
- for (Tile tile: route.path()) tile.add(route);
- this.routes.put(route.id(), route);
- }
+ for (Route route : routes) registerRoute(route);
return t("Found {} routes.",routes.size());
}
-
+
private Collection follow(Route route, Connector connector) {
Tile tile = get(connector.x,connector.y);
Vector results = new Vector<>();
@@ -166,7 +165,7 @@ public class Plan {
public static Plan load(String filename) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Plan result = new Plan();
- File file = new File(filename);
+ File file = new File(filename+".plan");
BufferedReader br = new BufferedReader(new FileReader(file));
while (br.ready()) {
String line = br.readLine().trim();
@@ -181,6 +180,43 @@ public class Plan {
}
}
br.close();
+ file = new File(filename+".routes");
+ if (file.exists()) {
+ br = new BufferedReader(new FileReader(file));
+ while (br.ready()) {
+ String line = br.readLine().trim();
+ String[] parts = line.split("=",2);
+ try {
+ String id = parts[0];
+ JSONObject json = new JSONObject(parts[1]);
+ Route route = new Route();
+ json.getJSONArray(Route.PATH).forEach(entry -> {
+ JSONObject pos = (JSONObject) entry;
+ Tile tile = result.get(pos.getInt("x"),pos.getInt("y"));
+ if (route.path().isEmpty()) {
+ route.start((Block) tile);
+ } else {
+ route.add(tile, null);
+ }
+ });
+ json.getJSONArray(Route.SIGNALS).forEach(entry -> {
+ JSONObject pos = (JSONObject) entry;
+ Tile tile = result.get(pos.getInt("x"),pos.getInt("y"));
+ route.addSignal((Signal) tile);
+ });
+ json.getJSONArray(Route.TURNOUTS).forEach(entry -> {
+ JSONObject pos = (JSONObject) entry;
+ Tile tile = result.get(pos.getInt("x"),pos.getInt("y"));
+ route.addTurnout((Turnout) tile, Turnout.State.valueOf(pos.getString(Turnout.STATE)));
+ });
+ if (json.has(Route.NAME)) route.name(json.getString(Route.NAME));
+ result.registerRoute(route);
+ } catch (Exception e) {
+ LOG.warn("Was not able to load \"{}\":",line,e);
+ }
+ }
+ br.close();
+ } else LOG.debug("{} not found.",file);
return result;
}
@@ -321,6 +357,11 @@ public class Plan {
if (tile instanceof Shadow) tile = ((Shadow)tile).overlay();
return tile.propMenu();
}
+
+ private void registerRoute(Route route) {
+ for (Tile tile: route.path()) tile.add(route);
+ routes.put(route.id(), route);
+ }
private String saveTo(String name) throws IOException {
if (name == null || name.isEmpty()) throw new NullPointerException("Name must not be empty!");
@@ -340,6 +381,12 @@ public class Plan {
}
}
br.close();
+ file = new File(name+".routes");
+ br = new BufferedWriter(new FileWriter(file));
+ for (Route route: routes.values()) {
+ br.append(route.id()+"="+route.json()+"\n");
+ }
+ br.close();
return t("Plan saved as \"{}\".",file);
}
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index c6314e0..1d31dd4 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -2,9 +2,12 @@ package de.srsoftware.web4rail;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Vector;
+import org.json.JSONArray;
+import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,8 +25,11 @@ import de.srsoftware.web4rail.tiles.Turnout.State;
public class Route {
private static final Logger LOG = LoggerFactory.getLogger(Route.class);
- private static final String NAME = "name";
+ static final String NAME = "name";
private static final HashMap names = new HashMap();
+ static final String PATH = "path";
+ static final String SIGNALS = "signals";
+ static final String TURNOUTS = "turnouts";
private Vector path;
private Vector signals;
private Vector contacts;
@@ -36,12 +42,20 @@ public class Route {
if (tile instanceof Contact) contacts.add((Contact) tile);
if (tile instanceof Signal) {
Signal signal = (Signal) tile;
- if (signal.isAffectedFrom(direrction)) signals.add(signal);
+ if (signal.isAffectedFrom(direrction)) addSignal(signal);
}
return tile;
}
+ void addSignal(Signal signal) {
+ signals.add(signal);
+ }
+
+ void addTurnout(Turnout t, State s) {
+ turnouts.put(t, s);
+ }
+
protected Route clone() {
Route clone = new Route();
clone.contacts = new Vector(contacts);
@@ -68,6 +82,29 @@ public class Route {
}
return id;
}
+
+ public String json() {
+ JSONObject props = new JSONObject();
+ JSONArray path = new JSONArray();
+ for (Tile t : this.path) path.put(new JSONObject(Map.of("x",t.x,"y",t.y)));
+ props.put(PATH, path);
+
+ JSONArray signals = new JSONArray();
+ for (Tile t : this.signals) signals.put(new JSONObject(Map.of("x",t.x,"y",t.y)));
+ props.put(SIGNALS, signals);
+
+ JSONArray turnouts = new JSONArray();
+ for (Entry entry : this.turnouts.entrySet()) {
+ Turnout t = entry.getKey();
+ turnouts.put(new JSONObject(Map.of("x",t.x,"y",t.y,Turnout.STATE,entry.getValue())));
+ }
+ props.put(TURNOUTS, turnouts);
+
+ if (names.containsKey(id())) props.put(NAME, names.get(id));
+
+ return props.toString();
+ }
+
public List multiply(int size) {
Vector routes = new Vector();
@@ -80,30 +117,44 @@ public class Route {
return name == null ? id() : name;
}
+ public void name(String name) {
+ if (name.isEmpty()) {
+ names.remove(id());
+ } else names.put(id(),name);
+ }
+
public Vector path() {
- return new Vector(path);
+ Vector result = new Vector();
+ if (path != null) result.addAll(path);
+ return result;
}
public Window properties() {
Window win = new Window("route-properties",t("Properties of {}",this));
- new Tag("h4").content(t("Signals")).addTo(win);
- Tag list = new Tag("ul");
- for (Signal s : signals) Plan.addLink(s,s.toString(),list);
- list.addTo(win);
+ if (!signals.isEmpty()) {
+ new Tag("h4").content(t("Signals")).addTo(win);
+ Tag list = new Tag("ul");
+ for (Signal s : signals) Plan.addLink(s,s.toString(),list);
+ list.addTo(win);
+ }
- new Tag("h4").content(t("Contacts")).addTo(win);
- list = new Tag("ul");
- for (Contact c : contacts) Plan.addLink(c,c.toString(),list);
- list.addTo(win);
+ if (!contacts.isEmpty()) {
+ new Tag("h4").content(t("Contacts")).addTo(win);
+ Tag list = new Tag("ul");
+ for (Contact c : contacts) Plan.addLink(c,c.toString(),list);
+ list.addTo(win);
+ }
- new Tag("h4").content(t("Turnouts")).addTo(win);
- list = new Tag("ul");
- for (Entry entry : turnouts.entrySet()) {
- Turnout turnout = entry.getKey();
- Plan.addLink(turnout, turnout+": "+entry.getValue(), list);
+ if (!turnouts.isEmpty()) {
+ new Tag("h4").content(t("Turnouts")).addTo(win);
+ Tag list = new Tag("ul");
+ for (Entry entry : turnouts.entrySet()) {
+ Turnout turnout = entry.getKey();
+ Plan.addLink(turnout, turnout+": "+entry.getValue(), list);
+ }
+ list.addTo(win);
}
- list.addTo(win);
Tag form = propForm();
new Tag("button").attr("type", "submit").content(t("save")).addTo(form);
@@ -141,13 +192,7 @@ public class Route {
public void setLast(State state) {
if (state == null || state == State.UNDEF) return;
Tile lastTile = path.lastElement();
- if (lastTile instanceof Turnout) turnouts.put((Turnout) lastTile,state);
- }
-
- private void setName(String name) {
- if (name.isEmpty()) {
- names.remove(id());
- } else names.put(id(),name);
+ if (lastTile instanceof Turnout) addTurnout((Turnout) lastTile,state);
}
public Block startBlock() {
@@ -160,6 +205,6 @@ public class Route {
public void update(HashMap params) {
LOG.debug("update({})",params);
- if (params.containsKey(NAME)) setName(params.get(NAME));
+ if (params.containsKey(NAME)) name(params.get(NAME));
}
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
index 0bf6e12..8a886a0 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Turnout.java
@@ -1,6 +1,7 @@
package de.srsoftware.web4rail.tiles;
public abstract class Turnout extends Tile {
+ public static final String STATE = "state";
public enum State{
LEFT,STRAIGHT,RIGHT,UNDEF;
}