001package jmri.server.json.turnout; 002 003import static jmri.server.json.JSON.CLOSED; 004import static jmri.server.json.JSON.INCONSISTENT; 005import static jmri.server.json.JSON.INVERTED; 006import static jmri.server.json.JSON.STATE; 007import static jmri.server.json.JSON.THROWN; 008import static jmri.server.json.JSON.UNKNOWN; 009import static jmri.server.json.sensor.JsonSensor.SENSOR; 010import static jmri.server.json.turnout.JsonTurnout.FEEDBACK_MODE; 011import static jmri.server.json.turnout.JsonTurnout.FEEDBACK_MODES; 012import static jmri.server.json.turnout.JsonTurnout.TURNOUT; 013import static jmri.server.json.turnout.JsonTurnout.TURNOUTS; 014 015import com.fasterxml.jackson.databind.JsonNode; 016import com.fasterxml.jackson.databind.ObjectMapper; 017import com.fasterxml.jackson.databind.node.ArrayNode; 018import com.fasterxml.jackson.databind.node.ObjectNode; 019 020import javax.annotation.Nonnull; 021import javax.servlet.http.HttpServletResponse; 022import jmri.InstanceManager; 023import jmri.JmriException; 024import jmri.NamedBean; 025import jmri.ProvidingManager; 026import jmri.Sensor; 027import jmri.Turnout; 028import jmri.TurnoutManager; 029import jmri.server.json.JSON; 030import jmri.server.json.JsonException; 031import jmri.server.json.JsonNamedBeanHttpService; 032import jmri.server.json.JsonRequest; 033import jmri.server.json.sensor.JsonSensor; 034import jmri.server.json.sensor.JsonSensorHttpService; 035 036/** 037 * 038 * @author Randall Wood 039 */ 040public class JsonTurnoutHttpService extends JsonNamedBeanHttpService<Turnout> { 041 042 private final JsonSensorHttpService sensorService; 043 044 public JsonTurnoutHttpService(ObjectMapper mapper) { 045 super(mapper); 046 sensorService = new JsonSensorHttpService(mapper); 047 } 048 049 @Override 050 public ObjectNode doGet(Turnout turnout, String name, String type, JsonRequest request) throws JsonException { 051 ObjectNode root = this.getNamedBean(turnout, name, getType(), request); // throws JsonException if turnout == null 052 ObjectNode data = root.with(JSON.DATA); 053 if (turnout != null) { 054 data.put(INVERTED, turnout.getInverted()); 055 switch (turnout.getKnownState()) { 056 case Turnout.THROWN: 057 data.put(STATE, THROWN); 058 break; 059 case Turnout.CLOSED: 060 data.put(STATE, CLOSED); 061 break; 062 case NamedBean.INCONSISTENT: 063 data.put(STATE, INCONSISTENT); 064 break; 065 case NamedBean.UNKNOWN: 066 default: 067 data.put(STATE, UNKNOWN); 068 break; 069 } 070 data.put(FEEDBACK_MODE, turnout.getFeedbackMode()); 071 ArrayNode modes = data.arrayNode(); 072 turnout.getValidFeedbackModes().forEach(modes::add); 073 data.set(FEEDBACK_MODES, modes); 074 ArrayNode sensors = data.arrayNode(); 075 Sensor sensor = turnout.getFirstSensor(); 076 sensors.add(sensor == null ? null : sensorService.doGet(sensor, sensor.getSystemName(), JsonSensor.SENSOR, request)); 077 sensor = turnout.getSecondSensor(); 078 sensors.add(sensor == null ? null : sensorService.doGet(sensor, sensor.getSystemName(), JsonSensor.SENSOR, request)); 079 data.set(SENSOR, sensors); 080 } 081 return root; 082 } 083 084 @Override 085 public ObjectNode doPost(Turnout turnout, String name, String type, JsonNode data, JsonRequest request) throws JsonException { 086 if (data.path(SENSOR).isArray()) { 087 int number = 0; 088 for (JsonNode node : data.path(SENSOR)) { 089 if (node != null) { 090 this.addSensorToTurnout(turnout, node, number, request); 091 } 092 number++; 093 } 094 } 095 if (data.path(FEEDBACK_MODE).isInt()) { 096 try { 097 turnout.setFeedbackMode(data.path(FEEDBACK_MODE).asInt()); 098 } catch (IllegalArgumentException ex) { 099 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorInvalidProperty", FEEDBACK_MODE, type, name), request.id); 100 } 101 } 102 if (data.path(INVERTED).isBoolean()) { 103 turnout.setInverted(data.path(INVERTED).asBoolean()); 104 } 105 turnout.setInverted(data.path(INVERTED).asBoolean(turnout.getInverted())); 106 int state = data.path(STATE).asInt(UNKNOWN); 107 switch (state) { 108 case THROWN: 109 turnout.setCommandedState(Turnout.THROWN); 110 break; 111 case CLOSED: 112 turnout.setCommandedState(Turnout.CLOSED); 113 break; 114 case UNKNOWN: 115 // leave state alone in this case 116 break; 117 default: 118 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorUnknownState", TURNOUT, state), request.id); 119 } 120 return this.doGet(turnout, name, type, request); 121 } 122 123 private void addSensorToTurnout(@Nonnull Turnout turnout, @Nonnull JsonNode data, int number, @Nonnull JsonRequest request) throws JsonException { 124 try { 125 if (data.isNull()) { 126 turnout.provideFeedbackSensor(null, number); 127 } else { 128 Sensor sensor = null; 129 if (data.isTextual()) { 130 sensor = sensorService.getNamedBean(SENSOR, data.asText(), mapper.nullNode(), request); 131 } else if (data.isObject()) { 132 sensor = sensorService.getNamedBean(SENSOR, data.path(JSON.NAME).asText(), data, request); 133 } else { 134 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorInvalidProperty", SENSOR, TURNOUT, turnout.getSystemName()), request.id); 135 } 136 if (sensor != null) { 137 turnout.provideFeedbackSensor(sensor.getSystemName(), number); 138 } else { 139 throw new JsonException(404, 140 Bundle.getMessage(request.locale, "ErrorNotFound", SENSOR, data.asText()), request.id); 141 } 142 } 143 } catch (JmriException ex) { 144 throw new JsonException(500, Bundle.getMessage(request.locale, "ErrorInternal", TURNOUT), request.id); 145 } 146 } 147 148 @Override 149 protected void doDelete(Turnout bean, String name, String type, JsonNode data, JsonRequest request) 150 throws JsonException { 151 deleteBean(bean, name, type, data, request); 152 } 153 154 @Override 155 public JsonNode doSchema(String type, boolean server, JsonRequest request) throws JsonException { 156 switch (type) { 157 case TURNOUT: 158 case TURNOUTS: 159 return doSchema(type, 160 server, 161 "jmri/server/json/turnout/turnout-server.json", 162 "jmri/server/json/turnout/turnout-client.json", 163 request.id); 164 default: 165 throw new JsonException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, Bundle.getMessage(request.locale, JsonException.ERROR_UNKNOWN_TYPE, type), request.id); 166 } 167 } 168 169 @Override 170 protected String getType() { 171 return TURNOUT; 172 } 173 174 @Override 175 protected ProvidingManager<Turnout> getProvidingManager() { 176 return InstanceManager.getDefault(TurnoutManager.class); 177 } 178}