restructuring remote calls
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>de.srsoftware</groupId>
|
<groupId>de.srsoftware</groupId>
|
||||||
<artifactId>web4rail</artifactId>
|
<artifactId>web4rail</artifactId>
|
||||||
<version>0.5.2</version>
|
<version>0.5.3</version>
|
||||||
<name>Web4Rail</name>
|
<name>Web4Rail</name>
|
||||||
<description>Java Model Railway Control</description>
|
<description>Java Model Railway Control</description>
|
||||||
<url>https://github.com/StephanRichter/Web4Rail</url>
|
<url>https://github.com/StephanRichter/Web4Rail</url>
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ public class Application {
|
|||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
plan = new Plan();
|
plan = new Plan();
|
||||||
}
|
}
|
||||||
|
|
||||||
Desktop.getDesktop().browse(URI.create("http://localhost:"+config.getInt(PORT)+"/plan"));
|
Desktop.getDesktop().browse(URI.create("http://localhost:"+config.getInt(PORT)+"/plan"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,20 @@ package de.srsoftware.web4rail;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import de.keawe.tools.translations.Translation;
|
||||||
|
import de.srsoftware.web4rail.tags.Button;
|
||||||
|
import de.srsoftware.web4rail.tags.Fieldset;
|
||||||
|
import de.srsoftware.web4rail.tags.Form;
|
||||||
|
import de.srsoftware.web4rail.tags.Input;
|
||||||
|
import de.srsoftware.web4rail.tags.Label;
|
||||||
|
|
||||||
public class ControlUnit extends Thread{
|
public class ControlUnit extends Thread{
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ControlUnit.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ControlUnit.class);
|
||||||
private static final String DEFAULT_HOST = "localhost";
|
private static final String DEFAULT_HOST = "localhost";
|
||||||
@@ -16,6 +24,8 @@ public class ControlUnit extends Thread{
|
|||||||
private static final int OK_PROTO = 201;
|
private static final int OK_PROTO = 201;
|
||||||
private static final int OK_MODE = 202;
|
private static final int OK_MODE = 202;
|
||||||
private static final int OK = 200;
|
private static final int OK = 200;
|
||||||
|
private static final String HOST = "host";
|
||||||
|
private static final String PORT = "port";
|
||||||
|
|
||||||
private class Reply{
|
private class Reply{
|
||||||
private long secs;
|
private long secs;
|
||||||
@@ -56,6 +66,31 @@ public class ControlUnit extends Thread{
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handshake() throws IOException {
|
||||||
|
String proto = null;
|
||||||
|
if (scanner.hasNext()) {
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
LOG.debug("recv: "+line);
|
||||||
|
for (String part : line.split(";")) {
|
||||||
|
part = part.trim();
|
||||||
|
if (part.startsWith("SRCP ")) proto = part.substring(5);
|
||||||
|
}
|
||||||
|
if (proto == null) throw new IOException("Handshake failed: "+line);
|
||||||
|
if (!proto.startsWith("0.8.")) throw new IOException("Unsupported protocol: "+proto);
|
||||||
|
writeln("SET PROTOCOL SRCP "+proto);
|
||||||
|
} else throw new IOException("Handshake expected.");
|
||||||
|
|
||||||
|
Reply reply = new Reply(scanner);
|
||||||
|
if (reply.code != OK_PROTO) throw new IOException("Handshake failed: "+reply);
|
||||||
|
|
||||||
|
writeln("SET CONNECTIONMODE SRCP COMMAND"); // preset following mode: COMMAND MODE
|
||||||
|
reply = new Reply(scanner);
|
||||||
|
if (reply.code != OK_MODE) throw new IOException("Handshake failed: "+reply);
|
||||||
|
writeln("GO"); // switch mode
|
||||||
|
reply = new Reply(scanner);
|
||||||
|
if (reply.code != OK) throw new IOException("Handshake failed: "+reply);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
ControlUnit cu = new ControlUnit().setEndpoint("Modellbahn", DEFAULT_PORT).setBus(1).restart();
|
ControlUnit cu = new ControlUnit().setEndpoint("Modellbahn", DEFAULT_PORT).setBus(1).restart();
|
||||||
@@ -66,16 +101,21 @@ public class ControlUnit extends Thread{
|
|||||||
cu.end();
|
cu.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ControlUnit setBus(int bus) {
|
public Object properties() {
|
||||||
this.bus = bus;
|
Window win = new Window("cu-props", t("Properties of the control unit"));
|
||||||
return this;
|
Form form = new Form();
|
||||||
|
new Input(Plan.ACTION,Plan.ACTION_UPDATE).hideIn(form);
|
||||||
|
new Input(Plan.REALM,Plan.REALM_CU).hideIn(form);
|
||||||
|
Fieldset fieldset = new Fieldset(t("Server connection"));
|
||||||
|
new Input(HOST,host).addTo(new Label(t("Hostname"))).addTo(fieldset);
|
||||||
|
new Input(PORT,port).attr("type", "numeric").addTo(new Label(t("Port"))).addTo(fieldset);
|
||||||
|
return new Button(t("Save")).addTo(fieldset).addTo(form).addTo(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void queue(String command) {
|
public void queue(String command) {
|
||||||
queue.add(command);
|
queue.add(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should close the server connection and establish new server connection
|
* Should close the server connection and establish new server connection
|
||||||
* @return
|
* @return
|
||||||
@@ -103,7 +143,7 @@ public class ControlUnit extends Thread{
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* send command to Server
|
* send command to Server
|
||||||
* @param command
|
* @param command
|
||||||
@@ -116,6 +156,11 @@ public class ControlUnit extends Thread{
|
|||||||
return new Reply(scanner);
|
return new Reply(scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ControlUnit setBus(int bus) {
|
||||||
|
this.bus = bus;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ControlUnit setEndpoint(String newHost, int newPort){
|
public ControlUnit setEndpoint(String newHost, int newPort){
|
||||||
host = newHost;
|
host = newHost;
|
||||||
port = newPort;
|
port = newPort;
|
||||||
@@ -134,32 +179,9 @@ public class ControlUnit extends Thread{
|
|||||||
}
|
}
|
||||||
super.start();
|
super.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String t(String text,Object...fills) {
|
||||||
private void handshake() throws IOException {
|
return Translation.get(Application.class, text, fills);
|
||||||
String proto = null;
|
|
||||||
if (scanner.hasNext()) {
|
|
||||||
String line = scanner.nextLine();
|
|
||||||
LOG.debug("recv: "+line);
|
|
||||||
for (String part : line.split(";")) {
|
|
||||||
part = part.trim();
|
|
||||||
if (part.startsWith("SRCP ")) proto = part.substring(5);
|
|
||||||
}
|
|
||||||
if (proto == null) throw new IOException("Handshake failed: "+line);
|
|
||||||
if (!proto.startsWith("0.8.")) throw new IOException("Unsupported protocol: "+proto);
|
|
||||||
writeln("SET PROTOCOL SRCP "+proto);
|
|
||||||
} else throw new IOException("Handshake expected.");
|
|
||||||
|
|
||||||
Reply reply = new Reply(scanner);
|
|
||||||
if (reply.code != OK_PROTO) throw new IOException("Handshake failed: "+reply);
|
|
||||||
|
|
||||||
writeln("SET CONNECTIONMODE SRCP COMMAND"); // preset following mode: COMMAND MODE
|
|
||||||
reply = new Reply(scanner);
|
|
||||||
if (reply.code != OK_MODE) throw new IOException("Handshake failed: "+reply);
|
|
||||||
writeln("GO"); // switch mode
|
|
||||||
reply = new Reply(scanner);
|
|
||||||
if (reply.code != OK) throw new IOException("Handshake failed: "+reply);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeln(String data) throws IOException {
|
private void writeln(String data) throws IOException {
|
||||||
@@ -167,4 +189,9 @@ public class ControlUnit extends Thread{
|
|||||||
socket.getOutputStream().write((data+"\n").getBytes(StandardCharsets.US_ASCII));
|
socket.getOutputStream().write((data+"\n").getBytes(StandardCharsets.US_ASCII));
|
||||||
LOG.debug("sent {}.",data);
|
LOG.debug("sent {}.",data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void update(HashMap<String, String> params) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class Plan {
|
|||||||
private static final String ACTION_MOVE = "move";
|
private static final String ACTION_MOVE = "move";
|
||||||
private static final String ACTION_CLICK = "click";
|
private static final String ACTION_CLICK = "click";
|
||||||
private static final String ACTION_SAVE = "save";
|
private static final String ACTION_SAVE = "save";
|
||||||
private static final String ACTION_UPDATE = "update";
|
public static final String ACTION_UPDATE = "update";
|
||||||
private static final String TILE = "tile";
|
private static final String TILE = "tile";
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Plan.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Plan.class);
|
||||||
private static final String X = "x";
|
private static final String X = "x";
|
||||||
@@ -102,7 +102,7 @@ public class Plan {
|
|||||||
private static final String FILE = "file";
|
private static final String FILE = "file";
|
||||||
private static final String DIRECTION = "direction";
|
private static final String DIRECTION = "direction";
|
||||||
private static final String ACTION_ROUTE = "openRoute";
|
private static final String ACTION_ROUTE = "openRoute";
|
||||||
private static final String ID = "id";
|
public static final String ID = "id";
|
||||||
private static final String ROUTE = "route";
|
private static final String ROUTE = "route";
|
||||||
private static final HashMap<OutputStreamWriter,Integer> clients = new HashMap<OutputStreamWriter, Integer>();
|
private static final HashMap<OutputStreamWriter,Integer> clients = new HashMap<OutputStreamWriter, Integer>();
|
||||||
private static final String ACTION_TRAIN = "train";
|
private static final String ACTION_TRAIN = "train";
|
||||||
@@ -111,12 +111,18 @@ public class Plan {
|
|||||||
private static final String ACTION_CAR = "car";
|
private static final String ACTION_CAR = "car";
|
||||||
public static final String ACTION_ADD_LOCO = "addLoco";
|
public static final String ACTION_ADD_LOCO = "addLoco";
|
||||||
public static final String ACTION_ADD_TRAIN = "addTrain";
|
public static final String ACTION_ADD_TRAIN = "addTrain";
|
||||||
public static final String ACTION_UPDATE_CAR = "updateCar";
|
public static final String ACTION_CU_PROPS = "cuProps";
|
||||||
private static final String ACTION_CONTROL_UNIT = "controlProps";
|
public static final String ACTION_UPDATE_CU = "update-cu";
|
||||||
|
public static final String REALM = "realm";
|
||||||
|
public static final String REALM_CU = "cu";
|
||||||
|
public static final String REALM_ROUTE = "route";
|
||||||
|
public static final String REALM_TILE = "tile";
|
||||||
|
public static final String REALM_CAR = "car";
|
||||||
|
|
||||||
public HashMap<String,Tile> tiles = new HashMap<String,Tile>();
|
public HashMap<String,Tile> tiles = new HashMap<String,Tile>();
|
||||||
private HashSet<Block> blocks = new HashSet<Block>();
|
private HashSet<Block> blocks = new HashSet<Block>();
|
||||||
private HashMap<Integer, Route> routes = new HashMap<Integer, Route>();
|
private HashMap<Integer, Route> routes = new HashMap<Integer, Route>();
|
||||||
|
private ControlUnit controlUnit = new ControlUnit();
|
||||||
|
|
||||||
public Plan() {
|
public Plan() {
|
||||||
new Heartbeat().start();
|
new Heartbeat().start();
|
||||||
@@ -179,20 +185,17 @@ public class Plan {
|
|||||||
Car car = Car.get(params.get(Car.ID));
|
Car car = Car.get(params.get(Car.ID));
|
||||||
if (car == null) return t("No car with id {} found!",params.get(Car.ID));
|
if (car == null) return t("No car with id {} found!",params.get(Car.ID));
|
||||||
|
|
||||||
switch (params.get(ACTION)) {
|
return car.properties();
|
||||||
case ACTION_CAR:
|
|
||||||
return car.properties();
|
|
||||||
case ACTION_UPDATE_CAR:
|
|
||||||
car.update(params);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return html();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object click(Tile tile) throws IOException {
|
private Object click(Tile tile) throws IOException {
|
||||||
if (tile == null) return null;
|
if (tile == null) return null;
|
||||||
return tile.click();
|
return tile.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object cuProps(HashMap<String, String> params) {
|
||||||
|
return controlUnit.properties();
|
||||||
|
}
|
||||||
|
|
||||||
private Collection<Route> follow(Route route, Connector connector) {
|
private Collection<Route> follow(Route route, Connector connector) {
|
||||||
Tile tile = get(Tile.id(connector.x,connector.y),false);
|
Tile tile = get(Tile.id(connector.x,connector.y),false);
|
||||||
@@ -239,7 +242,7 @@ public class Plan {
|
|||||||
private Tag hardwareMenu() throws IOException {
|
private Tag hardwareMenu() throws IOException {
|
||||||
Tag tileMenu = new Tag("div").clazz("hardware").content(t("Hardware"));
|
Tag tileMenu = new Tag("div").clazz("hardware").content(t("Hardware"));
|
||||||
Tag list = new Tag("div").clazz("list").content("");
|
Tag list = new Tag("div").clazz("list").content("");
|
||||||
new Div(ACTION_CONTROL_UNIT).content(t("Control unit")).addTo(list);
|
new Div(ACTION_CU_PROPS).content(t("Control unit")).addTo(list);
|
||||||
return list.addTo(tileMenu);
|
return list.addTo(tileMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,10 +398,11 @@ public class Plan {
|
|||||||
case ACTION_TRAIN:
|
case ACTION_TRAIN:
|
||||||
return trainAction(params);
|
return trainAction(params);
|
||||||
case ACTION_CAR:
|
case ACTION_CAR:
|
||||||
case ACTION_UPDATE_CAR:
|
|
||||||
return carAction(params);
|
return carAction(params);
|
||||||
case ACTION_CLICK:
|
case ACTION_CLICK:
|
||||||
return click(get(params.get(Tile.ID),true));
|
return click(get(params.get(Tile.ID),true));
|
||||||
|
case ACTION_CU_PROPS:
|
||||||
|
return cuProps(params);
|
||||||
case ACTION_ANALYZE:
|
case ACTION_ANALYZE:
|
||||||
return analyze();
|
return analyze();
|
||||||
case ACTION_LOCOS:
|
case ACTION_LOCOS:
|
||||||
@@ -412,7 +416,7 @@ public class Plan {
|
|||||||
case ACTION_TRAINS:
|
case ACTION_TRAINS:
|
||||||
return Train.manager();
|
return Train.manager();
|
||||||
case ACTION_UPDATE:
|
case ACTION_UPDATE:
|
||||||
return update(params);
|
return update(params);
|
||||||
default:
|
default:
|
||||||
LOG.warn("Unknown action: {}",action);
|
LOG.warn("Unknown action: {}",action);
|
||||||
}
|
}
|
||||||
@@ -570,12 +574,29 @@ public class Plan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object update(HashMap<String, String> params) throws IOException {
|
private Object update(HashMap<String, String> params) throws IOException {
|
||||||
if (params.containsKey(ROUTE)) {
|
if (params.containsKey(REALM)) {
|
||||||
Route route = routes.get(Integer.parseInt(params.get(ROUTE)));
|
switch (params.get(REALM)) {
|
||||||
if (route == null) return t("Unknown route: {}",params.get(ROUTE));
|
case REALM_CAR:
|
||||||
route.update(params);
|
Car car = Car.get(params.get(Car.ID));
|
||||||
} else update(get(params.get(Tile.ID),true),params);
|
if (car == null) return t("No car with id {} found!",params.get(Car.ID));
|
||||||
return this.html();
|
car.update(params);
|
||||||
|
break;
|
||||||
|
case REALM_CU:
|
||||||
|
controlUnit.update(params);
|
||||||
|
break;
|
||||||
|
case REALM_ROUTE:
|
||||||
|
Route route = routes.get(Integer.parseInt(params.get(ID)));
|
||||||
|
if (route == null) return t("Unknown route: {}",params.get(ROUTE));
|
||||||
|
route.update(params);
|
||||||
|
break;
|
||||||
|
case REALM_TILE:
|
||||||
|
update(get(params.get(Tile.ID),true),params);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return t("Unknown realm \"{}\"",params.get(REALM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return html();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(Tile tile, HashMap<String, String> params) throws IOException {
|
private void update(Tile tile, HashMap<String, String> params) throws IOException {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import de.srsoftware.web4rail.actions.SetSignalsToStop;
|
|||||||
import de.srsoftware.web4rail.actions.SpeedReduction;
|
import de.srsoftware.web4rail.actions.SpeedReduction;
|
||||||
import de.srsoftware.web4rail.moving.Train;
|
import de.srsoftware.web4rail.moving.Train;
|
||||||
import de.srsoftware.web4rail.tags.Form;
|
import de.srsoftware.web4rail.tags.Form;
|
||||||
|
import de.srsoftware.web4rail.tags.Input;
|
||||||
import de.srsoftware.web4rail.tiles.Block;
|
import de.srsoftware.web4rail.tiles.Block;
|
||||||
import de.srsoftware.web4rail.tiles.Contact;
|
import de.srsoftware.web4rail.tiles.Contact;
|
||||||
import de.srsoftware.web4rail.tiles.Shadow;
|
import de.srsoftware.web4rail.tiles.Shadow;
|
||||||
@@ -366,8 +367,9 @@ public class Route {
|
|||||||
|
|
||||||
public Tag propForm() {
|
public Tag propForm() {
|
||||||
Form form = new Form();
|
Form form = new Form();
|
||||||
new Tag("input").attr("type", "hidden").attr("name","action").attr("value", "update").addTo(form);
|
new Input(Plan.ACTION, Plan.ACTION_UPDATE).hideIn(form);
|
||||||
new Tag("input").attr("type", "hidden").attr("name","route").attr("value", ""+id()).addTo(form);
|
new Input(Plan.REALM,Plan.REALM_ROUTE).hideIn(form);
|
||||||
|
new Input(Plan.ID,id()).hideIn(form);
|
||||||
|
|
||||||
Tag label = new Tag("label").content(t("name:"));
|
Tag label = new Tag("label").content(t("name:"));
|
||||||
new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).addTo(label);
|
new Tag("input").attr("type", "text").attr(NAME,"name").attr("value", name()).addTo(label);
|
||||||
|
|||||||
@@ -112,8 +112,9 @@ public class Car {
|
|||||||
|
|
||||||
public Tag propertyForm() {
|
public Tag propertyForm() {
|
||||||
Form form = new Form();
|
Form form = new Form();
|
||||||
new Input("action", Plan.ACTION_UPDATE_CAR).hideIn(form);
|
new Input(Plan.ACTION, Plan.ACTION_UPDATE).hideIn(form);
|
||||||
new Input(ID,id()).hideIn(form);
|
new Input(Plan.REALM,Plan.REALM_CAR).hideIn(form);
|
||||||
|
new Input(Plan.ID,id()).hideIn(form);
|
||||||
Fieldset fieldset = new Fieldset("Basic properties");
|
Fieldset fieldset = new Fieldset("Basic properties");
|
||||||
new Input(NAME,name).addTo(new Label(t("Name"))).addTo(fieldset);
|
new Input(NAME,name).addTo(new Label(t("Name"))).addTo(fieldset);
|
||||||
new Input(STOCK_ID,stockId).addTo(new Label(t("Stock ID"))).addTo(fieldset);
|
new Input(STOCK_ID,stockId).addTo(new Label(t("Stock ID"))).addTo(fieldset);
|
||||||
|
|||||||
@@ -179,8 +179,9 @@ public abstract class Tile {
|
|||||||
|
|
||||||
public Tag propForm() {
|
public Tag propForm() {
|
||||||
Form form = new Form();
|
Form form = new Form();
|
||||||
new Input("action", "update").hideIn(form);
|
new Input(Plan.ACTION, Plan.ACTION_UPDATE).hideIn(form);
|
||||||
new Input(ID,id()).hideIn(form);
|
new Input(Plan.REALM, Plan.REALM_TILE).hideIn(form);
|
||||||
|
new Input(Plan.ID,id()).hideIn(form);
|
||||||
|
|
||||||
List<Direction> pd = possibleDirections();
|
List<Direction> pd = possibleDirections();
|
||||||
if (!pd.isEmpty()) {
|
if (!pd.isEmpty()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user