diff --git a/pom.xml b/pom.xml
index fbad1e3..4f55e45 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.7.8
+ 0.7.9
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 2a9e5e9..deafca0 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.actions.ActionList;
import de.srsoftware.web4rail.conditions.Condition;
import de.srsoftware.web4rail.moving.Car;
import de.srsoftware.web4rail.moving.Locomotive;
@@ -62,6 +63,8 @@ public class Application implements Constants{
if (action == null) throw new NullPointerException(ACTION+" should not be null!");
switch (realm) {
+ case REALM_ACTIONS:
+ return ActionList.process(params);
case REALM_CAR:
return Car.action(params);
case REALM_CONDITION:
diff --git a/src/main/java/de/srsoftware/web4rail/Constants.java b/src/main/java/de/srsoftware/web4rail/Constants.java
index 6128559..89745e2 100644
--- a/src/main/java/de/srsoftware/web4rail/Constants.java
+++ b/src/main/java/de/srsoftware/web4rail/Constants.java
@@ -30,6 +30,7 @@ public interface Constants {
public static final String ACTION_UPDATE = "update";
public static final String REALM = "realm";
+ public static final String REALM_ACTIONS = "actions";
public static final String REALM_CAR = "car";
public static final String REALM_CONDITION = "condition";
public static final String REALM_CU = "cu";
diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java
index 1552a99..3e2aec5 100644
--- a/src/main/java/de/srsoftware/web4rail/Plan.java
+++ b/src/main/java/de/srsoftware/web4rail/Plan.java
@@ -169,7 +169,7 @@ public class Plan implements Constants{
this.routes.clear();
for (Tile tile : tiles.values()) tile.routes().clear();
for (Route route : routes) {
- route.complete(this);
+ route.complete();
registerRoute(route);
}
return t("Found {} routes.",routes.size());
@@ -416,12 +416,6 @@ public class Plan implements Constants{
Route route = route(Integer.parseInt(params.get(ID)));
if (route == null) return t("Unknown route: {}",params.get(ID));
switch (params.get(ACTION)) {
- case ACTION_ADD_ACTION:
- return route.addActionForm(params);
- case ACTION_DROP:
- return route.dropAction(params);
- case ACTION_MOVE:
- return route.moveAction(params);
case ACTION_PROPS:
return route.properties();
case ACTION_UPDATE:
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index ae21945..2c60baa 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -25,18 +25,14 @@ import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.actions.Action.Context;
+import de.srsoftware.web4rail.actions.ActionList;
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;
-import de.srsoftware.web4rail.actions.TurnTrain;
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;
-import de.srsoftware.web4rail.tags.Select;
import de.srsoftware.web4rail.tiles.Block;
import de.srsoftware.web4rail.tiles.Contact;
import de.srsoftware.web4rail.tiles.Shadow;
@@ -55,7 +51,7 @@ public class Route implements Constants{
private Vector signals;
private Vector contacts;
private HashMap turnouts;
- private HashMap> triggers = new HashMap>();
+ private HashMap triggers = new HashMap();
private int id;
private static HashMap names = new HashMap(); // maps id to name. needed to keep names during plan.analyze()
public Train train;
@@ -65,31 +61,9 @@ public class Route implements Constants{
public Direction startDirection;
private Direction endDirection;
- private Plan plan;
private static final String TRIGGER = "trigger";
private static final String ACTIONS = "actions";
- private static final String ACTION_ID = "action_id";
- private static final String TILE = Tile.class.getSimpleName();
-
- private Tag actionTypeForm(Contact contact) {
- String formId ="add-action-to-contact-"+contact.id();
- Tag typeForm = new Form(formId);
- new Input(REALM, REALM_ROUTE).hideIn(typeForm);
- new Input(ID,id()).hideIn(typeForm);
- new Input(ACTION,ACTION_ADD_ACTION).hideIn(typeForm);
- new Input(CONTACT,contact.id()).hideIn(typeForm);
- Select select = new Select(TYPE);
- List> classes = List.of(
- SpeedReduction.class,
- SetSignalsToStop.class,
- FinishRoute.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);
- }
/**
* Route wurde von Zug betreten
@@ -117,45 +91,14 @@ public class Route implements Constants{
}
public void addAction(String trigger, Action action) {
- Vector actions = triggers.get(trigger);
+ ActionList actions = triggers.get(trigger);
if (actions == null) {
- actions = new Vector();
+ actions = new ActionList();
triggers.put(trigger, actions);
}
actions.add(action);
}
- public Object addActionForm(HashMap params) {
- String contactId = params.get(CONTACT);
- 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);
- 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;
- case "SpeedReduction":
- return SpeedReduction.propForm(params,this,contact);
- case "SetSignalsToStop":
- addAction(contact.trigger(),new SetSignalsToStop(id()));
- break;
- case "TurnTrain":
- addAction(contact.trigger(),new TurnTrain(id()));
- break;
- default:
- return win;
- }
- plan.stream("Action added!");
- return properties();
- }
-
private void addBasicPropertiesTo(Window win) {
new Tag("h4").content(t("Origin and destination")).addTo(win);
Tag list = new Tag("ul");
@@ -174,34 +117,15 @@ public class Route implements Constants{
private void addContactsTo(Window win) {
if (!contacts.isEmpty()) {
new Tag("h4").content(t("Contacts and actions")).addTo(win);
- Tag list = new Tag("ul");
+ Tag list = new Tag("ol");
for (Contact c : contacts) {
Tag link = Plan.addLink(c,c.toString(),list);
- Map props = new HashMap(Map.of(
- REALM,REALM_ROUTE,
- ID,id,
- ACTION,ACTION_ADD_ACTION,
- CONTACT,c.id()));
- new Button(t("add action"),props).addTo(link);
- Vector actions = triggers.get(c.trigger());
- if (actions != null && !actions.isEmpty()) {
- Tag ul = new Tag("ul");
- boolean first = true;
- for (Action action : actions) {
- props.put(ACTION_ID, action.id());
-
- Tag act = new Tag("li").content(action.toString());
- if (!first) {
- props.put(ACTION, ACTION_MOVE);
- new Button("↑",props).addTo(act);
- }
- props.put(ACTION, ACTION_DROP);
- new Button("-",props).addTo(act);
- act.addTo(ul);
- first = false;
- }
- ul.addTo(link);
+ ActionList actions = triggers.get(c.trigger());
+ if (actions == null) {
+ actions = new ActionList();
+ triggers.put(c.trigger(), actions);
}
+ actions.addTo(link);
}
list.addTo(win);
}
@@ -254,18 +178,17 @@ public class Route implements Constants{
return clone;
}
- public void complete(Plan plan) {
- this.plan = plan;
+ public void complete() {
if (contacts.size()>1) { // mindestens 2 Kontakte: erster Kontakt aktiviert Block, vorletzter Kontakt leitet Bremsung ein
- addAction(contacts.firstElement().trigger(),new ActivateRoute(id()));
+ addAction(contacts.firstElement().trigger(),new ActivateRoute());
Contact nextToLastContact = contacts.get(contacts.size()-2);
- addAction(nextToLastContact.trigger(),new SpeedReduction(id(),30));
- addAction(nextToLastContact.trigger(),new SetSignalsToStop(id()));
+ addAction(nextToLastContact.trigger(),new SpeedReduction(30));
+ addAction(nextToLastContact.trigger(),new SetSignalsToStop());
}
if (!contacts.isEmpty()) {
Contact lastContact = contacts.lastElement();
- addAction(lastContact.trigger(), new SpeedReduction(id(), 0));
- addAction(lastContact.trigger(), new FinishRoute(id()));
+ addAction(lastContact.trigger(), new SpeedReduction(0));
+ addAction(lastContact.trigger(), new FinishRoute());
}
}
@@ -276,48 +199,16 @@ public class Route implements Constants{
*/
public void contact(Contact contact) {
LOG.debug("{} on {} activated {}.",train,this,contact);
- Vector actions = triggers.get(contact.trigger());
+ ActionList actions = triggers.get(contact.trigger());
if (actions == null) return;
- LOG.debug("Triggering {}",actions);
Context context = new Context(contact);
- for (Action action : actions) {
- try {
- action.fire(context);
- } catch (IOException e) {
- LOG.warn("Action did not fire properly: {}",action,e);
- }
- }
+ actions.fire(context);
}
public Vector contacts() {
return new Vector<>(contacts);
}
- public Object dropAction(HashMap params) {
- String actionId = params.get(ACTION_ID);
- if (actionId == null) {
- plan.remove(this); // if id of an action is given: delete the action from the route. otherwise: delete the route
- String tileId = params.get(TILE);
- Tile tile = plan.get(tileId,false);
- return tile.propMenu();
- }
- String contactId = params.get(CONTACT);
- Tile tag = plan.get(contactId, false);
- if (!(tag instanceof Contact)) return t("No contact id passed to request!");
- Contact contact = (Contact) tag;
- Vector actions = triggers.get(contact.trigger());
-
- for (int i=0; i> entry : triggers.entrySet()) {
+ for (Entry entry : triggers.entrySet()) {
JSONObject trigger = new JSONObject();
trigger.put(TRIGGER, entry.getKey());
@@ -401,7 +292,6 @@ public class Route implements Constants{
}
private Route load(JSONObject json,Plan plan) {
- this.plan = plan;
if (json.has(ID)) id = json.getInt(ID);
JSONArray pathIds = json.getJSONArray(PATH);
startDirection = Direction.valueOf(json.getString(START_DIRECTION));
@@ -477,28 +367,6 @@ public class Route implements Constants{
return true;
}
- public Object moveAction(HashMap params) {
- 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!");
- Contact contact = (Contact) tag;
- Vector actions = triggers.get(contact.trigger());
-
- for (int i=1; i multiply(int size) {
Vector routes = new Vector();
for (int i=0; i implements Constants{
+
+ private static final long serialVersionUID = 4862000041987682112L;
+ private static final Logger LOG = LoggerFactory.getLogger(ActionList.class);
+ private int id;
+ private static final HashMap actionLists = new HashMap();
+
+ public ActionList() {
+ id = new Date().hashCode();
+ actionLists.put(id,this);
+ }
+
+ public void fire(Context context) {
+ LOG.debug("Firing {}",this);
+
+ for (Action action : this) {
+ try {
+ action.fire(context);
+ } catch (IOException e) {
+ LOG.warn("Action did not fire properly: {}",action,e);
+ }
+ }
+ }
+
+ public boolean drop(int actionId) {
+ for (Action action : this) {
+ if (action.id() == actionId) {
+ this.remove(action);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean moveUp(int actionId) {
+ for (int i=1; i props = new HashMap(Map.of(
+ REALM,REALM_ACTIONS,
+ ID,id,
+ ACTION,ACTION_ADD));
+ new Button(t("add action"),props).addTo(link);
+
+ props.put(ACTION,ACTION_PROPS);
+ if (!isEmpty()) {
+ Tag ul = new Tag("ol");
+ boolean first = true;
+ for (Action action : this) {
+ props.put(ID, id+"/"+action.id());
+ Tag act = new Tag("li").content(action.toString());
+ if (!first) {
+ props.put(ACTION, ACTION_MOVE);
+ new Button("↑",props).addTo(act);
+ }
+ props.put(ACTION, ACTION_DROP);
+ new Button("-",props).addTo(act);
+ act.addTo(ul);
+ first = false;
+ }
+ ul.addTo(link);
+ }
+ }
+
+ private static String t(String text,Object...fills) {
+ return Translation.get(Application.class, text, fills);
+ }
+
+ public static Object process(HashMap params) {
+ if (!params.containsKey(ID)) return t("No action list id passed to ActionList.process()!");
+ String[] parts = params.get(ID).split("/");
+ int listId = Integer.parseInt(parts[0]);
+ int actionId = parts.length>1 ? Integer.parseInt(parts[1]) : 0;
+ ActionList actionList = actionLists.get(listId);
+ if (actionList == null) return t("No action list with id {} found!",listId);
+ String action = params.get(ACTION);
+ if (action == null) return t("No action passed to ActionList.process()!");
+ switch (action) {
+ case ACTION_ADD:
+ return actionList.addActionForm(params);
+ case ACTION_DROP:
+ return actionList.drop(actionId) ? t("Action removed") : t("No action with id {} found!",actionId);
+ case ACTION_MOVE:
+ return actionList.moveUp(actionId) ? t("Action moved") : t("No action with id {} found!",actionId);
+ }
+ return t("Unknown action: {}",action);
+ }
+
+ private Object addActionForm(HashMap params) {
+ Window win = new Window("add-action-form", t("Add action to action list"));
+ String formId ="add-action-to-"+id;
+ Tag typeForm = new Form(formId);
+ new Input(REALM, REALM_ACTIONS).hideIn(typeForm);
+ new Input(ID,id).hideIn(typeForm);
+ new Input(ACTION,ACTION_ADD).hideIn(typeForm);
+ String type = params.get(TYPE);
+ if (type == null) return actionTypeForm(win);
+
+ switch (type) {
+ case "FinishRoute":
+ add(new FinishRoute());
+ break;
+ case "SetSignalsToStop":
+ add(new SetSignalsToStop());
+ break;
+ case "TurnTrain":
+ add(new TurnTrain());
+ break;
+ default:
+ actionTypeForm(win);
+ new Tag("span").content(t("Unknown action type: {}",type)).addTo(win);
+ return win;
+ }
+ return t("Action added!");
+ }
+
+ private Object actionTypeForm(Window win) {
+ String formId ="add-action-to-"+id;
+ Tag typeForm = new Form(formId);
+ new Input(REALM, REALM_ACTIONS).hideIn(typeForm);
+ new Input(ID,id).hideIn(typeForm);
+ new Input(ACTION,ACTION_ADD).hideIn(typeForm);
+ Select select = new Select(TYPE);
+ List> classes = List.of(
+ SpeedReduction.class,
+ SetSignalsToStop.class,
+ FinishRoute.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).addTo(win);
+ }
+}
diff --git a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java
index f014536..a36bc10 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/ActivateRoute.java
@@ -2,11 +2,7 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException;
-public class ActivateRoute extends RouteAction {
-
- public ActivateRoute(int routeId) {
- super(routeId);
- }
+public class ActivateRoute extends Action {
@Override
public boolean fire(Context context) throws IOException {
diff --git a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
index f976e7a..d63cd9d 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/FinishRoute.java
@@ -2,11 +2,7 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException;
-public class FinishRoute extends RouteAction {
-
- public FinishRoute(int routeId) {
- super(routeId);
- }
+public class FinishRoute extends Action {
@Override
public boolean fire(Context context) throws IOException {
diff --git a/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java b/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java
deleted file mode 100644
index 758d973..0000000
--- a/src/main/java/de/srsoftware/web4rail/actions/RouteAction.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.srsoftware.web4rail.actions;
-
-import org.json.JSONObject;
-
-public abstract class RouteAction extends Action {
-
- static final String ROUTE = "route";
- protected int routeId;
-
- public RouteAction(int routeId) {
- this.routeId = routeId;
- }
-
- @Override
- public JSONObject json() {
- JSONObject json = super.json();
- json.put(ROUTE, routeId);
- return json;
- }
-}
diff --git a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
index 01503a6..819f003 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/SetSignalsToStop.java
@@ -4,11 +4,7 @@ import java.io.IOException;
import de.srsoftware.web4rail.tiles.Signal;
-public class SetSignalsToStop extends RouteAction {
-
- public SetSignalsToStop(int routeId) {
- super(routeId);
- }
+public class SetSignalsToStop extends Action {
@Override
public boolean fire(Context context) throws IOException {
diff --git a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java
index 969b15e..85e1bed 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/SpeedReduction.java
@@ -5,7 +5,6 @@ import java.util.HashMap;
import org.json.JSONObject;
import de.srsoftware.tools.Tag;
-import de.srsoftware.web4rail.Constants;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.tags.Button;
@@ -14,13 +13,13 @@ import de.srsoftware.web4rail.tags.Input;
import de.srsoftware.web4rail.tags.Label;
import de.srsoftware.web4rail.tiles.Contact;
-public class SpeedReduction extends RouteAction implements Constants{
+public class SpeedReduction extends Action{
public static final String MAX_SPEED = "max_speed";
private int maxSpeed;
- public SpeedReduction(int routeId, int kmh) {
- super(routeId);
+ public SpeedReduction(int kmh) {
+ super();
maxSpeed = kmh;
}
@@ -50,7 +49,7 @@ public class SpeedReduction extends RouteAction implements Constants{
int s = Integer.parseInt(ms);
if (s<0) error = t("Speed must not be less than zero!");
if (error == null) {
- route.addAction(contact.trigger(),new SpeedReduction(route.id(), s));
+ route.addAction(contact.trigger(),new SpeedReduction(s));
contact.plan().stream("Action added!");
return route.properties();
}
diff --git a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
index d472bf7..5089ee8 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/TurnTrain.java
@@ -1,12 +1,6 @@
package de.srsoftware.web4rail.actions;
-import de.srsoftware.web4rail.Constants;
-
-public class TurnTrain extends RouteAction implements Constants{
-
- public TurnTrain(int routeId) {
- super(routeId);
- }
+public class TurnTrain extends Action{
@Override
public boolean fire(Context context) {
diff --git a/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java
index f83e52d..a0b349c 100644
--- a/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java
+++ b/src/main/java/de/srsoftware/web4rail/conditions/TrainSelect.java
@@ -30,7 +30,7 @@ public class TrainSelect extends Condition {
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);
+ new Button(t("Save"),"return submitForm('"+formId+"');").addTo(form).addTo(win);
return win;
}