diff --git a/pom.xml b/pom.xml
index a8c0be6..5a2ae7a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.7.6
+ 0.7.7
Web4Rail
jar
Java Model Railway Control
diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java
index 070ae61..2a9e5e9 100644
--- a/src/main/java/de/srsoftware/web4rail/Application.java
+++ b/src/main/java/de/srsoftware/web4rail/Application.java
@@ -25,6 +25,7 @@ import com.sun.net.httpserver.HttpServer;
import de.keawe.localconfig.Configuration;
import de.keawe.tools.translations.Translation;
import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.conditions.Condition;
import de.srsoftware.web4rail.moving.Car;
import de.srsoftware.web4rail.moving.Locomotive;
import de.srsoftware.web4rail.moving.Train;
@@ -63,6 +64,8 @@ public class Application implements Constants{
switch (realm) {
case REALM_CAR:
return Car.action(params);
+ case REALM_CONDITION:
+ return Condition.action(params);
case REALM_CU:
return plan.controlUnit().process(params);
case REALM_LOCO:
diff --git a/src/main/java/de/srsoftware/web4rail/Constants.java b/src/main/java/de/srsoftware/web4rail/Constants.java
index 661f9f0..6128559 100644
--- a/src/main/java/de/srsoftware/web4rail/Constants.java
+++ b/src/main/java/de/srsoftware/web4rail/Constants.java
@@ -29,13 +29,14 @@ public interface Constants {
public static final String ACTION_TURN = "turn";
public static final String ACTION_UPDATE = "update";
- public static final String REALM = "realm";
- public static final String REALM_CAR = "car";
- public static final String REALM_CU = "cu";
- public static final String REALM_LOCO = "loco";
- public static final String REALM_ROUTE = "route";
- public static final String REALM_PLAN = "plan";
- public static final String REALM_TRAIN = "train";
+ public static final String REALM = "realm";
+ public static final String REALM_CAR = "car";
+ public static final String REALM_CONDITION = "condition";
+ public static final String REALM_CU = "cu";
+ public static final String REALM_LOCO = "loco";
+ public static final String REALM_ROUTE = "route";
+ public static final String REALM_PLAN = "plan";
+ public static final String REALM_TRAIN = "train";
public static final String ID = "id";
public static final String PORT = "port";
@@ -43,5 +44,4 @@ public interface Constants {
public static final String CONTACT = "contact";
public static final String TYPE = "type";
public static final String NBSP = " ";
-
}
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index 5ff3cca..ec09a3c 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -26,6 +26,7 @@ import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.actions.Action.Context;
import de.srsoftware.web4rail.actions.ActivateRoute;
+import de.srsoftware.web4rail.actions.ConditionalAction;
import de.srsoftware.web4rail.actions.FinishRoute;
import de.srsoftware.web4rail.actions.SetSignalsToStop;
import de.srsoftware.web4rail.actions.SpeedReduction;
@@ -82,7 +83,8 @@ public class Route implements Constants{
SpeedReduction.class,
SetSignalsToStop.class,
FinishRoute.class,
- TurnTrain.class);
+ TurnTrain.class,
+ ConditionalAction.class);
for (Class extends Action> clazz : classes) select.addOption(clazz.getSimpleName());
select.addTo(new Label("Action type:")).addTo(typeForm);
return new Button(t("Create action"),"return submitForm('"+formId+"');").addTo(typeForm);
@@ -127,13 +129,14 @@ public class Route implements Constants{
Tile tag = plan.get(contactId, false);
if (!(tag instanceof Contact)) return t("No contact id passed to request!");
Contact contact = (Contact) tag;
+ String type = params.get(TYPE);
Window win = new Window("add-action-form", t("Add action to contact on route"));
new Tag("div").content("Route: "+this).addTo(win);
new Tag("div").content("Contact: "+contact).addTo(win);
-
- String type = params.get(TYPE);
if (type == null) return (actionTypeForm(contact).addTo(win));
switch (type) {
+ case "ConditionalAction":
+ return ConditionalAction.propForm(params,this,contact);
case "FinishRoute":
addAction(contact.trigger(),new FinishRoute(id()));
break;
@@ -184,7 +187,7 @@ public class Route implements Constants{
Tag ul = new Tag("ul");
boolean first = true;
for (Action action : actions) {
- props.put(ACTION_ID, action.toString());
+ props.put(ACTION_ID, action.id());
Tag act = new Tag("li").content(action.toString());
if (!first) {
@@ -469,8 +472,10 @@ public class Route implements Constants{
}
public Object moveAction(HashMap params) {
- String action_id = params.get(ACTION_ID);
- if (action_id == null) return t("No action id passed to request!");
+ if (!params.containsKey(ACTION_ID)) return t("No action id passed to request!");
+
+ int action_id = Integer.parseInt(params.get(ACTION_ID));
+
String contactId = params.get(CONTACT);
Tile tag = plan.get(contactId, false);
if (!(tag instanceof Contact)) return t("No contact id passed to request!");
@@ -478,7 +483,7 @@ public class Route implements Constants{
Vector actions = triggers.get(contact.trigger());
for (int i=1; i conditions = new Vector();
+ private Vector actions = new Vector();
+
+ private ConditionalAction addCondition(Condition condition) {
+ conditions.add(new TrainSelect());
+ return this;
+ }
+
+ private static void addToContact(Route route, Contact contact, String conditionType) {
+ Condition condition = null;
+ switch (conditionType) {
+ case "TrainSelect":
+ condition = new TrainSelect();
+ break;
+ default: return;
+ }
+ route.addAction(contact.trigger(), new ConditionalAction().addCondition(condition));
+ }
+
+ @Override
+ public boolean fire(Context context) throws IOException {
+ for (Condition condition : conditions) {
+ if (condition.fulfilledBy(context)) return fireActions(context);
+ }
+ return false;
+ }
+
+ private boolean fireActions(Context context) {
+ for (Action action : actions) try {
+ action.fire(context);
+ } catch (IOException e) {
+ LOG.warn("Was not able to fire {}",action);
+ }
+ return true;
+ }
+
+ public static Window propForm(HashMap params, Route route, Contact contact) {
+ String condition = params.get(REALM_CONDITION);
+ if (condition != null) {
+ addToContact(route,contact,condition);
+ return route.properties();
+ }
+ Window win = Action.propForm(params);
+ String formId = "add-action-to-contact-"+contact.id();
+ Tag form = new Form(formId);
+ new Tag("div").content(t("Add Action {} to contact {} on route {}:",ConditionalAction.class.getSimpleName(),contact,route)).addTo(win);
+ new Input(REALM, REALM_ROUTE).hideIn(form);
+ new Input(ID,route.id()).hideIn(form);
+ new Input(ACTION,ACTION_ADD_ACTION).hideIn(form);
+ new Input(CONTACT,contact.id()).hideIn(form);
+ new Input(TYPE,ConditionalAction.class.getSimpleName()).hideIn(form);
+ Select select = new Select(REALM_CONDITION);
+ List> conditionTypes = List.of(TrainSelect.class);
+ for (Class extends Condition> clazz : conditionTypes) select.addOption(clazz.getSimpleName());
+ select.addTo(form);
+ new Button(t("Create action"),"return submitForm('"+formId+"');").addTo(form).addTo(win);
+ return win;
+ }
+
+ @Override
+ public String toString() {
+ if (conditions.isEmpty()) return t("Invalid condition");
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i maxSpeed) context.train.setSpeed(maxSpeed);
+ public boolean fire(Context context) {
+ if (context.train != null && context.train.speed > maxSpeed) {
+ context.train.setSpeed(maxSpeed);
+ return true;
+ }
+ return false;
}
@Override
diff --git a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
index 241fc1f..d472bf7 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
@@ -9,7 +9,11 @@ public class TurnTrain extends RouteAction implements Constants{
}
@Override
- public void fire(Context context) {
- if (context.train != null) context.train.turn();
+ public boolean fire(Context context) {
+ if (context.train != null) {
+ context.train.turn();
+ return true;
+ }
+ return false;
}
}
diff --git a/src/main/java/de/srsoftware/web4rail/conditions/Condition.java b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java
new file mode 100644
index 0000000..a523ad3
--- /dev/null
+++ b/src/main/java/de/srsoftware/web4rail/conditions/Condition.java
@@ -0,0 +1,69 @@
+package de.srsoftware.web4rail.conditions;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.json.JSONObject;
+
+import de.keawe.tools.translations.Translation;
+import de.srsoftware.tools.Tag;
+import de.srsoftware.web4rail.Application;
+import de.srsoftware.web4rail.Constants;
+import de.srsoftware.web4rail.Window;
+import de.srsoftware.web4rail.actions.Action.Context;
+
+public abstract class Condition implements Constants {
+
+ private static HashMap conditions = new HashMap();
+
+ public abstract boolean fulfilledBy(Context context);
+ protected int id;
+
+ public static Object action(HashMap params) {
+ if (!params.containsKey(ID)) return t("No id passed to Condition.action!");
+ int cid = Integer.parseInt(params.get(ID));
+ Condition condition = conditions.get(cid);
+ if (condition == null) return t("No condition with id {}!",cid);
+
+ String action = params.get(ACTION);
+ if (action == null) return t("No action passed to Condition.action!");
+
+ switch (action) {
+ case ACTION_PROPS:
+ return condition.properties();
+ case ACTION_UPDATE:
+ return condition.update(params);
+ }
+ return t("Unknown action: {}",action);
+ }
+
+ protected abstract Window properties();
+
+
+ public Condition() {
+ this(new Date().hashCode());
+ }
+
+ public Condition(int id) {
+ this.id = id;
+ conditions.put(id, this);
+ }
+
+ public Tag link(String tagClass) {
+ String json = new JSONObject(Map.of(REALM,REALM_CONDITION,ID,id,ACTION,ACTION_PROPS)).toString().replace("\"", "'");
+ return new Tag(tagClass).clazz("link").attr("onclick","request("+json+")").content(toString());
+ }
+
+
+ @Override
+ public String toString() {
+ return t("invalid condition");
+ }
+
+ public static String t(String text, Object...fills) {
+ return Translation.get(Application.class, text, fills);
+ }
+
+ protected abstract Object update(HashMap params);
+}
diff --git a/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java
new file mode 100644
index 0000000..f83e52d
--- /dev/null
+++ b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java
@@ -0,0 +1,52 @@
+package de.srsoftware.web4rail.conditions;
+
+import java.util.HashMap;
+
+import de.srsoftware.web4rail.Window;
+import de.srsoftware.web4rail.actions.Action.Context;
+import de.srsoftware.web4rail.moving.Train;
+import de.srsoftware.web4rail.tags.Button;
+import de.srsoftware.web4rail.tags.Form;
+import de.srsoftware.web4rail.tags.Input;
+import de.srsoftware.web4rail.tags.Label;
+
+public class TrainSelect extends Condition {
+
+ private static final Object TRAIN = Train.class.getSimpleName();
+ private Train train;
+
+ @Override
+ public boolean fulfilledBy(Context context) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ protected Window properties() {
+ Window win = new Window("condition-props", t("Properties of {}",getClass().getSimpleName()));
+ String formId = "conditional-props-"+id;
+ Form form = new Form(formId);
+ new Input(REALM,REALM_CONDITION).hideIn(form);
+ new Input(ACTION,ACTION_UPDATE).hideIn(form);
+ new Input(ID,id).hideIn(form);
+ Train.selector(train, null).addTo(new Label(t("Select train:")+NBSP)).addTo(form);
+ new Button(t("Save")).addTo(form).addTo(win);
+ return win;
+ }
+
+ @Override
+ public String toString() {
+ if (train == null) return super.toString();
+ return t("Train = {}",train);
+ }
+
+ @Override
+ protected Object update(HashMap params) {
+ if (!params.containsKey(TRAIN)) return t("No train id passed to TrainSelect.update()!");
+ int tid = Integer.parseInt(params.get(TRAIN));
+ Train train = Train.get(tid);
+ if (train == null) return t("No train with id {} found!",tid);
+ this.train = train;
+ return t("Updated condition");
+ }
+}
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java
index f0666a5..a64abad 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Train.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java
@@ -39,10 +39,10 @@ import de.srsoftware.web4rail.tiles.Signal;
public class Train implements Constants {
private static final Logger LOG = LoggerFactory.getLogger(Train.class);
- private static final HashMap trains = new HashMap<>();
+ private static final HashMap trains = new HashMap<>();
public static final String ID = "id";
- public long id;
+ public int id;
private static final String NAME = "name";
private String name = null;
@@ -98,8 +98,8 @@ public class Train implements Constants {
this(loco,null);
}
- public Train(Locomotive loco, Long id) {
- if (id == null) id = new Date().getTime();
+ public Train(Locomotive loco, Integer id) {
+ if (id == null) id = new Date().hashCode();
this.id = id;
add(loco);
trains.put(id, this);
@@ -117,7 +117,7 @@ public class Train implements Constants {
}
return t("No train id passed!");
}
- long id = Long.parseLong(params.get(Train.ID));
+ int id = Integer.parseInt(params.get(Train.ID));
Train train = trains.get(id);
if (train == null) return(t("No train with id {}!",id));
switch (action) {
@@ -189,7 +189,7 @@ public class Train implements Constants {
this.block = block;
}
- public static Train get(long id) {
+ public static Train get(int id) {
return trains.get(id);
}
@@ -237,7 +237,7 @@ public class Train implements Constants {
while (line != null) {
JSONObject json = new JSONObject(line);
- long id = json.getLong(ID);
+ int id = json.getInt(ID);
Train train = new Train(null,id);
train.load(json).plan(plan);
@@ -378,12 +378,24 @@ public class Train implements Constants {
public static void saveAll(String filename) throws IOException {
BufferedWriter file = new BufferedWriter(new FileWriter(filename));
- for (Entry entry:trains.entrySet()) {
+ for (Entry entry:trains.entrySet()) {
Train train = entry.getValue();
file.write(train.json()+"\n");
}
file.close();
}
+
+ public static Select selector(Train preselected,Collection exclude) {
+ if (exclude == null) exclude = new Vector();
+ Select select = new Select(Train.class.getSimpleName());
+ new Tag("option").attr("value","0").content(t("unset")).addTo(select);
+ for (Train train : Train.list()) {
+ if (exclude.contains(train)) continue;
+ Tag opt = select.addOption(train.id, train);
+ if (train == preselected) opt.attr("selected", "selected");
+ }
+ return select;
+ }
public void setSpeed(int v) {
LOG.debug("Setting speed to {} kmh.",v);
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java
index fca4d5c..a0ef631 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java
@@ -14,6 +14,7 @@ import de.srsoftware.web4rail.tags.Button;
import de.srsoftware.web4rail.tags.Checkbox;
import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
+import de.srsoftware.web4rail.tags.Select;
public abstract class Block extends StretchableTile{
private static final String NAME = "name";
@@ -22,7 +23,7 @@ public abstract class Block extends StretchableTile{
private static final String ALLOW_TURN = "allowTurn";
public boolean turnAllowed = false;
- private static final String TRAIN = "train";
+ private static final String TRAIN = Train.class.getSimpleName();
@Override
public JSONObject config() {
@@ -51,7 +52,7 @@ public abstract class Block extends StretchableTile{
name = json.has(NAME) ? json.getString(NAME) : "Block";
turnAllowed = json.has(ALLOW_TURN) && json.getBoolean(ALLOW_TURN);
if (json.has(TRAIN)) {
- Train tr = Train.get(json.getLong(TRAIN));
+ Train tr = Train.get(json.getInt(TRAIN));
train(tr);
}
return this;
@@ -65,13 +66,7 @@ public abstract class Block extends StretchableTile{
new Checkbox(ALLOW_TURN,t("Turn allowed"),turnAllowed).addTo(new Tag("p")).addTo(form);
- Tag select = new Tag("select").attr("name", TRAIN);
- new Tag("option").attr("value","0").content(t("unset")).addTo(select);
- for (Train train : Train.list()) {
- Tag opt = new Tag("option").attr("value", ""+train.id);
- if (this.train == train) opt.attr("selected", "selected");
- opt.content(train.toString()).addTo(select);
- }
+ Select select = Train.selector(train, null);
select.addTo(new Label(t("Trains:")+" ")).addTo(new Tag("p")).addTo(form);
return form;
@@ -118,7 +113,7 @@ public abstract class Block extends StretchableTile{
super.update(params);
if (params.containsKey(NAME)) name=params.get(NAME);
if (params.containsKey(TRAIN)) {
- long trainId = Long.parseLong(params.get(TRAIN));
+ int trainId = Integer.parseInt(params.get(TRAIN));
Train t = Train.get(trainId);
if (t != null) {
Block oldBlock = t.block();