package com.jenjinstudios.core;
import com.jenjinstudios.core.io.Message;
import com.jenjinstudios.core.io.MessageInputStream;
import com.jenjinstudios.core.io.MessageOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Used to contain a {@code MessageInputStream} and {@code MessageOutputStream}.
*
* @author Caleb Brinkman
*/
public class MessageIO
{
private static final Logger LOGGER = Logger.getLogger(MessageIO.class.getName());
private final MessageInputStream in;
private final MessageOutputStream out;
private final InetAddress address;
private final LinkedList<Message> outgoingMessages;
/**
* Construct a new {@code MessageIO} from the given message input and output streams.
*
* @param in The input stream.
* @param out The output stream.
*/
public MessageIO(MessageInputStream in, MessageOutputStream out) { this(in, out, null); }
/**
* Construct a new {@code MessageIO} from the given message input and output streams.
*
* @param in The input stream.
* @param out The output stream.
* @param address The Internet Address of the complementary connection.
*/
public MessageIO(MessageInputStream in, MessageOutputStream out, InetAddress address) {
this.in = in;
this.out = out;
this.address = address;
outgoingMessages = new LinkedList<>();
}
/**
* Get the address of the complementary connection, if it exists. Returns null if no address is known.
*
* @return The address of the complementary connection, null if unknown.
*/
public InetAddress getAddress() { return address; }
/**
* Get the {@code MessageInputStream} managed by this {@code MessageIO}.
*
* @return The {@code MessageInputStream} managed by this {@code MessageIO}.
*/
MessageInputStream getIn() { return in; }
/**
* Get the {@code MessageOutputStream} managed by this {@code MessageIO}.
*
* @return The {@code MessageOutputStream} managed by this {@code MessageIO}.
*/
public MessageOutputStream getOut() { return out; }
/**
* Add the specified {@code Message} to the queue of outgoing messages. This queue is written when {@code
* writeAllMessages} is called.
*
* @param message The {@code Message} to write.
*/
public void queueOutgoingMessage(Message message) {
if (out.isClosed())
{
throw new MessageQueueException(message);
}
synchronized (outgoingMessages)
{
outgoingMessages.add(message);
}
}
/**
* Write all the messages in the outgoing messages queue to the output stream.
*
* @throws java.io.IOException If there is an exception writing a message to the output stream.
*/
public void writeAllMessages() throws IOException {
synchronized (outgoingMessages)
{
while (!outgoingMessages.isEmpty())
{
out.writeMessage(outgoingMessages.remove());
}
}
}
void closeOutputStream() {
try
{
out.close();
} catch (IOException e)
{
LOGGER.log(Level.INFO, "Error closing output stream.", e);
}
}
void closeInputStream() {
try
{
in.close();
} catch (IOException e)
{
LOGGER.log(Level.INFO, "Error closing input stream.", e);
}
}
}