1 /* 2 * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 import java.nio.ByteBuffer; 42 43 /** 44 * The first state a newly connected {@code Client} is in, this 45 * handles writing out the welcoming message and reads the response 46 * up to a newline. When a newline character have been received 47 * it changes the handler from NameReader to MessageReader on the 48 * client. 49 */ 50 class NameReader implements DataReader { 51 private final StringBuilder buffer = new StringBuilder(); 52 private final ChatServer chatServer; 53 private boolean once = true; 54 private static final String NEWLINE = "\n"; 55 56 public NameReader(ChatServer chatServer) { 57 this.chatServer = chatServer; 58 } 59 60 /** 61 * Writes the welcoming message to the client the first time this method 62 * is called. 63 * 64 * @param client the client to receive the message 65 */ 66 @Override 67 public void beforeRead(Client client) { 68 // if it is a long name that takes more than one read we only want to display Name: once. 69 if (once) { 70 client.writeStringMessage("Name: "); 71 once = false; 72 } 73 } 74 75 public boolean acceptsMessages() { 76 return false; 77 } 78 79 /** 80 * Receives incoming data from the socket, searches for a newline 81 * and tries to set the username if one is found 82 */ 83 @Override 84 public void onData(Client client, ByteBuffer buffer, int bytes) { 85 buffer.flip(); 86 String name; 87 name = this.buffer.append(new String(buffer.array(), 0, bytes)).toString(); 88 if (name.contains(NEWLINE)) { 89 onUserNameRead(client, name); 90 } 91 } 92 93 /** 94 * Splits the name on the newlines, takes the first as the username 95 * and appends everything else to the clients message buffer. 96 * Sets the clients handler to MessageReader. 97 * 98 * @param client the client to set the username for 99 * @param name the string containing the buffered input 100 */ 101 private void onUserNameRead(Client client, String name) { 102 String[] strings = name.split(NEWLINE, 2); 103 client.setUserName(strings[0].trim()); 104 sendRemainingParts(client, strings); 105 client.setReader(new ClientReader(chatServer, new MessageReader(chatServer))); 106 client.writeStringMessage("Welcome " + client.getUserName() + "\n"); 107 } 108 109 /** 110 * Appends the remaining parts to the clients message buffer 111 * 112 * @param client the client 113 * @param strings the messages to append to the buffer 114 */ 115 private void sendRemainingParts(Client client, String[] strings) { 116 for (int i = 1; i < strings.length; ++i) { 117 client.appendMessage(strings[i]); 118 } 119 } 120 } 121