package com.twasyl.slideshowfx.server.beans.chat;
import io.vertx.core.json.JsonObject;
import java.net.InetSocketAddress;
import java.util.Base64;
import java.util.logging.Logger;
import static com.twasyl.slideshowfx.global.configuration.GlobalConfiguration.getDefaultCharset;
/**
* This class represents a message that can be sent over the internal chat of SlideshowFX.
*
* @author Thierry Wasylczenko
* @version 1.0
* @since SlideshowFX 1.0
*/
public class ChatMessage {
private static final Logger LOGGER = Logger.getLogger(ChatMessage.class.getName());
private static final String JSON_MESSAGE_OBJECT = "message";
private static final String JSON_MESSAGE_ID_ATTR = "id";
private static final String JSON_MESSAGE_AUTHOR_ATTR = "author";
private static final String JSON_MESSAGE_CONTENT_ATTR = "content";
private static final String JSON_MESSAGE_ACTION_ATTR = "action";
private static final String JSON_MESSAGE_SOURCE_ATTR = "source";
private static final String JSON_MESSAGE_STATUS_ATTR = "status";
private String id;
private String author;
private String content;
private ChatMessageSource source;
private ChatMessageAction action;
private ChatMessageStatus status;
private InetSocketAddress ip;
public ChatMessage() {}
public String getId() { return id; }
public void setId(String id) {
if(id != null) {
if(id.startsWith("msg-")) this.id = id;
else this.id = "msg-".concat(id);
}
}
public String getAuthor() { return author; }
public void setAuthor(String author) { this.author = author; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public ChatMessageSource getSource() { return source; }
public void setSource(ChatMessageSource source) { this.source = source; }
public ChatMessageAction getAction() { return action; }
public void setAction(ChatMessageAction action) { this.action = action; }
public ChatMessageStatus getStatus() { return status; }
public void setStatus(ChatMessageStatus status) { this.status = status; }
public InetSocketAddress getIp() { return ip; }
public void setIp(InetSocketAddress ip) { this.ip = ip; }
/**
* Encode the content in Base64.
* @return the content of the message encoded in Base64.
*/
private String encodeContent() {
if(getContent() != null) {
return Base64.getEncoder().encodeToString(getContent().getBytes(getDefaultCharset()));
}
return null;
}
/**
* Decode the given base64 content.
* @param contentToDecode The content that must be decoded.
* @return The decoded content.
*/
private String decodeContent(String contentToDecode) {
if(contentToDecode != null) {
return new String(Base64.getDecoder().decode(contentToDecode), getDefaultCharset());
}
return null;
}
/**
* Build a ChatMessage according the JSON representation.
* @param json The JSON representation of the message.
* @param ip The IP address of the message.
* @return A ChatMessage according the JSON representation.
* @throws IllegalArgumentException If the JSON representation is {@code null} or empty.
*/
public static ChatMessage build(String json, InetSocketAddress ip) throws IllegalArgumentException {
if(json == null) throw new IllegalArgumentException("The JSON can not be null");
if(json.isEmpty()) throw new IllegalArgumentException("The JSON can not beb empty");
ChatMessage message = new ChatMessage();
message.setIp(ip);
JsonObject jsonObject = new JsonObject(json);
message.setId(jsonObject.getString(JSON_MESSAGE_ID_ATTR));
message.setAuthor(jsonObject.getString(JSON_MESSAGE_AUTHOR_ATTR));
message.setSource(ChatMessageSource.fromString(jsonObject.getString(JSON_MESSAGE_SOURCE_ATTR)));
message.setAction(ChatMessageAction.fromString(jsonObject.getString(JSON_MESSAGE_ACTION_ATTR)));
message.setStatus(ChatMessageStatus.fromString(jsonObject.getString(JSON_MESSAGE_STATUS_ATTR)));
message.setContent(message.decodeContent(jsonObject.getString(JSON_MESSAGE_CONTENT_ATTR)));
return message;
}
/**
* Build the JSON representation of this ChatMessage.
*
* @return The JSON representation of this ChatMessage
*/
public JsonObject toJSON() { return getJSONObject(); }
/**
* Build the JSON representation of this ChatMessage. The given <code>ip</code> is used to determine who is the
* author of this message. If the IP of the message is equal to the given <code>ip</code> then the author is
* identified as <code>I</code> in the JSON representation.
*
* @param ip The IP address used to determine the author of this message.
* @return The JSON representation of this ChatMessage.
*/
public JsonObject toJSON(InetSocketAddress ip) {
JsonObject jsonObject = getJSONObject();
if(this.getIp() != null && this.getIp().equals(ip)) {
jsonObject.getJsonObject(JSON_MESSAGE_OBJECT).put(JSON_MESSAGE_AUTHOR_ATTR, "I");
}
return jsonObject;
}
/**
* Build the JsonObject associated to this ChatMessage. Only attributes of this ChatMessage that are not null are
* inserted in the JsonObject.
*
* @return The JSON object representing this ChatMessage.
*/
private JsonObject getJSONObject() {
JsonObject jsonMessage = new JsonObject();
if(getId() != null) jsonMessage.put(JSON_MESSAGE_ID_ATTR, getId());
if(getAuthor() != null) jsonMessage.put(JSON_MESSAGE_AUTHOR_ATTR, getAuthor());
if(getContent() != null) jsonMessage.put(JSON_MESSAGE_CONTENT_ATTR, encodeContent());
if(getSource() != null) jsonMessage.put(JSON_MESSAGE_SOURCE_ATTR, getSource().getAsString());
if(getAction() != null) jsonMessage.put(JSON_MESSAGE_ACTION_ATTR, getAction().getAsString());
if(getStatus() != null) jsonMessage.put(JSON_MESSAGE_STATUS_ATTR, getStatus().getAsString());
return jsonMessage;
}
}