/*
* Copyright 2014 NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.navercorp.pinpoint.thrift.io;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TField;
import org.apache.thrift.protocol.TList;
import org.apache.thrift.protocol.TMap;
import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TSet;
import org.apache.thrift.protocol.TStruct;
/**
* Replace list field protocol.
*
* @author jaehong.kim
*/
public class TReplaceListProtocol extends TProtocol {
private boolean writeFieldBegin = false;
private int writeListDepth = 0;
private Map<String, List<ByteArrayOutput>> replaceFields = new HashMap<String, List<ByteArrayOutput>>();
private TField currentField = null;
private TProtocol protocol;
public TReplaceListProtocol(final TProtocol protocol) {
super(protocol.getTransport());
this.protocol = protocol;
}
public void addReplaceField(final String fieldName, List<ByteArrayOutput> outputs) {
if (fieldName == null) {
throw new IllegalArgumentException("field name must not be null");
}
if (outputs == null || outputs.isEmpty()) {
throw new IllegalArgumentException("stream nodes must not be empty");
}
replaceFields.put(fieldName, outputs);
}
@Override
public void writeFieldBegin(TField field) throws TException {
if (!writeFieldBegin) {
protocol.writeFieldBegin(field);
if (replaceFields.containsKey(field.name)) {
writeFieldBegin = true;
currentField = field;
}
}
}
@Override
public void writeFieldEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeFieldEnd();
} else if (writeListDepth == 0) {
writeFieldBegin = false;
currentField = null;
}
}
@Override
public void writeListBegin(TList list) throws TException {
if (!writeFieldBegin) {
protocol.writeListBegin(list);
return;
}
if (writeListDepth == 0 && currentField != null) {
List<ByteArrayOutput> outputs = replaceFields.get(currentField.name);
if (outputs == null) {
throw new TException("not found replace field - " + currentField.name);
}
final TList replaceList = new TList(list.elemType, outputs.size());
protocol.writeListBegin(replaceList);
for (ByteArrayOutput output : outputs) {
try {
final OutputStream out = ((ByteArrayOutputStreamTransport) getTransport()).getByteArrayOutputStream();
output.writeTo(out);
} catch (IOException e) {
throw new TException(e);
}
}
}
writeListDepth++;
}
@Override
public void writeListEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeListEnd();
} else {
writeListDepth--;
}
}
@Override
public void reset() {
protocol.reset();
}
@Override
public void writeMessageBegin(TMessage message) throws TException {
if (!writeFieldBegin) {
protocol.writeMessageBegin(message);
}
}
@Override
public void writeMessageEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeMessageEnd();
}
}
@Override
public void writeStructBegin(TStruct struct) throws TException {
if (!writeFieldBegin) {
protocol.writeStructBegin(struct);
}
}
@Override
public void writeStructEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeStructEnd();
}
}
@Override
public void writeFieldStop() throws TException {
if (!writeFieldBegin) {
protocol.writeFieldStop();
}
}
@Override
public void writeMapBegin(TMap map) throws TException {
if (!writeFieldBegin) {
protocol.writeMapBegin(map);
}
}
@Override
public void writeMapEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeMapEnd();
}
}
@Override
public void writeSetBegin(TSet set) throws TException {
if (!writeFieldBegin) {
protocol.writeSetBegin(set);
}
}
@Override
public void writeSetEnd() throws TException {
if (!writeFieldBegin) {
protocol.writeSetEnd();
}
}
@Override
public void writeBool(boolean b) throws TException {
if (!writeFieldBegin) {
protocol.writeBool(b);
}
}
@Override
public void writeByte(byte b) throws TException {
if (!writeFieldBegin) {
protocol.writeByte(b);
}
}
@Override
public void writeI16(short i16) throws TException {
if (!writeFieldBegin) {
protocol.writeI16(i16);
}
}
@Override
public void writeI32(int i32) throws TException {
if (!writeFieldBegin) {
protocol.writeI32(i32);
}
}
@Override
public void writeI64(long i64) throws TException {
if (!writeFieldBegin) {
protocol.writeI64(i64);
}
}
@Override
public void writeDouble(double dub) throws TException {
if (!writeFieldBegin) {
protocol.writeDouble(dub);
}
}
@Override
public void writeString(String str) throws TException {
if (!writeFieldBegin) {
protocol.writeString(str);
}
}
@Override
public void writeBinary(ByteBuffer bin) throws TException {
if (!writeFieldBegin) {
protocol.writeBinary(bin);
}
}
@Override
public ByteBuffer readBinary() throws TException {
throw new TException("unsupported operation");
}
@Override
public boolean readBool() throws TException {
throw new TException("unsupported operation");
}
@Override
public byte readByte() throws TException {
throw new TException("unsupported operation");
}
@Override
public double readDouble() throws TException {
throw new TException("unsupported operation");
}
@Override
public TField readFieldBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readFieldEnd() throws TException {
throw new TException("unsupported operation");
}
@Override
public short readI16() throws TException {
throw new TException("unsupported operation");
}
@Override
public int readI32() throws TException {
throw new TException("unsupported operation");
}
@Override
public long readI64() throws TException {
throw new TException("unsupported operation");
}
@Override
public TList readListBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readListEnd() throws TException {
throw new TException("unsupported operation");
}
@Override
public TMap readMapBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readMapEnd() throws TException {
throw new TException("unsupported operation");
}
@Override
public TMessage readMessageBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readMessageEnd() throws TException {
throw new TException("unsupported operation");
}
@Override
public TSet readSetBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readSetEnd() throws TException {
throw new TException("unsupported operation");
}
@Override
public String readString() throws TException {
throw new TException("unsupported operation");
}
@Override
public TStruct readStructBegin() throws TException {
throw new TException("unsupported operation");
}
@Override
public void readStructEnd() throws TException {
throw new TException("unsupported operation");
}
}