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 JsonIdTagHttpService idTagService = new JsonIdTagHttpService(mapper); 043 private JsonReporterHttpService reporterService = new JsonReporterHttpService(mapper); 044 private 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(request.locale, ((BasicRosterEntry) bv).getId(), request.id); 074 data.set(VALUE, rosterValue); 075 } else { 076 // send string for types not explicitly handled 077 data.put(VALUE, bv.toString()); 078 } 079 data.put(JsonSensor.SENSOR, block.getSensor() != null ? block.getSensor().getSystemName() : null); 080 data.put(JsonReporter.REPORTER, block.getReporter() != null ? block.getReporter().getSystemName() : null); 081 data.put(JSON.SPEED, block.getBlockSpeed()); 082 data.put(JsonBlock.CURVATURE, block.getCurvature()); 083 data.put(JSON.DIRECTION, block.getDirection()); 084 data.put(JSON.LENGTH, block.getLengthMm()); 085 data.put(JsonBlock.PERMISSIVE, block.getPermissiveWorking()); 086 data.put(JsonBlock.SPEED_LIMIT, block.getSpeedLimit()); 087 ArrayNode array = data.putArray(JsonBlock.DENIED); 088 block.getDeniedBlocks().forEach(array::add); 089 return root; 090 } 091 092 @Override 093 public ObjectNode doPost(Block block, String name, String type, JsonNode data, JsonRequest request) 094 throws JsonException { 095 if (!data.path(JSON.VALUE).isMissingNode()) { 096 if (data.path(JSON.VALUE).isNull()) { 097 block.setValue(null); 098 } else { 099 block.setValue(data.path(JSON.VALUE).asText()); 100 } 101 } 102 int state = data.path(JSON.STATE).asInt(JSON.UNKNOWN); 103 switch (state) { 104 case JSON.ACTIVE: 105 block.setState(Block.OCCUPIED); 106 break; 107 case JSON.INACTIVE: 108 block.setState(Block.UNOCCUPIED); 109 break; 110 case JSON.UNKNOWN: 111 // leave state alone in this case 112 break; 113 default: 114 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorUnknownState", BLOCK, state), 115 request.id); 116 } 117 if (!data.path(JsonSensor.SENSOR).isMissingNode()) { 118 JsonNode node = data.path(JsonSensor.SENSOR); 119 if (node.isNull()) { 120 block.setSensor(null); 121 } else { 122 Sensor sensor = InstanceManager.getDefault(SensorManager.class).getBySystemName(node.asText()); 123 if (sensor != null) { 124 block.setSensor(sensor.getSystemName()); 125 } else { 126 throw new JsonException(404, 127 Bundle.getMessage(request.locale, JsonException.ERROR_NOT_FOUND, JsonSensor.SENSOR, 128 node.asText()), 129 request.id); 130 } 131 } 132 } 133 if (!data.path(JsonReporter.REPORTER).isMissingNode()) { 134 JsonNode node = data.path(JsonReporter.REPORTER); 135 if (node.isNull()) { 136 block.setReporter(null); 137 } else { 138 Reporter reporter = InstanceManager.getDefault(ReporterManager.class).getBySystemName(node.asText()); 139 if (reporter != null) { 140 block.setReporter(reporter); 141 } else { 142 throw new JsonException(404, 143 Bundle.getMessage(request.locale, JsonException.ERROR_NOT_FOUND, JsonReporter.REPORTER, 144 node.asText()), 145 request.id); 146 } 147 } 148 } 149 String text = data.findPath(JSON.SPEED).asText(block.getBlockSpeed()); 150 try { 151 block.setBlockSpeed(text); 152 } catch (JmriException ex) { 153 throw new JsonException(HttpServletResponse.SC_BAD_REQUEST, 154 Bundle.getMessage(request.locale, JsonException.ERROR_BAD_PROPERTY_VALUE, text, JSON.SPEED, type), 155 request.id); 156 } 157 block.setCurvature(data.path(JsonBlock.CURVATURE).asInt(block.getCurvature())); 158 block.setDirection(data.path(JSON.DIRECTION).asInt(block.getDirection())); 159 if (data.path(JSON.LENGTH).isNumber()) { 160 block.setLength(data.path(JSON.LENGTH).floatValue()); 161 } 162 block.setPermissiveWorking(data.path(JsonBlock.PERMISSIVE).asBoolean(block.getPermissiveWorking())); 163 return this.doGet(block, name, type, request); 164 } 165 166 @Override 167 protected void doDelete(Block bean, String name, String type, JsonNode data, JsonRequest request) 168 throws JsonException { 169 deleteBean(bean, name, type, data, request); 170 } 171 172 @Override 173 public JsonNode doSchema(String type, boolean server, JsonRequest request) throws JsonException { 174 switch (type) { 175 case BLOCK: 176 case BLOCKS: 177 return doSchema(type, 178 server, 179 "jmri/server/json/block/block-server.json", 180 "jmri/server/json/block/block-client.json", 181 request.id); 182 default: 183 throw new JsonException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 184 Bundle.getMessage(request.locale, JsonException.ERROR_UNKNOWN_TYPE, type), request.id); 185 } 186 } 187 188 @Override 189 protected String getType() { 190 return BLOCK; 191 } 192 193 @Override 194 protected ProvidingManager<Block> getProvidingManager() { 195 return InstanceManager.getDefault(BlockManager.class); 196 } 197 198}