001package jmri.jmrix.roco.z21; 002 003import jmri.jmrix.lenz.XNetReply; 004import jmri.jmrix.lenz.XPressNetMessageFormatter; 005import org.reflections.Reflections; 006import org.slf4j.Logger; 007import org.slf4j.LoggerFactory; 008 009import java.lang.reflect.Constructor; 010import java.lang.reflect.InvocationTargetException; 011import java.util.ArrayList; 012import java.util.List; 013import java.util.Set; 014 015/** 016 * Represents a single response from the XpressNet, with extensions 017 * from Roco for the Z21. 018 * 019 * @author Paul Bender Copyright (C) 2018 020 * 021 */ 022public class Z21XNetReply extends XNetReply { 023 024 // Create a new reply. 025 public Z21XNetReply() { 026 super(); 027 } 028 029 // Create a new reply from an existing reply 030 public Z21XNetReply(Z21XNetReply reply) { 031 super(reply); 032 } 033 034 /** 035 * Create a reply from an XNetMessage. 036 * @param message message to create reply from. 037 */ 038 public Z21XNetReply(Z21XNetMessage message) { 039 super(message); 040 } 041 042 /** 043 * Create a reply from a string of hex characters. 044 * @param message hex character string. 045 */ 046 public Z21XNetReply(String message) { 047 super(message); 048 } 049 050 /** 051 * Is this message a service mode response? 052 */ 053 @Override 054 public boolean isServiceModeResponse() { 055 return ((getElement(0) == Z21Constants.LAN_X_CV_RESULT_XHEADER && 056 (getElement(1) == Z21Constants.LAN_X_CV_RESULT_DB0)) || 057 super.isServiceModeResponse()); 058 } 059 060 @Override 061 public boolean isFeedbackMessage() { 062 return (this.getElement(0) == Z21Constants.LAN_X_TURNOUT_INFO || 063 super.isFeedbackMessage()); 064 } 065 066 067 private static final List<XPressNetMessageFormatter> formatterList = new ArrayList<>(); 068 /** 069 * @return a string representation of the reply suitable for display in the 070 * XpressNet monitor. 071 */ 072 @Override 073 public String toMonitorString(){ 074 if(formatterList.isEmpty()) { 075 try { 076 Reflections reflections = new Reflections("jmri.jmrix"); 077 Set<Class<? extends XPressNetMessageFormatter>> f = reflections.getSubTypesOf(XPressNetMessageFormatter.class); 078 for (Class<?> c : f) { 079 log.debug("Found formatter: {}", f.getClass().getName()); 080 Constructor<?> ctor = c.getConstructor(); 081 formatterList.add((XPressNetMessageFormatter) ctor.newInstance()); 082 } 083 } catch (NoSuchMethodException | SecurityException | InstantiationException | 084 IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { 085 log.error("Error instantiating formatter", e); 086 } 087 } 088 089 return formatterList.stream() 090 .filter(f -> f.handlesMessage(this)) 091 .findFirst().map(f -> f.formatMessage(this)) 092 .orElse(this.toString()); 093 } 094 095 private static final Logger log = LoggerFactory.getLogger(Z21XNetReply.class); 096}