From cbda104d8941b56ba30c9a2dc9a847ae3fd932fa Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Thu, 29 Oct 2020 19:04:48 +0100 Subject: [PATCH] moved action related code to new ActionList class --- pom.xml | 2 +- .../de/srsoftware/web4rail/Application.java | 3 + .../de/srsoftware/web4rail/Constants.java | 1 + .../java/de/srsoftware/web4rail/Plan.java | 8 +- .../java/de/srsoftware/web4rail/Route.java | 170 ++---------------- .../srsoftware/web4rail/actions/Action.java | 11 +- .../web4rail/actions/ActionList.java | 166 +++++++++++++++++ .../web4rail/actions/ActivateRoute.java | 6 +- .../web4rail/actions/FinishRoute.java | 6 +- .../web4rail/actions/RouteAction.java | 20 --- .../web4rail/actions/SetSignalsToStop.java | 6 +- .../web4rail/actions/SpeedReduction.java | 9 +- .../web4rail/actions/TurnTrain.java | 8 +- .../web4rail/conditions/TrainSelect.java | 2 +- 14 files changed, 205 insertions(+), 213 deletions(-) create mode 100644 src/main/java/de/srsoftware/web4rail/actions/ActionList.java delete mode 100644 src/main/java/de/srsoftware/web4rail/actions/RouteAction.java 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 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 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; }