Package srsim.io

Source Code of srsim.io.ClientConnection

package srsim.io;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.Socket;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;

import srsim.domain.Room;
import srsim.simulator.ISimulationController;
import srsim.simulator.SimulationContext;
import srsim.simulator.SimulationContextException;

/**
* Client connection class to handle communication with clients
*
* @author phil
*
*/
public class ClientConnection extends Thread {

  private static final String FAILURE_MSG = "ERR";
  private static final String SUCCESS_MSG = "OK";
  private static final String ROOM_LIST_MSG = "LIST_ROOMS";
  private static final String UPDATE_REQUEST_MSG = "UPDATE_REQUEST";
  private static final int RECIEVE_BUFFER_SIZE = 1024;
  private Socket clientSocket;
  private PreferencesServer server;
  private Map<String, List<String>> preferences;
  private String roomId;

  public ClientConnection(final Socket clientSocket,
      final PreferencesServer server) {
    this.clientSocket = clientSocket;
    this.server = server;
    preferences = new HashMap<String, List<String>>();
    roomId = null;
    setName("SRSIM Client " + clientSocket.getInetAddress());
    setDaemon(true);
    start();
  }

  @Override
  public void run() {
    try {
      handleConnection();
    } catch (IOException e) {
      System.out.println("Client "
          + clientSocket.getInetAddress().getHostAddress()
          + " lost connection");
    } catch (SimulationContextException e) {
      e.printStackTrace();
    } finally {
      try {
        unsetPreferences();
      } catch (SimulationContextException e) {
        e.printStackTrace();
      }
      server.setClientLocation(clientSocket.getInetAddress()
          .getHostAddress(), null);
    }
  }

  /**
   * Handles the connection, i.e. Reads from the input stream and replies with
   * "OK" whenever a message has been successfully processed.
   *
   * @throws IOException
   * @throws SimulationContextException
   */
  private void handleConnection() throws IOException,
      SimulationContextException {
    InputStreamReader reader;
    reader = new InputStreamReader(clientSocket.getInputStream());
    char[] buffer = new char[RECIEVE_BUFFER_SIZE];
    int len = reader.read(buffer);
    while (len >= 0) {
      String msg = new String(buffer, 0, len);
      if (msg.trim().equalsIgnoreCase(UPDATE_REQUEST_MSG)) {
        JsonObject contextUpdate = buildContextUpdate();
        String string = contextUpdate.toString();
        clientSocket.getOutputStream().write(string.getBytes());
      } else if (msg.trim().equalsIgnoreCase(ROOM_LIST_MSG)) {
        JsonArrayBuilder roomArrayBuilder = Json.createArrayBuilder();
        for (Room room : server.getController().getRooms()) {
          roomArrayBuilder.add(room.getName());
        }
        clientSocket.getOutputStream().write(
            roomArrayBuilder.build().toString().getBytes());
      } else if (msg.startsWith("{")) {
        try {
          parseMessage(msg);
          clientSocket.getOutputStream()
              .write(SUCCESS_MSG.getBytes());
        } catch (SimulationContextException e) {
          clientSocket.getOutputStream()
              .write(FAILURE_MSG.getBytes());
        }
      }
      buffer = new char[RECIEVE_BUFFER_SIZE];
      len = reader.read(buffer);
    }
  }

  /**
   * Builds a JSON representation of a simulation record
   *
   * @return
   * @throws SimulationContextException
   */
  private JsonObject buildContextUpdate() throws SimulationContextException {
    ISimulationController controller = server.getController();
    List<Room> rooms = controller.getRooms();
    JsonObjectBuilder contextUpdateBuilder = Json.createObjectBuilder();
    if (rooms != null) {
      for (Room room : rooms) {
        String name = room.getName();
        if (name.equalsIgnoreCase(roomId)) {
          SimulationContext context = room.getLocalContext();
          int[] lightColor = context.getLightColor();
          contextUpdateBuilder
              .add(SimulationContext.BRIGHTNESS,
                  context.getBrightness())
              .add(SimulationContext.TEMPERATURE,
                  context.getTemperature())
              .add(SimulationContext.LIGHTCOLOR,
                  String.format("%d %d %d", lightColor[0],
                      lightColor[1], lightColor[2]))
              .add(SimulationContext.ENERGY_CONSUMPTION,
                  context.getEnergyConsumption())
              .add(SimulationContext.MUSIC_GENRE,
                  context.getMusicGenre())
              .add(SimulationContext.MUSIC_VOLUME,
                  context.getMusicVolume());
        }
      }
    }
    JsonObject contextUpdate = contextUpdateBuilder.build();
    return contextUpdate;
  }

  /**
   * Unsets all prefrences set by the client
   *
   * @throws SimulationContextException
   */
  private void unsetPreferences() throws SimulationContextException {
    for (String key : preferences.keySet()) {
      for (String value : preferences.get(key)) {
        server.unsetPreference(roomId, key, value);
      }
    }
  }

  /**
   * Processes a JSON message
   *
   * @param msg
   * @throws SimulationContextException
   */
  private void parseMessage(final String msg)
      throws SimulationContextException {
    JsonObject jsonObject = Json.createReader(new StringReader(msg))
        .readObject();
    for (String key : jsonObject.keySet()) {
      String value = jsonObject.getString(key).trim();
      if (key.trim().equalsIgnoreCase("roomId")) {
        roomId = value;
        server.setClientLocation(clientSocket.getInetAddress()
            .getHostAddress(), roomId);
      } else {
        setPreference(key.trim(), value);
      }
    }
  }

  /**
   * Sets a preference
   *
   * @param key
   * @param value
   * @throws SimulationContextException
   */
  private void setPreference(final String key, final String value)
      throws SimulationContextException {
    server.setPreference(roomId, key, value);
    if (!preferences.keySet().contains(key)) {
      preferences.put(key, new LinkedList<String>());
    }
    preferences.get(key).add(value);
  }

  public void close() throws IOException {
    clientSocket.close();
  }
}
TOP

Related Classes of srsim.io.ClientConnection

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.