package org.rzo.netty.ahessian.rpc.message;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.rzo.netty.ahessian.Constants;
import org.rzo.netty.ahessian.io.InputStreamConsumer;
import org.rzo.netty.ahessian.io.InputStreamDecoder;
import org.rzo.netty.ahessian.io.OutputStreamEncoder;
import org.rzo.netty.ahessian.rpc.io.Hessian2Input;
import org.rzo.netty.ahessian.rpc.server.HessianRPCServiceHandler;
import org.rzo.netty.ahessian.session.ServerSessionFilter;
import com.caucho.hessian4.io.AbstractSerializerFactory;
import com.caucho.hessian4.io.SerializerFactory;
/**
* Decodes a call request from an input stream
*/
public class HessianRPCCallDecoder implements InputStreamConsumer, Constants
{
/** The _factory. */
HessianRPCServiceHandler _factory;
SerializerFactory sFactory = new SerializerFactory();
volatile Hessian2Input in = null;
public HessianRPCCallDecoder()
{
super();
}
public HessianRPCCallDecoder(AbstractSerializerFactory serializerFactory)
{
super();
if (serializerFactory != null)
sFactory.addFactory(serializerFactory);
}
public void consume(ChannelHandlerContext ctx, InputStream inx)
{
HessianRPCCallMessage result = null;
boolean getNextMessage = true;
if (in == null || in.isClosed() || in.getInputStream() != inx)
{
in = new Hessian2Input(inx);
in.setSerializerFactory(sFactory);
}
while (ctx.getChannel().isConnected() && getNextMessage)
{
try
{
if (in.bufferEmpty())
{
// we have nothing to parse
break;
}
int ch;
if ((ch=in.read()) != 'H')
{
ahessianLogger.warn("H expected got " + "0x" + Integer.toHexString(ch & 0xff) + " (" + (char) + ch + ")");
continue;
}
in.read();
in.read();
in.readEnvelope();
String h = in.readString();
if (!HEADER_STRING.equals(h))
{
ahessianLogger.warn("missing header");
continue;
}
Map<Object, Object> headers = new HashMap<Object, Object>();
String methodName = null;
List values = new ArrayList();
int l = in.readInt();
for (int i=0; i<l; i++)
{
Integer key = in.readInt();
Object value = in.readObject();
headers.put(key, value);
}
in.readCall();
methodName = in.readMethod();
int argsLength = in.readInt();
for (int i=0; i<argsLength; i++)
values.add(in.readObject());
in.completeCall();
in.completeEnvelope();
in.resetReferences();
result = new HessianRPCCallMessage(methodName, values.toArray(), headers, (OutputStreamEncoder) OutputStreamEncoder.getOutputEncoder(ctx));
result.setServer(true);
result.setHasSessionFilter((Boolean) headers.get(HAS_SESSION_FILTER_HEADER_KEY));
result.setSession(ServerSessionFilter.getSession(ctx));
}
catch (Exception ex)
{
Constants.ahessianLogger.warn("", ex);
result = null;
}
if (in.bufferEmpty())
{
getNextMessage = false;
}
if (result != null)
Channels.fireMessageReceived(ctx, result);
}
}
public boolean isBufferEmpty()
{
return in != null && in.bufferEmpty();
}
public void setContext(ChannelHandlerContext ctx)
{
if (in == null)
{
in = new Hessian2Input(InputStreamDecoder.getInputStream(ctx));
in.setSerializerFactory(sFactory);
}
}
}