package iitb.con.ds;
import iitb.con.core.Attribute;
import iitb.con.core.Entity;
import iitb.con.core.Relation;
import iitb.con.core.Type;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
public class TypeSerializer implements ItemSerializer<Type> {
public ByteBuffer serialize(Type type) {
int typeElementSize = computeSize(type);
ByteBuffer buf = ByteBuffer.allocate(typeElementSize);
buf.putInt(typeElementSize);
if(type instanceof Entity) {
buf.put((byte)0); }else {
Relation r = (Relation) type;
buf.put((byte)1); buf.putShort(r.getLeftEntityId()); buf.putShort(r.getRightEntityId()); buf.put(r.getDirection()); if(r.leftRole != null) {
buf.putShort((short) r.leftRole.length()); buf.put(r.leftRole.getBytes()); }else{
buf.putShort((short)0); }
if(r.rightRole != null) {
buf.putShort((short) r.rightRole.length()); buf.put(r.rightRole.getBytes()); }else{
buf.putShort((short)0); }
}
buf.putShort(type.id); buf.putShort((short) type.name.length()); buf.put(type.name.getBytes());
buf.putShort((short)type.getAttributesCount());
List<Attribute> attributes = type.getAllAttributes();
for(Attribute attribute : attributes) {
buf.putShort(attribute.id);
if(attribute.repeating)
buf.put((byte)1);
else
buf.put((byte)0);
buf.put(attribute.dataType);
buf.putShort((short)attribute.name.length());
buf.put(attribute.name.getBytes());
if(attribute.defaultValue != null) {
buf.putShort((short)attribute.defaultValue.length());
buf.put(attribute.defaultValue.getBytes());
}else{
buf.putShort((short)0);
}
}
buf.rewind();
return buf;
}
public Type deSerialize(ByteBuffer buf) {
Type type = null;
buf.getInt(); Byte b = buf.get();
if(b == 0) { type = deSerializeEntityType(buf);
}else {
type = deSerializeRelationType(buf);
}
return type;
}
public Object attributeDeSerialize(ByteBuffer buf, Object name) {
return null;
}
private Type deSerializeEntityType(ByteBuffer buf) {
Entity type = new Entity("");
type.id = buf.getShort();
short size = buf.getShort();
byte[] tempBuf = new byte[size];
buf.get(tempBuf);
type.name = new String(tempBuf);
type.setAllAttributes(deSerializeAttributes(buf));
return type;
}
private Type deSerializeRelationType(ByteBuffer buf) {
Relation type = new Relation("");
type.setLeftEntityId(buf.getShort());
type.setRightEntityId(buf.getShort());
type.setDirection(buf.get());
short size = buf.getShort();
byte[] tempBuf = new byte[size];
buf.get(tempBuf);
type.leftRole = new String(tempBuf);
size = buf.getShort();
tempBuf = new byte[size];
buf.get(tempBuf);
type.rightRole = new String(tempBuf);
type.id = buf.getShort();
size = buf.getShort();
tempBuf = new byte[size];
buf.get(tempBuf);
type.name = new String(tempBuf);
type.setAllAttributes(deSerializeAttributes(buf));
return type;
}
private List<Attribute> deSerializeAttributes(ByteBuffer buf) {
short attribute_count = buf.getShort();
List<Attribute> attributes = new ArrayList<Attribute>();
for(short i = 0; i < attribute_count ; i++ ) {
Attribute attribute = new Attribute();
attribute.id = buf.getShort();
if (buf.get() == 0)
attribute.repeating = false;
else
attribute.repeating = true;
attribute.dataType = buf.get();
short size = buf.getShort();
byte[] tempBuf = new byte[size];
buf.get(tempBuf);
attribute.name = new String(tempBuf);
size = buf.getShort();
if(size > 0) {
tempBuf = new byte[size];
buf.get(tempBuf);
attribute.defaultValue = new String(tempBuf);
}
attributes.add(attribute);
}
return attributes;
}
private int computeSize(Type type) {
int size = 0;
size += 2;
short attributeStaticHeaderSize = 9;
List<Attribute> attributes = type.getAllAttributes();
for(Attribute attribute : attributes) {
size += attribute.name.length();
if(attribute.defaultValue !=null)
size += attribute.defaultValue.length();
size += attributeStaticHeaderSize;
}
size += 4;
size += type.name.length();
if(type instanceof Entity) {
size++; }else {
Relation r = (Relation) type;
size += 10;
if(r.leftRole != null)
size += r.leftRole.length();
if(r.rightRole != null)
size += r.rightRole.length();
}
size += 4;
return size;
}
}