SVFormat.java 5.41 KiB
package tap.formatter;
/*
* This file is part of TAPLibrary.
*
* TAPLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TAPLibrary 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TAPLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2012 - UDS/Centre de Données astronomiques de Strasbourg (CDS)
*/
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import cds.savot.writer.SavotWriter;
import adql.db.DBColumn;
import tap.ServiceConnection;
import tap.TAPException;
import tap.TAPExecutionReport;
public abstract class SVFormat< R > implements OutputFormat<R> {
/** Indicates whether a format report (start and end date/time) must be printed in the log output. */
private boolean logFormatReport;
public static final char COMMA_SEPARATOR = ',';
public static final char SEMI_COLON_SEPARATOR = ';';
public static final char TAB_SEPARATOR = '\t';
protected final ServiceConnection<R> service;
protected final String separator;
protected final boolean delimitStr;
public SVFormat(final ServiceConnection<R> service, char colSeparator){
this(service, colSeparator, true);
}
public SVFormat(final ServiceConnection<R> service, char colSeparator, boolean delimitStrings){
this(service, colSeparator, delimitStrings, false);
}
public SVFormat(final ServiceConnection<R> service, char colSeparator, boolean delimitStrings, final boolean logFormatReport){
separator = "" + colSeparator;
delimitStr = delimitStrings;
this.service = service;
this.logFormatReport = logFormatReport;
}
public SVFormat(final ServiceConnection<R> service, String colSeparator){
this(service, colSeparator, true);
}
public SVFormat(final ServiceConnection<R> service, String colSeparator, boolean delimitStrings){
separator = (colSeparator == null) ? ("" + COMMA_SEPARATOR) : colSeparator;
delimitStr = delimitStrings;
this.service = service;
}
public String getMimeType(){
switch(separator.charAt(0)){
case COMMA_SEPARATOR:
case SEMI_COLON_SEPARATOR:
return "text/csv";
case TAB_SEPARATOR:
return "text/tsv";
default:
return "text/plain";
}
}
public String getShortMimeType(){
switch(separator.charAt(0)){
case COMMA_SEPARATOR:
case SEMI_COLON_SEPARATOR:
return "csv";
case TAB_SEPARATOR:
return "tsv";
default:
return "text";
}
}
public String getDescription(){
return null;
}
public String getFileExtension(){
switch(separator.charAt(0)){
case COMMA_SEPARATOR:
case SEMI_COLON_SEPARATOR:
return "csv";
case TAB_SEPARATOR:
return "tsv";
default:
return "txt";
}
}
@Override
public void writeResult(R queryResult, OutputStream output, TAPExecutionReport execReport, Thread thread) throws TAPException, InterruptedException{
try{
final long startTime = System.currentTimeMillis();
final PrintWriter writer = new PrintWriter(output);
// Write header:
DBColumn[] columns = writeMetadata(queryResult, writer, execReport, thread);
// Write data:
int nbRows = writeData(queryResult, columns, writer, execReport, thread);
writer.flush();
if (logFormatReport)
service.getLogger().info("JOB " + execReport.jobID + " WRITTEN\tResult formatted (in SV[" + delimitStr + "] ; " + nbRows + " rows ; " + columns.length + " columns) in " + (System.currentTimeMillis() - startTime) + " ms !");
}catch(Exception ex){
service.getLogger().error("While formatting in (T/C)SV !", ex);
}
}
protected abstract DBColumn[] writeMetadata(R queryResult, PrintWriter writer, TAPExecutionReport execReport, Thread thread) throws IOException, TAPException, InterruptedException;
protected abstract int writeData(R queryResult, DBColumn[] selectedColumns, PrintWriter writer, TAPExecutionReport execReport, Thread thread) throws IOException, TAPException, InterruptedException;
/**
* <p>Writes the given field value in the given OutputStream.</p>
*
* <p>
* The given value will be encoded as an XML element (see {@link SavotWriter#encodeElement(String)}.
* Besides, if the given value is <code>null</code> and if the column datatype is <code>int</code>,
* <code>short</code> or <code>long</code>, the NULL values declared in the field metadata will be written.</p>
*
* @param value The value to write.
* @param column The corresponding column metadata.
* @param out The stream in which the field value must be written.
*
* @throws IOException If there is an error while writing the given field value in the given stream.
* @throws TAPException If there is any other error (by default: never happen).
*/
protected void writeFieldValue(final Object value, final DBColumn column, final PrintWriter writer) throws IOException, TAPException{
if (value != null){
if ((delimitStr && value instanceof String) || value.toString().contains(separator)){
writer.print('"');
writer.print(value.toString().replaceAll("\"", "'"));
writer.print('"');
}else
writer.print(value.toString());
}
}
}