001package jmri.server.json.signalhead; 002 003import static jmri.server.json.JSON.APPEARANCE; 004import static jmri.server.json.JSON.APPEARANCE_NAME; 005import static jmri.server.json.JSON.DATA; 006import static jmri.server.json.JSON.LIT; 007import static jmri.server.json.JSON.STATE; 008import static jmri.server.json.JSON.TOKEN_HELD; 009import static jmri.server.json.signalhead.JsonSignalHead.SIGNAL_HEAD; 010import static jmri.server.json.signalhead.JsonSignalHead.SIGNAL_HEADS; 011 012import com.fasterxml.jackson.databind.JsonNode; 013import com.fasterxml.jackson.databind.ObjectMapper; 014import com.fasterxml.jackson.databind.node.ArrayNode; 015import com.fasterxml.jackson.databind.node.ObjectNode; 016import javax.servlet.http.HttpServletResponse; 017import jmri.InstanceManager; 018import jmri.SignalHead; 019import jmri.SignalHeadManager; 020import jmri.server.json.JSON; 021import jmri.server.json.JsonException; 022import jmri.server.json.JsonNonProvidedNamedBeanHttpService; 023import jmri.server.json.JsonRequest; 024 025/** 026 * JSON HTTP service for {@link jmri.SignalHead}s. 027 * 028 * @author Randall Wood Copyright 2016, 2018 029 */ 030public class JsonSignalHeadHttpService extends JsonNonProvidedNamedBeanHttpService<SignalHead> { 031 032 public JsonSignalHeadHttpService(ObjectMapper mapper) { 033 super(mapper); 034 } 035 036 @Override 037 public JsonNode doGet(String type, String name, JsonNode data, JsonRequest request) throws JsonException { 038 return doGet(InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(name), name, type, request); 039 } 040 041 @Override 042 protected ObjectNode doGet(SignalHead signalHead, String name, String type, JsonRequest request) throws JsonException { 043 ObjectNode root = this.getNamedBean(signalHead, name, type, request); // throws JsonException if signalHead == null 044 ObjectNode data = root.with(DATA); 045 if (signalHead != null) { 046 data.put(LIT, signalHead.getLit()); 047 data.put(APPEARANCE, signalHead.getAppearance()); 048 data.put(TOKEN_HELD, signalHead.getHeld()); 049 //state is appearance, plus a flag for held status 050 if (signalHead.getHeld()) { 051 data.put(STATE, SignalHead.HELD); 052 } else { 053 data.put(STATE, signalHead.getAppearance()); 054 } 055 data.put(APPEARANCE_NAME, signalHead.getAppearanceName()); 056 } 057 return root; 058 } 059 060 @Override 061 public JsonNode doPost(String type, String name, JsonNode data, JsonRequest request) throws JsonException { 062 SignalHead signalHead = this.postNamedBean(InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(name), data, name, type, request); 063 if (data.path(STATE).isIntegralNumber()) { 064 int state = data.path(STATE).asInt(); 065 if (state == SignalHead.HELD) { 066 signalHead.setHeld(true); 067 } else { 068 boolean isValid = false; 069 for (int validState : signalHead.getValidStates()) { 070 if (state == validState) { 071 isValid = true; 072 // TODO: completely insulate JSON state from SignalHead state 073 if (signalHead.getHeld()) { 074 signalHead.setHeld(false); 075 } 076 signalHead.setAppearance(state); 077 break; 078 } 079 } 080 if (!isValid) { 081 throw new JsonException(400, Bundle.getMessage(request.locale, "ErrorUnknownState", SIGNAL_HEAD, state), request.id); 082 } 083 } 084 } 085 if (data.path(LIT).isTextual()) { 086 signalHead.setLit(data.path(LIT).asBoolean()); 087 } 088 if (data.path(TOKEN_HELD).isTextual()) { 089 signalHead.setHeld(data.path(TOKEN_HELD).asBoolean()); 090 } 091 return this.doGet(type, name, data, request); 092 } 093 094 @Override 095 public JsonNode doGetList(String type, JsonNode data, JsonRequest request) throws JsonException { 096 ArrayNode array = this.mapper.createArrayNode(); 097 for (SignalHead head : InstanceManager.getDefault(SignalHeadManager.class).getNamedBeanSet()) { 098 String name = head.getSystemName(); 099 array.add(this.doGet(SIGNAL_HEAD, name, data, request)); 100 } 101 return message(array, request.id); 102 } 103 104 @Override 105 public JsonNode doSchema(String type, boolean server, JsonRequest request) throws JsonException { 106 switch (type) { 107 case SIGNAL_HEAD: 108 case SIGNAL_HEADS: 109 return doSchema(type, 110 server, 111 "jmri/server/json/signalhead/signalHead-server.json", 112 "jmri/server/json/signalhead/signalHead-client.json", 113 request.id); 114 default: 115 throw new JsonException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, Bundle.getMessage(request.locale, JsonException.ERROR_UNKNOWN_TYPE, type), request.id); 116 } 117 } 118 119 @Override 120 public SignalHead getNamedBean(String type, String name, JsonNode data, JsonRequest request) throws JsonException { 121 try { 122 if (!data.isEmpty() && !data.isNull()) { 123 if (JSON.PUT.equals(request.method)) { 124 doPut(type, name, data, request); 125 } else if (JSON.POST.equals(request.method)) { 126 doPost(type, name, data, request); 127 } 128 } 129 return InstanceManager.getDefault(SignalHeadManager.class).getBySystemName(name); 130 } catch (IllegalArgumentException ex) { 131 throw new JsonException(HttpServletResponse.SC_BAD_REQUEST, Bundle.getMessage(request.locale, "ErrorInvalidSystemName", name, type), request.id); 132 } 133 } 134}