/*
* 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.addthis.hydra.task.output;
import java.io.IOException;
import java.io.OutputStream;
import com.addthis.basis.util.LessBytes;
import com.addthis.basis.util.LessStrings;
import com.addthis.bundle.core.Bundle;
import com.addthis.bundle.core.BundleField;
import com.addthis.bundle.core.BundleFormat;
import com.addthis.bundle.util.ValueUtil;
import com.addthis.codec.annotations.FieldConfig;
import com.addthis.codec.codables.SuperCodable;
import com.addthis.hydra.data.filter.value.StringFilter;
/**
* Token Separated Column Values
*
* @user-reference
*/
public class OutputStreamColumnized extends OutputStreamFormatter implements SuperCodable {
@FieldConfig(codable = true, required = true)
private String[] columns;
@FieldConfig(codable = true)
private String stringQuote;
@FieldConfig(codable = true)
private String separator = "\t";
@FieldConfig(codable = true)
private String eol = "\n";
@FieldConfig(codable = true)
private StringFilter filter;
@FieldConfig(codable = true)
private String nameSeparator;
private byte[] sepB;
private byte[] stqB;
private byte[] eolB;
@Override
public void open() {
}
@Override
public OutputStreamEmitter createEmitter() {
return new TokenOut();
}
private class TokenOut extends OutputStreamEmitter {
private BundleFormat format;
private BundleField[] fields;
@Override
public void write(OutputStream out, Bundle row) throws IOException {
BundleFormat rowFormat = row.getFormat();
if (fields == null || rowFormat != format) {
BundleField[] newFields = new BundleField[columns.length];
for (int i = 0; i < columns.length; i++) {
newFields[i] = rowFormat.getField(columns[i]);
}
fields = newFields;
format = rowFormat;
}
int rowlen = fields.length;
for (int i = 0; i < rowlen; i++) {
String val = ValueUtil.asNativeString(row.getValue(fields[i]));
if (filter != null) {
val = filter.filter(val);
}
if (!LessStrings.isEmpty(val)) {
if (nameSeparator != null) {
val = fields[i].getName() + nameSeparator + val;
}
if (stringQuote != null && val.indexOf(separator) >= 0) {
out.write(stqB);
out.write(LessBytes.toBytes(val));
out.write(stqB);
} else {
out.write(LessBytes.toBytes(val));
}
}
if (i < rowlen - 1) {
out.write(sepB);
}
}
out.write(eolB);
}
@Override
public void flush(OutputStream out) throws IOException {
out.flush();
}
}
@Override
public void postDecode() {
sepB = separator != null ? LessBytes.toBytes(separator) : null;
stqB = stringQuote != null ? LessBytes.toBytes(stringQuote) : null;
eolB = LessBytes.toBytes(eol);
}
@Override
public void preEncode() {
}
}