package com.cardshifter.core.messages;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import net.zomis.cardshifter.ecs.usage.CardshifterIO;
import com.cardshifter.api.ClientIO;
import com.cardshifter.api.messages.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
/**
* Handles incoming messages from clients in JSON format. For example: <code>{ "command": "something", "parameter": "example" }</code>
* @author Simon Forsberg
*
*/
public class IncomingHandler {
private final Map<Class<?>, MessageHandler<?>> consumer;
private final ObjectMapper mapper;
private final ObjectReader reader;
public IncomingHandler() {
this.consumer = new ConcurrentHashMap<>();
mapper = CardshifterIO.mapper();
reader = mapper.reader(Message.class);
}
/**
* Add the ability to parse a class. This causes commands passed to {@link #parse(String)} to be parsed as the specified class
*
* @see #parse(String)
*
* @param command Command-identifier to be supplied to the 'command' JSON parameter.
* @param handler The class to associate with this command identifier
*/
public <E extends Message> void addHandler(String command, Class<E> handler, MessageHandler<E> consumer) {
this.consumer.put(handler, consumer);
}
/**
* Parse a JSON request
*
* @param json JSON String to parse, formatted as <code>{ "command": "something", "parameter": "example" }</code>
* @return A subclass of {@link Message} that is associated with the command identifier
* @throws IOException If there was a problem parsing the JSON
*/
public <T extends Message> T parse(String json) throws IOException {
return reader.readValue(json);
}
public <E extends Message> void perform(E message, ClientIO client) {
@SuppressWarnings("unchecked")
MessageHandler<E> messagePerform = (MessageHandler<E>) this.consumer.get(message.getClass());
if (messagePerform == null) {
throw new NullPointerException("No handler for message " + message + " of class " + message.getClass());
}
messagePerform.handle(message, client);
}
}