MessageParser implements ReceiverListener { @Override public void messageArrived(final String message, final String ipAddress) { try { final int exclamation = message.indexOf("!"); final int hash = message.indexOf("#"); final int colon = message.indexOf(":"); final int msgCode = Integer.parseInt(message.substring(0, exclamation)); final String type = message.substring(exclamation + 1, hash); final String msgNick = message.substring(hash + 1, colon); final String msg = message.substring(colon + 1, message.length()); final User tempme = settings.getMe(); if (msgCode != tempme.getCode() && loggedOn) { if (type.equals(MSG)) { final int leftBracket = msg.indexOf("["); final int rightBracket = msg.indexOf("]"); final int rgb = Integer.parseInt(msg.substring(leftBracket + 1, rightBracket)); responder.messageArrived(msgCode, msg.substring(rightBracket + 1, msg.length()), rgb); } else if (type.equals(LOGON)) { final User newUser = new User(msgNick, msgCode); newUser.setIpAddress(ipAddress); newUser.setLastIdle(System.currentTimeMillis()); newUser.setLogonTime(System.currentTimeMillis()); responder.userLogOn(newUser); } else if (type.equals(EXPOSING)) { final User user = new User(msgNick, msgCode); user.setIpAddress(ipAddress); user.setAwayMsg(msg); if (msg.length() > 0) { user.setAway(true); } user.setLastIdle(System.currentTimeMillis()); user.setLogonTime(System.currentTimeMillis()); responder.userExposing(user); } else if (type.equals(LOGOFF)) { responder.userLogOff(msgCode); } else if (type.equals(AWAY)) { responder.awayChanged(msgCode, true, msg); } else if (type.equals(BACK)) { responder.awayChanged(msgCode, false, ""); } else if (type.equals(EXPOSE)) { responder.exposeRequested(); } else if (type.equals(NICKCRASH)) { if (tempme.getNick().equals(msg)) { responder.nickCrash(); } } else if (type.equals(WRITING)) { responder.writingChanged(msgCode, true); } else if (type.equals(STOPPEDWRITING)) { responder.writingChanged(msgCode, false); } else if (type.equals(GETTOPIC)) { responder.topicRequested(); } else if (type.equals(TOPIC)) { final int leftBracket = msg.indexOf("["); final int rightBracket = msg.indexOf("]"); final int leftPara = msg.indexOf("("); final int rightPara = msg.indexOf(")"); if (rightBracket != -1 && leftBracket != -1) { final String theNick = msg.substring(leftPara + 1, rightPara); final long theTime = Long.parseLong(msg.substring(leftBracket + 1, rightBracket)); String theTopic = null; if (msg.length() > rightBracket + 1) { theTopic = msg.substring(rightBracket + 1, msg.length()); } responder.topicChanged(msgCode, theTopic, theNick, theTime); } } else if (type.equals(NICK)) { responder.nickChanged(msgCode, msgNick); } else if (type.equals(IDLE)) { responder.userIdle(msgCode, ipAddress); } else if (type.equals(SENDFILEACCEPT)) { final int leftPara = msg.indexOf("("); final int rightPara = msg.indexOf(")"); final int fileCode = Integer.parseInt(msg.substring(leftPara + 1, rightPara)); if (fileCode == tempme.getCode()) { final int leftCurly = msg.indexOf("{"); final int rightCurly = msg.indexOf("}"); final int leftBracket = msg.indexOf("["); final int rightBracket = msg.indexOf("]"); final int port = Integer.parseInt(msg.substring(leftBracket + 1, rightBracket)); final int fileHash = Integer.parseInt(msg.substring(leftCurly + 1, rightCurly)); final String fileName = msg.substring(rightCurly + 1, msg.length()); responder.fileSendAccepted(msgCode, fileName, fileHash, port); } } else if (type.equals(SENDFILEABORT)) { final int leftPara = msg.indexOf("("); final int rightPara = msg.indexOf(")"); final int fileCode = Integer.parseInt(msg.substring(leftPara + 1, rightPara)); if (fileCode == tempme.getCode()) { final int leftCurly = msg.indexOf("{"); final int rightCurly = msg.indexOf("}"); final String fileName = msg.substring(rightCurly + 1, msg.length()); final int fileHash = Integer.parseInt(msg.substring(leftCurly + 1, rightCurly)); responder.fileSendAborted(msgCode, fileName, fileHash); } } else if (type.equals(SENDFILE)) { final int leftPara = msg.indexOf("("); final int rightPara = msg.indexOf(")"); final int fileCode = Integer.parseInt(msg.substring(leftPara + 1, rightPara)); if (fileCode == tempme.getCode()) { final int leftCurly = msg.indexOf("{"); final int rightCurly = msg.indexOf("}"); final int leftBracket = msg.indexOf("["); final int rightBracket = msg.indexOf("]"); final long byteSize = Long.parseLong(msg.substring(leftBracket + 1, rightBracket)); final String fileName = msg.substring(rightCurly + 1, msg.length()); final int fileHash = Integer.parseInt(msg.substring(leftCurly + 1, rightCurly)); responder.fileSend(msgCode, byteSize, fileName, msgNick, fileHash); } } else if (type.equals(CLIENT)) { final int leftPara = msg.indexOf("("); final int rightPara = msg.indexOf(")"); final int leftBracket = msg.indexOf("["); final int rightBracket = msg.indexOf("]"); final int leftCurly = msg.indexOf("{"); final int rightCurly = msg.indexOf("}"); final int lessThan = msg.indexOf("<"); final int greaterThan = msg.indexOf(">"); final int slash = msg.indexOf("/"); final int backslash = msg.indexOf("\\"); final String client = msg.substring(leftPara + 1, rightPara); final long timeSinceLogon = Long.parseLong(msg.substring(leftBracket + 1, rightBracket)); final String operatingSystem = msg.substring(leftCurly + 1, rightCurly); int privateChatPort = 0; try { privateChatPort = Integer.parseInt(msg.substring(lessThan + 1, greaterThan)); } catch (final NumberFormatException e) { LOG.log(Level.WARNING, "Failed to parse private chat port. message=" + message + ", ipAddress=" + ipAddress, e); } int tcpChatPort = 0; if (slash != -1 && backslash != -1) { try { tcpChatPort = Integer.parseInt(msg.substring(slash + 1, backslash)); } catch (final NumberFormatException e) { LOG.log(Level.WARNING, "Failed to parse tcp chat port. message=" + message + ", ipAddress=" + ipAddress, e); } } responder.clientInfo(msgCode, client, timeSinceLogon, operatingSystem, privateChatPort, tcpChatPort); } } else if (msgCode == tempme.getCode() && type.equals(LOGON)) { responder.meLogOn(ipAddress); loggedOn = true; } else if (msgCode == tempme.getCode() && type.equals(IDLE) && loggedOn) { responder.meIdle(ipAddress); } } catch (final StringIndexOutOfBoundsException e) { LOG.log(Level.SEVERE, "Failed to parse message. message=" + message + ", ipAddress=" + ipAddress, e); } catch (final NumberFormatException e) { LOG.log(Level.SEVERE, "Failed to parse message. message=" + message + ", ipAddress=" + ipAddress, e); } } MessageParser(final MessageResponder responder, final Settings settings); @Override void messageArrived(final String message, final String ipAddress);  }
@Test public void messageArrivedShouldLogIfUnableToFindNecessaryDetailsInMessage() { messageParser.messageArrived("Error", "192.168.1.1"); final ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(log).log(eq(Level.SEVERE), eq("Failed to parse message. message=Error, ipAddress=192.168.1.1"), exceptionCaptor.capture()); checkException(exceptionCaptor, StringIndexOutOfBoundsException.class, null); }
@Test public void messageArrivedShouldLogIfUnableToParseUserCodeInMessage() { messageParser.messageArrived("a16320462!LOGON#Christian:", "192.168.1.1"); final ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(log).log(eq(Level.SEVERE), eq("Failed to parse message. message=a16320462!LOGON#Christian:, ipAddress=192.168.1.1"), exceptionCaptor.capture()); checkException(exceptionCaptor, NumberFormatException.class, "For input string: \"a16320462\""); }
@Test public void messageArrivedShouldLogIfPrivateChatPortCouldNotBeParsed() { messageParser.messageArrived("16320462!CLIENT#Christian:(KouChat v1.3.0 Swing)[2688]{Linux}<a40657>", "192.168.1.1"); final ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(log).log(eq(Level.WARNING), eq("Failed to parse private chat port. " + "message=16320462!CLIENT#Christian:(KouChat v1.3.0 Swing)[2688]{Linux}<a40657>, " + "ipAddress=192.168.1.1"), exceptionCaptor.capture()); checkException(exceptionCaptor, NumberFormatException.class, "For input string: \"a40657\""); }
@Test public void messageArrivedShouldParseClientWithoutTcpChatPort() { messageParser.messageArrived("19879835!CLIENT#Christian:(KouChat v1.3.0 Swing)[1854]{Linux}<40656>", "192.168.1.1"); verify(responder).clientInfo(19879835, "KouChat v1.3.0 Swing", 1854, "Linux", 40656, 0); }
@Test public void messageArrivedShouldParseClientWithTcpChatPort() { messageParser.messageArrived("10066122!CLIENT#Christian:(KouChat v1.4.0 Swing)[1753]{Linux}<40656>/40657\\", "192.168.1.1"); verify(responder).clientInfo(10066122, "KouChat v1.4.0 Swing", 1753, "Linux", 40656, 40657); }
@Test public void messageArrivedShouldLogIfTcpChatPortCouldNotBeParsed() { messageParser.messageArrived("10066122!CLIENT#Christian:(KouChat v1.4.0 Swing)[1753]{Linux}<40656>/b40657\\", "192.168.1.1"); final ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(log).log(eq(Level.WARNING), eq("Failed to parse tcp chat port. " + "message=10066122!CLIENT#Christian:(KouChat v1.4.0 Swing)[1753]{Linux}<40656>/b40657\\, " + "ipAddress=192.168.1.1"), exceptionCaptor.capture()); checkException(exceptionCaptor, NumberFormatException.class, "For input string: \"b40657\""); }
@Test public void messageArrivedShouldLogIfTimeSinceLogonCouldNotBeParsed() { messageParser.messageArrived("16320462!CLIENT#Christian:(KouChat v1.3.0 Swing)[a2688]{Linux}<40657>", "192.168.1.1"); final ArgumentCaptor<Exception> exceptionCaptor = ArgumentCaptor.forClass(Exception.class); verify(log).log(eq(Level.SEVERE), eq("Failed to parse message. " + "message=16320462!CLIENT#Christian:(KouChat v1.3.0 Swing)[a2688]{Linux}<40657>, " + "ipAddress=192.168.1.1"), exceptionCaptor.capture()); checkException(exceptionCaptor, NumberFormatException.class, "For input string: \"a2688\""); }