001package jmri.server.json.consist; 002 003import com.fasterxml.jackson.databind.JsonNode; 004import java.io.IOException; 005import java.util.HashSet; 006import jmri.ConsistListListener; 007import jmri.ConsistListener; 008import jmri.DccLocoAddress; 009import jmri.JmriException; 010import jmri.LocoAddress; 011import jmri.jmrit.consisttool.ConsistFile; 012import jmri.server.json.JSON; 013import jmri.server.json.JsonConnection; 014import jmri.server.json.JsonException; 015import jmri.server.json.JsonRequest; 016import jmri.server.json.JsonSocketService; 017import org.slf4j.Logger; 018import org.slf4j.LoggerFactory; 019 020/** 021 * 022 * @author Randall Wood Copyright (C) 2016 023 */ 024public class JsonConsistSocketService extends JsonSocketService<JsonConsistHttpService> { 025 026 private final HashSet<LocoAddress> consists = new HashSet<>(); 027 private final JsonConsistListener consistListener = new JsonConsistListener(); 028 private final JsonConsistListListener consistListListener = new JsonConsistListListener(); 029 private static final Logger log = LoggerFactory.getLogger(JsonConsistSocketService.class); 030 031 public JsonConsistSocketService(JsonConnection connection) { 032 super(connection, new JsonConsistHttpService(connection.getObjectMapper())); 033 service.manager.addConsistListListener(consistListListener); 034 } 035 036 @Override 037 public void onMessage(String type, JsonNode data, JsonRequest request) throws IOException, JmriException, JsonException { 038 if (JsonConsist.CONSISTS.equals(type)) { 039 connection.sendMessage(service.doGetList(type, data, request), request.id); 040 } else { 041 DccLocoAddress address = new DccLocoAddress(data.path(JSON.ADDRESS).asInt(), data.path(JSON.IS_LONG_ADDRESS).asBoolean()); 042 String name = address.getNumber() + (address.isLongAddress() ? "L" : ""); 043 if (request.method.equals(JSON.PUT)) { 044 connection.sendMessage(service.doPut(type, name, data, request), request.id); 045 } else { 046 connection.sendMessage(service.doPost(type, name, data, request), request.id); 047 } 048 if (!consists.contains(address)) { 049 service.manager.getConsist(address).addConsistListener(consistListener); 050 consists.add(address); 051 } 052 } 053 } 054 055 @Override 056 public void onList(String type, JsonNode data, JsonRequest request) throws IOException, JmriException, JsonException { 057 connection.sendMessage(service.doGetList(type, data, request), request.id); 058 } 059 060 @Override 061 public void onClose() { 062 consists.stream().forEach(address -> service.manager.getConsist(address).removeConsistListener(consistListener)); 063 consists.clear(); 064 service.manager.removeConsistListListener(consistListListener); 065 } 066 067 private class JsonConsistListener implements ConsistListener { 068 069 @Override 070 public void consistReply(LocoAddress locoaddress, int status) { 071 try { 072 try { 073 connection.sendMessage(service.getConsist(locoaddress, new JsonRequest(getLocale(), JSON.V5, JSON.GET, 0)), 0); 074 } catch (JsonException ex) { 075 connection.sendMessage(ex.getJsonMessage(), 0); 076 } 077 } catch (IOException ex) { 078 // this IO execption caused by broken comms with client 079 service.manager.getConsist(locoaddress).removeConsistListener(this); 080 consists.remove(locoaddress); 081 } 082 try { 083 (new ConsistFile()).writeFile(service.manager.getConsistList()); 084 } catch (IOException ex) { 085 // this IO execption caused by unable to write file 086 log.error("Unable to write consist file \"{}\"", ConsistFile.defaultConsistFilename(), ex); 087 } 088 } 089 } 090 091 private class JsonConsistListListener implements ConsistListListener { 092 093 @Override 094 public void notifyConsistListChanged() { 095 try { 096 try { 097 connection.sendMessage(service.doGetList(JsonConsist.CONSISTS, 098 service.getObjectMapper().createObjectNode(), new JsonRequest(getLocale(), getVersion(), JSON.GET, 0)), 0); 099 } catch (JsonException ex) { 100 connection.sendMessage(ex.getJsonMessage(), 0); 101 } 102 } catch (IOException ex) { 103 // this IO exception caused by broken communications with client 104 service.manager.removeConsistListListener(this); 105 } 106 try { 107 (new ConsistFile()).writeFile(service.manager.getConsistList()); 108 } catch (IOException ex) { 109 // this IO exception caused by unable to write file 110 log.error("Unable to write consist file \"{}\"", ConsistFile.defaultConsistFilename(), ex); 111 } 112 } 113 } 114}