/**
*
*/
package vnet.sms.gateway.transports.serialization;
import static org.apache.commons.lang.Validate.notNull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream;
import org.jboss.netty.handler.codec.serialization.ObjectEncoderOutputStream;
import vnet.sms.common.messages.GsmPdu;
/**
* @author obergner
*
*/
public final class ReferenceableMessageContainer implements Serializable {
private static final long serialVersionUID = -278633444989175439L;
public static final ReferenceableMessageContainer wrap(
final int messageReference, final GsmPdu gsmPdu) {
return new ReferenceableMessageContainer(messageReference, gsmPdu);
}
public static final ReferenceableMessageContainer decode(
final ChannelBuffer channelBuffer) {
try {
notNull(channelBuffer, "Argument 'channelBuffer' must not be null");
final byte[] serializedForm = new byte[channelBuffer
.readableBytes()];
channelBuffer.getBytes(0, serializedForm);
final Object message = new ObjectDecoderInputStream(
new ByteArrayInputStream(serializedForm)).readObject();
if (!ReferenceableMessageContainer.class.isInstance(message)) {
return null;
}
return ReferenceableMessageContainer.class.cast(message);
} catch (final Exception e) {
throw new RuntimeException("Failed to decode [" + channelBuffer
+ "]: " + e.getMessage(), e);
}
}
private final int messageReference;
private final GsmPdu gsmPdu;
private ReferenceableMessageContainer(final int messageReference,
final GsmPdu gsmPdu) {
notNull(gsmPdu, "Argument 'gsmPdu' must not be null");
this.messageReference = messageReference;
this.gsmPdu = gsmPdu;
}
public int getMessageReference() {
return this.messageReference;
}
public GsmPdu getMessage() {
return this.gsmPdu;
}
public <M extends GsmPdu> M getMessage(final Class<M> expectedType)
throws IllegalArgumentException {
if (!expectedType.isInstance(this.gsmPdu)) {
throw new IllegalArgumentException(
"Contained gsmPdu is not of expected type "
+ expectedType.getName() + " but of type "
+ this.gsmPdu.getClass().getName());
}
return expectedType.cast(this.gsmPdu);
}
public ChannelBuffer encode() {
ObjectEncoderOutputStream oos = null;
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
oos = new ObjectEncoderOutputStream(baos);
oos.writeObject(this);
oos.flush();
return ChannelBuffers.copiedBuffer(baos.toByteArray());
} catch (final IOException e) {
throw new RuntimeException("Failed to serialize [" + this + "]: "
+ e.getMessage(), e);
} finally {
if (oos != null) {
try {
oos.close();
} catch (final IOException e) {
// Ignore
}
}
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((this.gsmPdu == null) ? 0 : this.gsmPdu.hashCode());
result = prime * result + this.messageReference;
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ReferenceableMessageContainer other = (ReferenceableMessageContainer) obj;
if (this.gsmPdu == null) {
if (other.gsmPdu != null) {
return false;
}
} else if (!this.gsmPdu.equals(other.gsmPdu)) {
return false;
}
if (this.messageReference != other.messageReference) {
return false;
}
return true;
}
@Override
public String toString() {
return "ReferenceableMessageContainer@" + hashCode()
+ " [messageReference: " + this.messageReference + "|gsmPdu: "
+ this.gsmPdu + "]";
}
}