/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.monitor.rest;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.geoserver.monitor.Monitor;
import org.geoserver.monitor.RequestData;
import org.geoserver.monitor.RequestDataVisitor;
import org.geoserver.ows.util.OwsUtils;
import org.geotools.feature.type.DateUtil;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.stereotype.Component;
/**
* Convert MonitorResutls to a csv file.
*/
@Component
public class CSVMonitorConverter extends BaseMonitorConverter {
static Pattern ESCAPE_REQUIRED = Pattern.compile("[\\,\\s\"]");
private static final class CSVRequestDataVisitor implements RequestDataVisitor {
private BufferedWriter writer;
private String[] fields;
CSVRequestDataVisitor( BufferedWriter writer, String fields[]){
this.writer = writer;
this.fields = fields;
}
@Override
public void visit(RequestData data, Object... aggregates) {
try {
StringBuffer sb = new StringBuffer();
for (String fld : fields) {
Object val = OwsUtils.get(data, fld);
if (val instanceof Date) {
val = DateUtil.serializeDateTime((Date) val);
}
if (val != null) {
String string = val.toString();
Matcher match = ESCAPE_REQUIRED.matcher(string);
if (match.find()) { // may need escaping, so escape
string = string.replaceAll("\"", "\"\"");// Double all double quotes to escape
sb.append("\"");
sb.append(string);
sb.append("\"");
} else { // No need for escaping
sb.append(string);
}
}
sb.append(",");
}
sb.setLength(sb.length() - 1); // Remove trailing comma
sb.append("\n");
writer.write(sb.toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public CSVMonitorConverter() {
super(MonitorRequestController.CSV_MEDIATYPE);
}
@Override
protected void writeInternal(MonitorQueryResults results, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
Object result = results.getResult();
String[] fields = results.getFields();
Monitor monitor = results.getMonitor();
OutputStream os = outputMessage.getBody();
writeCSVfile(result, fields, monitor, os);
}
/**
* Write CSV file (also called by {@link ZIPMonitorConverter}
* @param result Query, List or individual RequestData)
* @param fields
* @param monitor used to cancel output process
* @param os Output stream (not closed by this method allowing use of zipfile)
*/
void writeCSVfile(Object result, String[] fields, Monitor monitor, OutputStream os)
throws IOException {
final BufferedWriter w = new BufferedWriter(new OutputStreamWriter(os));
// write out the header
StringBuffer sb = new StringBuffer();
for (String fld : fields) {
sb.append(fld).append(",");
}
sb.setLength(sb.length() - 1);
w.write(sb.append("\n").toString());
handleRequests(result, new CSVRequestDataVisitor(w, fields), monitor);
w.flush();
}
}