Skip to content

Commit

Permalink
feat: add ability to add/edit/remove Operations Engines via JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
rhwood committed May 6, 2019
1 parent a362ea1 commit e6c6d6a
Show file tree
Hide file tree
Showing 5 changed files with 345 additions and 35 deletions.
Expand Up @@ -53,6 +53,7 @@
import jmri.jmrit.operations.rollingstock.cars.CarManager;
import jmri.jmrit.operations.rollingstock.cars.CarTypes;
import jmri.jmrit.operations.rollingstock.cars.Kernel;
import jmri.jmrit.operations.rollingstock.engines.Engine;
import jmri.jmrit.operations.rollingstock.engines.EngineManager;
import jmri.jmrit.operations.trains.Train;
import jmri.jmrit.operations.trains.TrainManager;
Expand Down Expand Up @@ -125,6 +126,7 @@ public JsonNode doPost(String type, String name, JsonNode data, Locale locale, i
}
return getKernel(carManager().getKernelByName(name), locale, id).put(RENAME, name);
case ENGINE:
return message(ENGINE, postEngine(name, data, locale, id), id);
case LOCATION:
case TRAINS:
// do nothing
Expand Down Expand Up @@ -160,6 +162,24 @@ public JsonNode doPut(String type, String name, JsonNode data, Locale locale, in
case CAR_TYPE:
InstanceManager.getDefault(CarTypes.class).addName(name);
return getCarType(name, locale, id);
case ENGINE:
if (data.path(ROAD).isMissingNode()) {
throw new JsonException(HttpServletResponse.SC_BAD_REQUEST,
Bundle.getMessage(locale, "ErrorMissingPropertyPut", ROAD, type), id); // NOI18N
}
if (data.path(NUMBER).isMissingNode()) {
throw new JsonException(HttpServletResponse.SC_BAD_REQUEST,
Bundle.getMessage(locale, "ErrorMissingPropertyPut", NUMBER, type), id); // NOI18N
}
road = data.path(ROAD).asText();
number = data.path(NUMBER).asText();
if (engineManager().getById(name) != null || engineManager().getByRoadAndNumber(road, number) != null) {
throw new JsonException(HttpServletResponse.SC_CONFLICT,
Bundle.getMessage(locale, "ErrorPutRollingStockConflict", type, road, number), id); // NOI18N
}
Engine engine = engineManager().newRS(road, number);
postEngine(engine, data, locale, id);
return message(ENGINE, utilities.getEngine(engine, locale), id);
case KERNEL:
Kernel kernel = carManager().newKernel(name);
return getKernel(kernel, locale, id);
Expand Down Expand Up @@ -222,6 +242,9 @@ public void doDelete(String type, String name, JsonNode data, Locale locale, int
}
InstanceManager.getDefault(CarTypes.class).deleteName(name);
break;
case ENGINE:
deleteEngine(name, data, locale, id);
break;
case KERNEL:
Kernel kernel = carManager().getKernelByName(name);
if (kernel == null) {
Expand Down Expand Up @@ -393,6 +416,43 @@ public ObjectNode postCar(@Nonnull Car car, JsonNode data, Locale locale, int id
return utilities.getCar(car, result, locale);
}


/**
* Set the properties in the data parameter for the given engine.
* <p>
* <strong>Note</strong> this returns the modified engine because changing the
* road or number of an engine changes its name in the JSON representation.
*
* @param name the operations id of the engine to change
* @param data engine data to change
* @param locale locale to throw exceptions in
* @param id message id set by client
* @return the JSON representation of the engine
* @throws JsonException if a engine by name cannot be found
*/
public ObjectNode postEngine(String name, JsonNode data, Locale locale, int id) throws JsonException {
return postEngine(getEngineByName(name, locale, id), data, locale, id);
}

/**
* Set the properties in the data parameter for the given engine.
* <p>
* <strong>Note</strong> this returns the modified engine because changing the
* road or number of an engine changes its name in the JSON representation.
*
* @param engine the engine to change
* @param data engine data to change
* @param locale locale to throw exceptions in
* @param id message id set by client
* @return the JSON representation of the engine
* @throws JsonException if unable to set location
*/
public ObjectNode postEngine(@Nonnull Engine engine, JsonNode data, Locale locale, int id) throws JsonException {
ObjectNode result = postRollingStock(engine, data, locale, id);
engine.setModel(data.path(MODEL).asText(engine.getModel()));
return utilities.getEngine(engine, result, locale);
}

/**
* Set the properties in the data parameter for the given rolling stock.
* <p>
Expand Down Expand Up @@ -452,6 +512,11 @@ public void deleteCar(@Nonnull String name, @Nonnull JsonNode data, @Nonnull Loc
carManager().deregister(getCarByName(name, locale, id));
}

public void deleteEngine(@Nonnull String name, @Nonnull JsonNode data, @Nonnull Locale locale, int id)
throws JsonException {
engineManager().deregister(getEngineByName(name, locale, id));
}

protected Car getCarByName(@Nonnull String name, @Nonnull Locale locale, int id) throws JsonException {
Car car = carManager().getById(name);
if (car == null) {
Expand All @@ -461,6 +526,15 @@ protected Car getCarByName(@Nonnull String name, @Nonnull Locale locale, int id)
return car;
}

protected Engine getEngineByName(@Nonnull String name, @Nonnull Locale locale, int id) throws JsonException {
Engine engine = engineManager().getById(name);
if (engine == null) {
throw new JsonException(HttpServletResponse.SC_NOT_FOUND,
Bundle.getMessage(locale, "ErrorNotFound", ENGINE, name), id);
}
return engine;
}

protected CarManager carManager() {
return InstanceManager.getDefault(CarManager.class);
}
Expand Down
15 changes: 13 additions & 2 deletions java/src/jmri/server/json/operations/JsonUtil.java
Expand Up @@ -95,9 +95,20 @@ public ObjectNode getCar(String name, Locale locale, int id) throws JsonExceptio
* @return the JSON representation of engine
*/
public ObjectNode getEngine(Engine engine, Locale locale) {
ObjectNode data = this.getRollingStock(engine, locale);
return getEngine(engine, getRollingStock(engine, locale), locale);
}

/**
* Get the JSON representation of an Engine.
*
* @param engine the Engine
* @param data the JSON data from {@link #getRollingStock(RollingStock, Locale)}
* @param locale the client's locale
* @return the JSON representation of engine
*/
public ObjectNode getEngine(Engine engine, ObjectNode data, Locale locale) {
data.put(JSON.MODEL, engine.getModel());
data.put(JsonConsist.CONSIST, engine.getConsistName());
data.put(JsonConsist.CONSIST, engine.getConsist() != null ? engine.getConsistName() : null);
return data;
}

Expand Down
80 changes: 78 additions & 2 deletions java/src/jmri/server/json/operations/engine-client.json
Expand Up @@ -6,9 +6,85 @@
"properties": {
"name": {
"type": "string",
"description": "Operations id of the engine being requested"
"description": "Operations id for engine"
},
"road": {
"type": "string",
"description": "The engine owning railroad"
},
"number": {
"type": "string",
"description": "The engine number"
},
"color": {
"type": "string",
"description": "The color of the engine"
},
"comment": {
"type": "string",
"description": "Freeform comment concerning engine"
},
"consist": {
"type": [
"string",
"null"
],
"description": "The name of the consist the engine is in"
},
"destination": {
"type": [
"object",
"null"
],
"description": "the current destination of the engine"
},
"length": {
"type": "integer",
"description": "Current engine length for available siding calculations"
},
"location": {
"type": [
"object",
"null"
],
"description": "The current location of the engine"
},
"model": {
"type": "string",
"description": "The model of engine"
},
"outOfService": {
"type": "boolean",
"description": "True if out of service; false otherwise"
},
"owner": {
"type": "string",
"description": "The engine owner"
},
"rfid": {
"type": [
"string",
"null"
],
"description": "RFID tag attached to car; null if none"
},
"type": {
"type": "string",
"description": "The engine type"
}
},
"additionalProperties": false,
"required": ["name"]
"anyOf": [
{
"required": [
"name"
]
},
{
"required": [
"road",
"number"
]
}
]
}
73 changes: 42 additions & 31 deletions java/src/jmri/server/json/operations/engine-server.json
Expand Up @@ -8,79 +8,90 @@
"type": "string",
"description": "Operations id for engine"
},
"number": {
"rename": {
"type": "string",
"description": "The engine number"
"description": "Old name of engine if road or number has changed"
},
"road": {
"type": "string",
"description": "The engine owning railroad"
},
"rfid": {
"type": [
"string",
"null"
],
"description": "RFID tag attached to car; null if none"
},
"type": {
"number": {
"type": "string",
"description": "The engine type"
},
"length": {
"type": "integer",
"description": "Current engine length for available siding calculations"
"description": "The engine number"
},
"color": {
"type": "string",
"description": "The color of the engine"
},
"owner": {
"type": "string",
"description": "The engine owner"
},
"comment": {
"type": "string",
"description": "Freeform comment concerning engine"
},
"location": {
"consist": {
"type": [
"string",
"null"
],
"description": "The current location of the engine"
"description": "The name of the consist the engine is in"
},
"destination": {
"type": [
"string",
"object",
"null"
],
"description": "the current destination of the engine"
},
"length": {
"type": "integer",
"description": "Current engine length for available siding calculations"
},
"location": {
"type": [
"object",
"null"
],
"description": "The current location of the engine"
},
"model": {
"type": "string",
"description": "The model of engine"
},
"consist": {
"type": "string",
"description": "The name of the consist the engine is in"
},
"outOfService": {
"type": "boolean",
"description": "True if out of service; false otherwise"
},
"owner": {
"type": "string",
"description": "The engine owner"
},
"rfid": {
"type": [
"string",
"null"
],
"description": "RFID tag attached to car; null if none"
},
"type": {
"type": "string",
"description": "The engine type"
}
},
"additionalProperties": false,
"required": [
"name",
"number",
"road",
"type",
"length",
"owner",
"color",
"comment",
"model",
"consist",
"outOfService"
"destination",
"length",
"location",
"model",
"outOfService",
"owner",
"rfid",
"type"
]
}

0 comments on commit e6c6d6a

Please sign in to comment.