001package jmri.server.json.util; 002 003import com.fasterxml.jackson.databind.JsonNode; 004import java.beans.PropertyChangeEvent; 005import java.beans.PropertyChangeListener; 006import java.io.IOException; 007import jmri.InstanceManager; 008import jmri.JmriException; 009import jmri.server.json.JSON; 010import jmri.server.json.JsonConnection; 011import jmri.server.json.JsonException; 012import jmri.server.json.JsonRequest; 013import jmri.server.json.JsonSocketService; 014import jmri.web.server.WebServerPreferences; 015 016/** 017 * 018 * @author Randall Wood 019 */ 020public class JsonUtilSocketService extends JsonSocketService<JsonUtilHttpService> { 021 022 private PropertyChangeListener rrNameListener; 023 024 public JsonUtilSocketService(JsonConnection connection) { 025 super(connection, new JsonUtilHttpService(connection.getObjectMapper())); 026 } 027 028 /** 029 * Package protected method for unit testing that allows a test HTTP service 030 * to be used. 031 * 032 * @param connection the connection to use 033 * @param service the supporting HTTP service 034 */ 035 JsonUtilSocketService(JsonConnection connection, JsonUtilHttpService service) { 036 super(connection, service); 037 } 038 039 @Override 040 public void onMessage(String type, JsonNode data, JsonRequest request) throws IOException, JmriException, JsonException { 041 String name = data.path(JSON.NAME).asText(); 042 switch (type) { 043 case JSON.LOCALE: 044 // do nothing - we only want to prevent an error at this point 045 break; 046 case JSON.PING: 047 this.connection.sendMessage(this.connection.getObjectMapper().createObjectNode().put(JSON.TYPE, JSON.PONG), request.id); 048 break; 049 case JSON.GOODBYE: 050 this.connection.sendMessage(this.connection.getObjectMapper().createObjectNode().put(JSON.TYPE, JSON.GOODBYE), request.id); 051 break; 052 case JSON.RAILROAD: 053 this.connection.sendMessage(this.service.doGet(type, name, data, request), request.id); 054 this.rrNameListener = (PropertyChangeEvent evt) -> { 055 try { 056 this.handleRailroadChange(); 057 } catch (IOException ex) { 058 InstanceManager.getDefault(WebServerPreferences.class).removePropertyChangeListener(this.rrNameListener); 059 } 060 }; 061 InstanceManager.getOptionalDefault(WebServerPreferences.class).ifPresent(preferences -> preferences.addPropertyChangeListener(this.rrNameListener)); 062 break; 063 default: 064 this.connection.sendMessage(this.service.doPost(type, name, data, request), request.id); 065 break; 066 } 067 } 068 069 @Override 070 public void onList(String type, JsonNode data, JsonRequest request) throws IOException, JmriException, JsonException { 071 this.connection.sendMessage(this.service.doGetList(type, data, request), request.id); 072 } 073 074 @Override 075 public void onClose() { 076 InstanceManager.getOptionalDefault(WebServerPreferences.class).ifPresent(preferences -> preferences.removePropertyChangeListener(this.rrNameListener)); 077 } 078 079 private void handleRailroadChange() throws IOException { 080 try { 081 connection.sendMessage(service.doGet(JSON.RAILROAD, null, connection.getObjectMapper().createObjectNode(), new JsonRequest(this.connection.getLocale(), JSON.V5, JSON.GET, 0)), 0); 082 } catch (JsonException ex) { 083 this.connection.sendMessage(ex.getJsonMessage(), 0); 084 } 085 } 086}