package com.netifera.platform.internal.dispatcher.channels;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.net.SocketException;
import com.netifera.platform.api.channels.ChannelException;
import com.netifera.platform.api.channels.IChannelMessageSerializer;
import com.netifera.platform.api.channels.IChannelTransport;
import com.netifera.platform.api.dispatcher.IProbeMessage;
import com.netifera.platform.api.dispatcher.ProbeMessage;
import com.netifera.platform.api.log.ILogger;
import com.netifera.platform.dispatcher.channels.ChannelEOFException;
public class ChannelMessageSerializer implements IChannelMessageSerializer {
private boolean isClosed;
public static ChannelMessageSerializer createServerSerializer(IChannelTransport transport, ILogger logger) throws IOException {
logger.debug("Initializing new server object serializer");
final ObjectInputStream in = new ObjectInputStream(transport.getInputStream());
final ObjectOutputStream out = new ObjectOutputStream(transport.getOutputStream());
return new ChannelMessageSerializer(in, out, logger);
}
public static ChannelMessageSerializer createClientSerializer(IChannelTransport transport, ILogger logger) throws IOException {
logger.debug("Initializing new client object serializer");
final ObjectOutputStream out = new ObjectOutputStream(transport.getOutputStream());
final ObjectInputStream in = new ObjectInputStream(transport.getInputStream());
return new ChannelMessageSerializer(in, out, logger);
}
private final ObjectOutputStream objectOutStream;
private final ObjectInputStream objectInStream;
private final ILogger logger;
private ChannelMessageSerializer(ObjectInputStream in, ObjectOutputStream out, ILogger logger) {
this.objectInStream = in;
this.objectOutStream = out;
this.logger = logger;
}
public ProbeMessage readMessage() throws ChannelException {
try {
return readObject();
} catch(ObjectStreamException e) {
logger.error("ObjectStreamException reading from input stream ", e);
throw new ChannelException("Disconnecting on channel error");
} catch(EOFException e) {
throw new ChannelEOFException();
} catch(SocketException e) {
throw new ChannelEOFException();
} catch(IOException e) {
logger.error("IOException reading probe message from channel", e);
throw new ChannelException("Error reading from channel", e);
} catch(ClassNotFoundException e) {
logger.error("Class not found exception reading probe message", e);
throw new ChannelException("Error reading from channel", e);
} catch (Exception e) {
logger.error("Unexpected exception reading from channel", e);
throw new ChannelException("Unexpected error reading from channel", e);
}
}
private ProbeMessage readObject() throws Exception {
Object o = objectInStream.readObject();
if(o instanceof ProbeMessage) {
return (ProbeMessage)o;
}
logger.error("Unexpected object type reading from channel: " + o.getClass().getName());
throw new ChannelException("Wrong object type read from channel " + o.getClass().getName());
}
public void sendMessage(IProbeMessage message) throws ChannelException {
try {
objectOutStream.reset();
objectOutStream.writeObject(message);
} catch(ObjectStreamException e) {
logger.error("ObjectStreamException writing to channel", e);
throw new ChannelException("Disconnecting on channel error");
} catch (IOException e) {
logger.error("IOException on channel write");
throw new ChannelException("Disconnecting on channel error");
}
}
public synchronized void close() {
if(isClosed)
return;
isClosed = true;
try {
objectInStream.close();
} catch (IOException e) {
logger.warning("Closing channel input object stream failed", e);
}
try {
objectOutStream.close();
} catch (IOException e) {
logger.warning("Closing channel output object stream failed", e);
}
}
}