001/*
002 * (C) Copyright 2018 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     pierre
018 */
019package org.nuxeo.ecm.core.io.marshallers.csv;
020
021import java.io.IOException;
022import java.io.OutputStream;
023import java.io.OutputStreamWriter;
024import java.lang.reflect.Type;
025import java.util.Calendar;
026import java.util.GregorianCalendar;
027
028import javax.inject.Inject;
029import javax.ws.rs.core.MediaType;
030
031import org.apache.commons.csv.CSVFormat;
032import org.apache.commons.csv.CSVPrinter;
033import org.nuxeo.ecm.core.io.registry.MarshallerRegistry;
034import org.nuxeo.ecm.core.io.registry.Writer;
035import org.nuxeo.ecm.core.io.registry.context.RenderingContext;
036import org.nuxeo.ecm.core.io.registry.reflect.Supports;
037import org.nuxeo.ecm.core.schema.SchemaManager;
038
039/**
040 * Base class for CSV {@link Writer}.
041 * </p>
042 * It provides you a {@link CSVPrinter} to manage the marshalling.
043 *
044 * @param <T> The Java type to marshall as CSV.
045 * @since 10.3
046 */
047@Supports(AbstractCSVWriter.TEXT_CSV)
048public abstract class AbstractCSVWriter<T> implements Writer<T> {
049
050    public static final String TEXT_CSV = "text/csv";
051
052    public static final MediaType TEXT_CSV_TYPE = new MediaType("text", "csv");
053
054    /**
055     * The current {@link RenderingContext}.
056     */
057    @Inject
058    protected RenderingContext ctx;
059
060    @Inject
061    protected SchemaManager schemaManager;
062
063    @Inject
064    protected MarshallerRegistry registry;
065
066    @Override
067    public boolean accept(Class<?> clazz, Type genericType, MediaType mediatype) {
068        return TEXT_CSV_TYPE.equals(mediatype);
069    }
070
071    @Override
072    public void write(T entity, Class<?> clazz, Type genericType, MediaType mediatype, OutputStream out)
073            throws IOException {
074        CSVPrinter printer = getCSVPrinter(entity, out);
075        write(entity, printer);
076        printer.flush();
077    }
078
079    protected abstract void write(T entity, CSVPrinter printer) throws IOException;
080
081    protected abstract void writeHeader(T entity, CSVPrinter printer) throws IOException;
082
083    protected CSVPrinter getCSVPrinter(T entity, OutputStream out) throws IOException {
084        CSVPrinter printer;
085        if (out instanceof OutputStreamWithCSVWriter) {
086            OutputStreamWithCSVWriter oscsv = (OutputStreamWithCSVWriter) out;
087            if (oscsv.getCsvPrinter() != null) {
088                return oscsv.getCsvPrinter();
089            } else {
090                printer = new CSVPrinter(new StringBuilder(), CSVFormat.DEFAULT);
091                oscsv.setCSVPrinter(printer);
092            }
093        } else {
094            printer = new CSVPrinter(new OutputStreamWriter(out), CSVFormat.DEFAULT);
095        }
096        writeHeader(entity, printer);
097        return printer;
098    }
099
100    protected void printCalendar(Calendar value, CSVPrinter printer) throws IOException {
101        if (value != null) {
102            printer.print(((GregorianCalendar) value).toZonedDateTime());
103        } else {
104            printer.print(null);
105        }
106    }
107
108}