/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.eas.client.threetier.platypus;
import com.eas.client.threetier.Response;
import com.eas.proto.CoreTags;
import com.eas.proto.ProtoReader;
import com.eas.proto.ProtoUtil;
import java.io.InputStream;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
/**
*
* @author mg
*/
public class ResponseDecoder extends CumulativeProtocolDecoder {
@Override
public boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
boolean ordinaryResponse = false;
boolean errorResponse = false;
boolean data = false;
int start = in.position();
int tag, tagSize;
String ticket = null;
do {
if (in.remaining() < 5) {
in.position(start);
return false;
}
tag = in.get() & 0xff;
tagSize = in.getInt();
if (in.remaining() < tagSize) {
in.position(start);
return false;
} else if (tag == RequestsTags.TAG_RESPONSE) {
ordinaryResponse = true;
} else if (tag == RequestsTags.TAG_ERROR_RESPONSE
|| tag == RequestsTags.TAG_SQL_ERROR_RESPONSE
|| tag == RequestsTags.TAG_JSON_ERROR_RESPONSE
|| tag == RequestsTags.TAG_ACCESS_CONTROL_ERROR_RESPONSE) {
errorResponse = true;
} else if (tag == CoreTags.TAG_SESSION_TICKET) {
byte[] ticketBuf = new byte[tagSize];
in.get(ticketBuf);
ticket = new String(ticketBuf, ProtoUtil.CHARSET_4_STRING_SERIALIZATION_NAME);
} else if (tag == RequestsTags.TAG_RESPONSE_DATA) {
data = true;
} else {
in.skip(tagSize);
}
} while (tag != RequestsTags.TAG_RESPONSE_END);
if (!ordinaryResponse && !errorResponse) {
throw new IllegalStateException("Responses should contain ordinary response marker or some error response marker tag");
}
if (!data) {
throw new IllegalStateException("Responses should contain response data tag");
}
RequestEnvelope requestEnv = (RequestEnvelope) session.getAttribute(RequestEnvelope.class.getSimpleName());
requestEnv.ticket = ticket;
int position = in.position();
int limit = in.limit();
try {
in.position(start);
in.limit(position);
try (InputStream is = in.slice().asInputStream()) {
ProtoReader responseReader = new ProtoReader(is);
Response response = PlatypusResponseReader.read(responseReader, requestEnv.request);
out.write(response);
}
return true;
} finally {
in.position(position);
in.limit(limit);
}
}
}