/** * <pre> * copy right meidusa.com * * This program is free software; you can redistribute it and/or modify it under the terms of * the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU AFFERO GENERAL PUBLIC LICENSE for more details. * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program; * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * </pre> */ package com.meidusa.amoeba.net.packet; import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.nio.ByteBuffer; import org.apache.commons.lang.builder.ToStringBuilder; import com.meidusa.amoeba.net.Connection; /** * @author struct */ public abstract class AbstractPacket<T extends AbstractPacketBuffer> implements Packet { public void init(byte[] buffer, Connection conn) { T packetBuffer = constractorBuffer(buffer); packetBuffer.init(conn); init(packetBuffer); afterRead(packetBuffer); } /** * �������ݰ�(������ͷ+��������,�������ͷ�Ժ�Ӧ�ý�Buffer��postion���õ�������) */ protected void init(T buffer){ readHead(buffer); readBody(buffer); } protected void readHead(T buffer){ } protected void readBody(T buffer){ } /** * �����ʼ���Ժ� */ protected void afterRead(T buffer) { } public ByteBuffer toByteBuffer(Connection conn) { try { int bufferSize = calculatePacketSize(); T packetBuffer = constractorBuffer(bufferSize); packetBuffer.init(conn); return toBuffer(packetBuffer).toByteBuffer(); } catch (UnsupportedEncodingException e) { return null; } } private T constractorBuffer(int bufferSize) { T buffer = null; try { Constructor<T> constractor = getPacketBufferClass().getConstructor(int.class); buffer = constractor.newInstance(bufferSize); } catch (Exception e) { e.printStackTrace(); } return buffer; } /** * <pre> * �÷���������{@link #write2Buffer(PacketBuffer)} д�뵽ָ����buffer�� * ���ҵ�����{@link #afterPacketWritten(PacketBuffer)} * </pre> */ private T toBuffer(T buffer) throws UnsupportedEncodingException { write2Buffer(buffer); afterPacketWritten(buffer); return buffer; } /** * ����ͷ����Ϣ��װ */ protected void write2Buffer(T buffer) throws UnsupportedEncodingException{ writeHead(buffer); writeBody(buffer); } protected void writeBody(T buffer) throws UnsupportedEncodingException { } protected void writeHead(T buffer){ } /** * <pre> * д��֮��һ����Ҫ�������������buffer��ָ��λ��ָ��ĩβ����һ��λ�ã����ܳ���λ�ã��� * ���һ���Ǽ������ݰ��ܳ���,����������Ҫ���ݰ�д�������ɵ����� * </pre> */ protected abstract void afterPacketWritten(T buffer); /** * ����packet�Ĵ�С�������̫���˷��ڴ棬�����̫С��Ӱ������ */ protected abstract int calculatePacketSize(); private T constractorBuffer(byte[] buffer) { T packetbuffer = null; try { Constructor<T> constractor = getPacketBufferClass().getConstructor(byte[].class); packetbuffer = constractor.newInstance(buffer); } catch (Exception e) { e.printStackTrace(); } return packetbuffer; } protected abstract Class<T> getPacketBufferClass(); public String toString() { return ToStringBuilder.reflectionToString(this); } }