001package jmri.server.json.block; 002 003import static jmri.server.json.JSON.VALUE; 004import static jmri.server.json.block.JsonBlock.BLOCK; 005import static jmri.server.json.block.JsonBlock.BLOCKS; 006import static jmri.server.json.idtag.JsonIdTag.IDTAG; 007import static jmri.server.json.reporter.JsonReporter.REPORTER; 008 009import com.fasterxml.jackson.databind.JsonNode; 010import com.fasterxml.jackson.databind.ObjectMapper; 011import com.fasterxml.jackson.databind.node.ArrayNode; 012import com.fasterxml.jackson.databind.node.ObjectNode; 013import javax.servlet.http.HttpServletResponse; 014 015import jmri.BasicRosterEntry; 016import jmri.Block; 017import jmri.BlockManager; 018import jmri.InstanceManager; 019import jmri.JmriException; 020import jmri.NamedBean; 021import jmri.ProvidingManager; 022import jmri.Reporter; 023import jmri.ReporterManager; 024import jmri.Sensor; 025import jmri.SensorManager; 026import jmri.server.json.JSON; 027import jmri.server.json.JsonException; 028import jmri.server.json.JsonNamedBeanHttpService; 029import jmri.server.json.JsonRequest; 030import jmri.server.json.idtag.JsonIdTagHttpService; 031import jmri.server.json.reporter.JsonReporter; 032import jmri.server.json.reporter.JsonReporterHttpService; 033import jmri.server.json.roster.JsonRosterHttpService; 034import jmri.server.json.sensor.JsonSensor; 035 036/** 037 * @author mstevetodd Copyright 2018 038 * @author Randall Wood Copyright 2018, 2019 039 */ 040public class JsonBlockHttpService extends JsonNamedBeanHttpService<Block> { 041 042 private final JsonIdTagHttpService idTagService = new JsonIdTagHttpService(mapper); 043 private final JsonReporterHttpService reporterService = new JsonReporterHttpService(mapper); 044 private final JsonRosterHttpService rosterService = new JsonRosterHttpService(mapper); 045 046 public JsonBlockHttpService(ObjectMapper mapper) { 047 super(mapper); 048 } 049 050 @Override 051 public ObjectNode doGet(Block block, String name, String type, JsonRequest request) throws JsonException { 052 ObjectNode root = this.getNamedBean(block, name, getType(), request); 053 ObjectNode data = root.with(JSON.DATA); 054 switch (block.getState()) { 055 case Block.UNDETECTED: 056 case NamedBean.UNKNOWN: 057 data.put(JSON.STATE, JSON.UNKNOWN); 058 break; 059 default: 060 data.put(JSON.STATE, block.getState()); 061 } 062 // set block value based on type stored there 063 Object bv = block.getValue(); 064 if (bv == null) { 065 data.putNull(VALUE); 066 } else if (bv instanceof jmri.IdTag) { 067 ObjectNode idTagValue = idTagService.doGet((jmri.IdTag) bv, name, IDTAG, request); 068 data.set(VALUE, idTagValue); 069 } else if (bv instanceof jmri.Reporter) { 070 ObjectNode reporterValue = reporterService.doGet((jmri.Reporter) bv, name, REPORTER, request); 071 data.set(VALUE, reporterValue); 072 } else if (bv instanceof jmri.BasicRosterEntry) { 073 ObjectNode rosterValue = (ObjectNode) rosterService.getRosterEntry( 074 request.locale, ((BasicRosterEntry) bv).getId(), request.id); 075 data.set(VALUE, rosterValue); 076 } else { 077 // send string for types not explicitly handled 078 data.put(VALUE, bv.toString()); 079 } 080 var sens = block.getSensor(); 081 data.put(JsonSensor.SENSOR, sens != null ? sens.getSystemName() : null); 082 var rep = block.getReporter(); 083 data.put(JsonReporter.REPORTER, rep != null ? rep.getSystemName() : null); 084 data.put(JSON.SPEED, block.getBlockSpeed()); 085 data.put(JsonBlock.CURVATURE, block.getCurvature()); 086 data.put(JSON.DIRECTION, block.getDirection()); 087 data.put(JSON.LENGTH, block.getLengthMm()); 088 data.put(JsonBlock.PERMISSIVE, block.getPermissiveWorking()); 089 data.put(JsonBlock.SPEED_LIMIT, block.getSpeedLimit()); 090 ArrayNode array = data.putArray(JsonBlock.DENIED); 091 block.getDeniedBlocks().forEach(array::add); 092 return root; 093 } 094 095 @Override 096 public ObjectNode doPost(Block block, String name, String type, JsonNode data, JsonRequest request) 097 throws JsonException { 098 if (!data.path(JSON.VALUE).isMissingNode()) { 099 if (data.path(JSON.VALUE).isNull()) { 100 block.setValue(null); 101 } else { 102 block.setValue(data.path(JSON.VALUE).asText()); 103 } 104 } 105 int state = data.path(JSON.STATE).asInt(JSON.UNKNOWN); 106 switch (state) { 107 case JSON.ACTIVE: 108 block.setState(Block.OCCUPIED); 109 break; 110 case JSON.INACTIVE: 111 block.setState(Block.UNOCCUPIED); 112 break; 113 case JSON.UNKNOWN: 114 // leave state alone in this case 115 break; 116 default: 117 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorUnknownState", BLOCK, state), 118 request.id); 119 } 120 if (!data.path(JsonSensor.SENSOR).isMissingNode()) { 121 JsonNode node = data.path(JsonSensor.SENSOR); 122 if (node.isNull()) { 123 block.setSensor(null); 124 } else { 125 Sensor sensor = InstanceManager.getDefault(SensorManager.class).getBySystemName(node.asText()); 126 if (sensor != null) { 127 block.setSensor(sensor.getSystemName()); 128 } else { 129 throw new JsonException(404, 130 Bundle.getMessage(request.locale, JsonException.ERROR_NOT_FOUND, JsonSensor.SENSOR, 131 node.asText()), 132 request.id); 133 } 134 } 135 } 136 if (!data.path(JsonReporter.REPORTER).isMissingNode()) { 137 JsonNode node = data.path(JsonReporter.REPORTER); 138 if (node.isNull()) { 139 block.setReporter(null); 140 } else { 141 Reporter reporter = InstanceManager.getDefault(ReporterManager.class).getBySystemName(node.asText()); 142 if (reporter != null) { 143 block.setReporter(reporter); 144 } else { 145 throw new JsonException(404, 146 Bundle.getMessage(request.locale, JsonException.ERROR_NOT_FOUND, JsonReporter.REPORTER, 147 node.asText()), 148 request.id); 149 } 150 } 151 } 152 String text = data.findPath(JSON.SPEED).asText(block.getBlockSpeed()); 153 try { 154 block.setBlockSpeed(text); 155 } catch (JmriException ex) { 156 throw new JsonException(HttpServletResponse.SC_BAD_REQUEST, 157 Bundle.getMessage(request.locale, JsonException.ERROR_BAD_PROPERTY_VALUE, text, JSON.SPEED, type), 158 request.id); 159 } 160 block.setCurvature(data.path(JsonBlock.CURVATURE).asInt(block.getCurvature())); 161 block.setDirection(data.path(JSON.DIRECTION).asInt(block.getDirection())); 162 if (data.path(JSON.LENGTH).isNumber()) { 163 block.setLength(data.path(JSON.LENGTH).floatValue()); 164 } 165 block.setPermissiveWorking(data.path(JsonBlock.PERMISSIVE).asBoolean(block.getPermissiveWorking())); 166 return this.doGet(block, name, type, request); 167 } 168 169 @Override 170 protected void doDelete(Block bean, String name, String type, JsonNode data, JsonRequest request) 171 throws JsonException { 172 deleteBean(bean, name, type, data, request); 173 } 174 175 @Override 176 public JsonNode doSchema(String type, boolean server, JsonRequest request) throws JsonException { 177 switch (type) { 178 case BLOCK: 179 case BLOCKS: 180 return doSchema(type, 181 server, 182 "jmri/server/json/block/block-server.json", 183 "jmri/server/json/block/block-client.json", 184 request.id); 185 default: 186 throw new JsonException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 187 Bundle.getMessage(request.locale, JsonException.ERROR_UNKNOWN_TYPE, type), request.id); 188 } 189 } 190 191 @Override 192 protected String getType() { 193 return BLOCK; 194 } 195 196 @Override 197 protected ProvidingManager<Block> getProvidingManager() { 198 return InstanceManager.getDefault(BlockManager.class); 199 } 200 201}