package edu.washington.cs.oneswarm.f2f.messaging;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.commons.lang.Entities;
import org.apache.ecs.xml.XML;
import org.apache.ecs.xml.XMLDocument;
import org.gudy.azureus2.core3.util.DirectByteBuffer;
import org.gudy.azureus2.core3.util.DirectByteBufferPool;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import com.aelitis.azureus.core.peermanager.messaging.Message;
import com.aelitis.azureus.core.peermanager.messaging.MessageException;
public class OSF2FChat implements OSF2FMessage {
public static final String MESSAGE_ELEMENT = "message";
public static final String PLAIN_TEXT_ATTRIB = "plaintext";
private static final int MAX_LENGTH = 1024 * 2; // 2k of XML ought to be
// enough for anybody
private byte version;
private String plain_text_message = null;
private String description;
private DirectByteBuffer buffer = null;
private int mMessageSize = -1;
public OSF2FChat(byte _version, String plain_text_message) {
this.version = _version;
if (plain_text_message != null) {
if (plain_text_message.length() > MAX_LENGTH) {
plain_text_message = plain_text_message.substring(0, MAX_LENGTH);
}
}
this.plain_text_message = plain_text_message;
}
public Message deserialize(DirectByteBuffer data, byte version) throws MessageException {
if (data == null) {
throw new MessageException("[" + getID() + "] decode error: data == null");
}
int length = data.remaining(DirectByteBuffer.SS_MSG);
if (length > MAX_LENGTH) {
throw new MessageException("[" + getID()
+ "] decode error: message length greater than " + MAX_LENGTH + " (" + length
+ ")");
}
byte[] in = new byte[length];
data.get(DirectByteBuffer.SS_MSG, in);
try {
// to change: org.xml.sax.driver system property
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
DefaultHandler handler = new DefaultHandler() {
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals(MESSAGE_ELEMENT)) {
plain_text_message = Entities.XML.unescape(attributes
.getValue(PLAIN_TEXT_ATTRIB));
}
}
};
xmlReader.setContentHandler(handler);
xmlReader.parse(new InputSource(new ByteArrayInputStream(in)));
if (plain_text_message == null) {
throw new MessageException("[" + getID()
+ "] decode error: no plain text message after XML parsing");
}
} catch (SAXException e) {
throw new MessageException("[" + getID() + "] XML decode error: "
+ e.getClass().getName() + " / " + e.toString() + " bytes: " + (new String(in)));
} catch (IOException e) {
throw new MessageException("[" + getID() + "] XML decode error: "
+ e.getClass().getName() + " / " + e.toString() + " bytes: " + (new String(in)));
}
data.returnToPool();
return new OSF2FChat(version, plain_text_message);
}
public String getID() {
return OSF2FMessage.ID_OS_CHAT;
}
public byte[] getIDBytes() {
return OSF2FMessage.ID_OS_CHAT_BYTES;
}
public String getFeatureID() {
return OSF2FMessage.OS_FEATURE_ID;
}
public int getFeatureSubID() {
return OSF2FMessage.SUBID_OS_CHAT;
}
public int getType() {
return Message.TYPE_PROTOCOL_PAYLOAD;
}
public byte getVersion() {
return version;
};
public String getDescription() {
if (description == null) {
description = OSF2FMessage.ID_OS_CHAT + "\tchat=" + plain_text_message;
}
return description;
}
public void destroy() {
if (buffer != null) {
buffer.returnToPool();
buffer = null;
}
}
public DirectByteBuffer[] getData() {
if (buffer == null) {
XMLDocument doc = new XMLDocument();
doc.addElement(new XML(MESSAGE_ELEMENT).addXMLAttribute(PLAIN_TEXT_ATTRIB,
org.apache.commons.lang.Entities.XML.escape(plain_text_message)));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.output(baos);
byte[] output = baos.toByteArray();
buffer = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG, output.length + 4);
buffer.put(DirectByteBuffer.SS_MSG, output);
buffer.flip(DirectByteBuffer.SS_MSG);
mMessageSize = output.length;
}
return new DirectByteBuffer[] { buffer };
}
public String getPlainText() {
return plain_text_message;
}
public int getMessageSize() {
if (mMessageSize == -1) {
getData();
}
return mMessageSize;
}
public static final void main(String[] args) throws Exception {
OSF2FChat test = new OSF2FChat((byte) 1, "I sure like being inside this fancy computer.");
OSF2FChat parse = new OSF2FChat((byte) 1, null);
OSF2FChat test2 = (OSF2FChat) parse.deserialize(test.getData()[0], (byte) 1);
System.out.println(test.getPlainText() + " / " + test2.getPlainText());
}
}