diff --git a/pom.xml b/pom.xml
index 88a5fbc..eb1ae21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0de.srsoftwareweb4rail
- 1.2.6
+ 1.2.7Web4RailjarJava Model Railway Control
diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation
index 1566dae..0854789 100644
--- a/resources/translations/Application.de.translation
+++ b/resources/translations/Application.de.translation
@@ -146,7 +146,7 @@ Right port\: : Port für rechts
Routes using this tile : Fahrstraßen, die diesen Abschnitt verwenden
Route will only be available, if all conditions are fulfilled. : Route ist nur verfügbar, wenn alle Bedingungen erfüllt sind.
Save : speichern
-Select block\: : Block auswählen:
+Select block : Block auswählen
Select contact\: : Kotakt auswählen:
Select display\: : Anzeige auswählen:
Select from plan : Auf Plan auswählen
diff --git a/src/main/java/de/srsoftware/web4rail/Application.java b/src/main/java/de/srsoftware/web4rail/Application.java
index 5d5f2ad..fd27b13 100644
--- a/src/main/java/de/srsoftware/web4rail/Application.java
+++ b/src/main/java/de/srsoftware/web4rail/Application.java
@@ -164,6 +164,11 @@ public class Application extends BaseClass{
return Files.probeContentType(file.toPath());
}
+ @Override
+ protected void removeChild(BaseClass child) {
+ throw new RuntimeException(this.getClass().getSimpleName()+".removeChild should never be called!");
+ }
+
/**
* sends a response generated from the application to a given client
* @param client
diff --git a/src/main/java/de/srsoftware/web4rail/BaseClass.java b/src/main/java/de/srsoftware/web4rail/BaseClass.java
index 1ae7dbd..1c83504 100644
--- a/src/main/java/de/srsoftware/web4rail/BaseClass.java
+++ b/src/main/java/de/srsoftware/web4rail/BaseClass.java
@@ -39,6 +39,7 @@ public abstract class BaseClass implements Constants{
private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
protected Id id = null;
protected String notes;
+ private static HashMap registry = new HashMap();
public static final Logger LOG = LoggerFactory.getLogger(BaseClass.class);
private BaseClass parent;
@@ -259,6 +260,17 @@ public abstract class BaseClass implements Constants{
return form;
}
+ @SuppressWarnings("unchecked")
+ public static T get(Id id) {
+ BaseClass element = registry.get(id);
+ if (isNull(element)) return null;
+ try {
+ return (T) element;
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+
public Id id() {
if (isNull(id)) id = new Id();
return id;
@@ -288,6 +300,25 @@ public abstract class BaseClass implements Constants{
return new Tag(tagClass).clazz("link").attr("onclick","request("+json+")").content(caption.toString());
}
+ @SuppressWarnings("unchecked")
+ public static List listElements(Class cls) {
+ ArrayList result = new ArrayList();
+ for (BaseClass object : registry.values()) {
+ if (isSet(object) && cls.isAssignableFrom(object.getClass())) {
+ result.add((T) object);
+ }
+ }
+ return result;
+ }
+
+ public BaseClass load(JSONObject json) {
+ if (json.has(ID)) {
+ id = Id.from(json);
+ register();
+ }
+ if (json.has(NOTES)) notes = json.getString(NOTES);
+ return this;
+ }
public static String md5sum(Object o) {
try {
@@ -349,7 +380,19 @@ public abstract class BaseClass implements Constants{
if (isSet(additionalProps)) props.putAll(additionalProps);
return props;
}
+
+ public BaseClass register() {
+ registry.put(id(),this);
+ return this;
+ }
+
+ public BaseClass remove() {
+ if (isSet(parent)) parent.removeChild(this);
+ return registry.remove(id());
+ }
+ protected abstract void removeChild(BaseClass child);
+
protected static String t(String txt, Object...fills) {
return Translation.get(Application.class, txt, fills);
}
@@ -359,10 +402,4 @@ public abstract class BaseClass implements Constants{
if (params.containsKey(NOTES)) notes = params.get(NOTES).trim();
return this;
}
-
- public BaseClass load(JSONObject json) {
- if (json.has(ID)) id = Id.from(json);
- if (json.has(NOTES)) notes = json.getString(NOTES);
- return this;
- }
}
diff --git a/src/main/java/de/srsoftware/web4rail/Constants.java b/src/main/java/de/srsoftware/web4rail/Constants.java
index 33f997a..ef474f7 100644
--- a/src/main/java/de/srsoftware/web4rail/Constants.java
+++ b/src/main/java/de/srsoftware/web4rail/Constants.java
@@ -48,18 +48,19 @@ public interface Constants {
public static final String REALM_TRAIN = "train";
- public static final String BLOCK = "block";
- public static final String CONTACT = "contact";
- public static final String CONTEXT = "context";
- public static final String DEFAULT_SPEED_UNIT = "km/h";
+ public static final String BLOCK = "block";
+ public static final String CONTACT = "contact";
+ public static final String CONTEXT = "context";
+ public static final String DEFAULT_SPEED_UNIT = "km/h";
public static final String DEFAULT_LENGTH_UNIT = "mm";
- public static final String DISABLED = "disabled";
- public static final String GITHUB_URL = "https://github.com/srsoftware-de/Web4Rail";
- public static final String ID = "id";
- public static final String NBSP = " ";
- public static final String NOTES = "notes";
- public static final String PORT = "port";
- public static final String RELAY = "relay";
- public static final String TYPE = "type";
- public static final Charset UTF8 = StandardCharsets.UTF_8;
+ public static final String DISABLED = "disabled";
+ public static final String GITHUB_URL = "https://github.com/srsoftware-de/Web4Rail";
+ public static final String ID = "id";
+ public static final String NBSP = " ";
+ public static final String NOTES = "notes";
+ public static final String PARENT = "parent";
+ public static final String PORT = "port";
+ public static final String RELAY = "relay";
+ public static final String TYPE = "type";
+ public static final Charset UTF8 = StandardCharsets.UTF_8;
}
diff --git a/src/main/java/de/srsoftware/web4rail/PathFinder.java b/src/main/java/de/srsoftware/web4rail/PathFinder.java
index cdffd96..00bb2c7 100644
--- a/src/main/java/de/srsoftware/web4rail/PathFinder.java
+++ b/src/main/java/de/srsoftware/web4rail/PathFinder.java
@@ -109,4 +109,9 @@ public class PathFinder extends BaseClass{
return selectetRoute;
}
+
+ @Override
+ protected void removeChild(BaseClass child) {
+ // this class has no child elements
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/Plan.java b/src/main/java/de/srsoftware/web4rail/Plan.java
index 8ec1f3f..4059c7d 100644
--- a/src/main/java/de/srsoftware/web4rail/Plan.java
+++ b/src/main/java/de/srsoftware/web4rail/Plan.java
@@ -12,13 +12,10 @@ import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.SortedSet;
import java.util.Stack;
-import java.util.TreeSet;
import java.util.Vector;
import org.json.JSONArray;
@@ -27,7 +24,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.srsoftware.tools.Tag;
-import de.srsoftware.web4rail.actions.Action;
import de.srsoftware.web4rail.moving.Car;
import de.srsoftware.web4rail.moving.Train;
import de.srsoftware.web4rail.tags.Button;
@@ -61,7 +57,6 @@ import de.srsoftware.web4rail.tiles.EndW;
import de.srsoftware.web4rail.tiles.Eraser;
import de.srsoftware.web4rail.tiles.Relay;
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;
@@ -140,10 +135,6 @@ public class Plan extends BaseClass{
private static final String SPEED_UNIT = "speed_unit";
private static final String LENGTH_UNIT = "length_unit";
- public HashMap tiles = new HashMap(); // The list of tiles of this plan, i.e. the Track layout
- private HashSet blocks = new HashSet(); // the list of tiles, that are blocks
- private HashSet signals = new HashSet(); // the list of tiles, that are signals
- private HashMap routes = new HashMap(); // the list of routes of the track layout
private ControlUnit controlUnit = new ControlUnit(this); // the control unit, to which the plan is connected
private Contact learningContact;
@@ -241,8 +232,11 @@ public class Plan extends BaseClass{
Tile tile = (Tile) tc.getClassLoader().loadClass(clazz).getDeclaredConstructor().newInstance();
if (tile instanceof Eraser) {
Tile erased = get(Tile.id(x,y),true);
- remove(erased);
- return erased == null ? null : t("Removed {}.",erased);
+ if (isSet(erased)) {
+ erased.remove();
+ return t("Removed {}.",erased);
+ }
+ return null;
}
//if (configJson != null) tile.configure(new JSONObject(configJson));
set(x, y, tile);
@@ -255,7 +249,7 @@ public class Plan extends BaseClass{
*/
private String analyze() {
Vector routes = new Vector();
- for (Block block : blocks) {
+ for (Block block : BaseClass.listElements(Block.class)) {
if (block.name.equals("Huhu")) {
System.err.println("Here we go!");
}
@@ -263,18 +257,11 @@ public class Plan extends BaseClass{
routes.addAll(follow(new Route().begin(block,con.from.inverse()),con));
}
}
- for (Tile tile : tiles.values()) tile.routes().clear();
+ for (Tile tile : BaseClass.listElements(Tile.class)) tile.routes().clear();
for (Route route : routes) registerRoute(route.complete());
return t("Found {} routes.",routes.size());
}
- /**
- * @return the list of blocks known to the plan, ordered by name
- */
- public Collection blocks() {
- return new TreeSet(blocks);
- }
-
/**
* calls tile.click()
* @param tile
@@ -342,7 +329,7 @@ public class Plan extends BaseClass{
*/
public Tile get(Id tileId,boolean resolveShadows) {
if (isNull(tileId)) return null;
- Tile tile = tiles.get(tileId);
+ Tile tile = BaseClass.get(tileId);
if (resolveShadows && tile instanceof Shadow) tile = ((Shadow)tile).overlay();
return tile;
}
@@ -391,7 +378,7 @@ public class Plan extends BaseClass{
*/
public Page html() throws IOException {
Page page = new Page().append("
");
- for (Tile tile: tiles.values()) {
+ for (Tile tile: BaseClass.listElements(Tile.class)) {
if (tile == null) continue;
page.append("\t\t"+tile.tag(null)+"\n");
}
@@ -570,7 +557,7 @@ public class Plan extends BaseClass{
tile = stack.pop();
if (!(tile instanceof Shadow)) {
LOG.debug("altering position of {}",tile);
- remove(tile);
+ tile.remove();
set(tile.x+xstep,tile.y+ystep,tile);
}
}
@@ -628,7 +615,7 @@ public class Plan extends BaseClass{
new Tag("h4").content(t("turnout properties")).addTo(win);
Table table = new Table();
table.addHead(t("Address"),t("Relay/Turnout"));
- tiles.values()
+ BaseClass.listElements(Tile.class)
.stream()
.filter(tile -> tile instanceof Device )
.map(tile -> (Device) tile)
@@ -658,38 +645,19 @@ public class Plan extends BaseClass{
*/
Route registerRoute(Route newRoute) {
newRoute.path().stream().filter(Tile::isSet).forEach(tile -> tile.add(newRoute));
- Id newRouteId = newRoute.id();
- Route existingRoute = routes.get(newRouteId);
+ Route existingRoute = BaseClass.get(newRoute.id());
if (isSet(existingRoute)) newRoute.addPropertiesFrom(existingRoute);
- routes.put(newRouteId, newRoute);
+ newRoute.register();
return newRoute;
}
- /**
- * removes a tile from the track layout
- * @param tile
- */
- private void remove(Tile tile) {
- if (isNull(tile)) return;
- removeTile(tile.x,tile.y);
- if (tile instanceof Block) blocks.remove(tile);
- for (int i=1; i isSet(tile))
+ BaseClass.listElements(Tile.class)
+ .stream()
.filter(tile -> !(tile instanceof Shadow))
.map(tile -> tile.json())
.forEach(jTiles::put);
@@ -754,8 +715,6 @@ public class Plan extends BaseClass{
*/
public void set(int x,int y,Tile tile) throws IOException {
if (tile == null) return;
- if (tile instanceof Block) blocks.add((Block) tile);
- if (tile instanceof Signal) signals .add((Signal) tile);
for (int i=1; i params) {
- String[] parts = params.get(CONTEXT).split(":");
- String realm = parts[0];
- Id id = parts.length>1 ? new Id(parts[1]) : null;
- switch (realm) {
- case REALM_ROUTE:
- return route(id).properties();
- case REALM_CONTACT:
- case REALM_PLAN:
- Tile tile = get(id, false);
- return isNull(tile) ? null : tile.properties();
- case REALM_ACTIONS:
- Action action = Action.get(id);
- return (isSet(action)) ? action.properties() : null;
-
- }
- return null;
- }
-
- public SortedSet signals() {
- return new TreeSet(signals);
- }
/**
* sends some data to the clients
diff --git a/src/main/java/de/srsoftware/web4rail/Range.java b/src/main/java/de/srsoftware/web4rail/Range.java
index 2b37776..bc1631c 100644
--- a/src/main/java/de/srsoftware/web4rail/Range.java
+++ b/src/main/java/de/srsoftware/web4rail/Range.java
@@ -28,6 +28,11 @@ public class Range extends BaseClass{
if (max - min == 0) return max - min;
return min + random.nextInt(max - min);
}
+
+ @Override
+ protected void removeChild(BaseClass child) {
+ // this class has no child elements
+ }
@Override
public String toString() {
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index d98bf21..2c6e991 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -4,7 +4,6 @@ import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -57,7 +56,6 @@ public class Route extends BaseClass implements Comparable{
private static final String ACTION_LISTS = "action_lists";
private static final String BRAKE_TIMES = "brake_times";
private static final String CONDITIONS = "conditions";
- private static final String DROP_CONDITION = "drop_condition";
private static final String END_DIRECTION = "direction_end";
private static final String ROUTES = "routes";
private static final String SETUP_ACTIONS = "setup_actions";
@@ -141,7 +139,6 @@ public class Route extends BaseClass implements Comparable{
private boolean disabled = false;
private Block endBlock = null;
public Direction endDirection;
- private Id id;
private Vector path;
private Vector signals;
public Train train;
@@ -151,7 +148,7 @@ public class Route extends BaseClass implements Comparable{
private ActionList startActions;
private Block startBlock = null;
public Direction startDirection;
- private HashSet triggeredContacts = new HashSet<>();
+ private HashSet triggeredContacts = new HashSet<>();
public Route() {
setupActions = new ActionList(this);
@@ -165,23 +162,17 @@ public class Route extends BaseClass implements Comparable{
* @throws IOException
*/
public static Object action(HashMap params) throws IOException {
- Route route = plan.route(Id.from(params));
+ Route route = BaseClass.get(Id.from(params));
if (isNull(route)) return t("Unknown route: {}",params.get(ID));
switch (params.get(ACTION)) {
case ACTION_DROP:
- String message = plan.remove(route);
- String context = params.get(CONTEXT);
- if (isSet(context)) {
- plan.stream(message);
- return plan.showContext(params);
- }
- return message;
+ route.remove();
+ return t("Removed {}.",route);
+
case ACTION_PROPS:
return route.properties();
case ACTION_UPDATE:
return route.update(params,plan);
- case DROP_CONDITION:
- return route.dropCodition(params);
}
return t("Unknown action: {}",params.get(ACTION));
}
@@ -419,12 +410,6 @@ public class Route extends BaseClass implements Comparable{
return disabled;
}
- private Object dropCodition(HashMap params) {
- Id condId = Id.from(params,REALM_CONDITION);
- if (isSet(condId)) conditions.removeById(condId);
- return properties();
- }
-
public Block endBlock() {
return endBlock;
}
@@ -435,7 +420,7 @@ public class Route extends BaseClass implements Comparable{
Tile lastTile = path.lastElement();
if (lastTile instanceof Contact) {
lastTile.set(null);
- if (isSet(train)) train.removeFromTrace(lastTile);
+ if (isSet(train)) train.removeChild(lastTile);
}
if (isSet(train)) {
train.set(endBlock);
@@ -508,7 +493,7 @@ public class Route extends BaseClass implements Comparable{
json.put(BRAKE_TIMES, brakeTimes);
- if (!conditions.isEmpty()) json.put(CONDITIONS, conditions.json());
+ if (!conditions.isEmpty()) json.put(CONDITIONS, conditions.jsonArray());
JSONArray jTriggers = new JSONArray();
for (Entry entry : triggers.entrySet()) {
@@ -652,20 +637,32 @@ public class Route extends BaseClass implements Comparable{
@Override
protected Window properties(List