001/* 
002 * Copyright 2018 Leibniz-Institut für Analytische Wissenschaften – ISAS – e.V..
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 */
016package de.isas.mztab2.io;
017
018import com.fasterxml.jackson.core.JsonProcessingException;
019import com.fasterxml.jackson.dataformat.csv.CsvMapper;
020import com.fasterxml.jackson.dataformat.csv.CsvSchema;
021import de.isas.mztab2.model.MzTab;
022import java.io.BufferedWriter;
023import java.io.IOException;
024import java.io.OutputStreamWriter;
025import java.io.Writer;
026import java.nio.charset.StandardCharsets;
027import java.nio.file.Files;
028import java.nio.file.Path;
029import java.nio.file.StandardOpenOption;
030import java.util.Optional;
031import lombok.extern.slf4j.Slf4j;
032import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabException;
033
034/**
035 * <p>
036 * MzTabNonValidatingWriter allows to write MzTab objects without additional
037 * validation checks. Use this if you are sure that your object structure
038 * conforms to the mzTab constraints. Otherwise, use the
039 * MzTabValidatingWriter.</p>
040 *
041 * <p>
042 * To create a non-validating instance, call:</p>
043 * {@code MzTabWriter plainWriter = new MzTabNonValidatingWriter();}
044 * <p>
045 * To create a <b>validating</b> writer using the default checks also applied by
046 * the parser, call:</p>
047 * {@code MzTabWriter validatingWriter = new MzTabValidatingWriter.Default();}
048 *
049 * @author nilshoffmann
050 * @see MzTabValidatingWriter
051 */
052@Slf4j
053public class MzTabNonValidatingWriter implements MzTabWriter<Void> {
054
055    private final MzTabWriterDefaults writerDefaults;
056
057    public MzTabNonValidatingWriter() {
058        this.writerDefaults = new MzTabWriterDefaults();
059    }
060
061    public MzTabNonValidatingWriter(MzTabWriterDefaults writerDefaults) {
062        this.writerDefaults = writerDefaults;
063    }
064
065    /**
066     * <p>
067     * Write the mzTab object to the provided output stream writer.</p>
068     *
069     * This method does not close the output stream but will issue a
070     * <code>flush</code> on the provided output stream writer!
071     *
072     * @param writer a {@link java.io.OutputStreamWriter} object.
073     * @param mzTab a {@link de.isas.mztab2.model.MzTab} object.
074     * @throws java.io.IOException if any.
075     */
076    @Override
077    public Optional<Void> write(OutputStreamWriter writer, MzTab mzTab) throws IOException {
078        if (!writer.getEncoding().
079            equals("UTF8")) {
080            throw new IllegalArgumentException(
081                "OutputStreamWriter encoding must be UTF8 but is " + writer.
082                    getEncoding());
083        }
084        writeMzTab(mzTab, writer);
085        return Optional.empty();
086    }
087
088    /**
089     * <p>
090     * Write the mzTab object to the provided path.</p>
091     *
092     *
093     * @param path a {@link java.nio.file.Path} object.
094     * @param mzTab a {@link de.isas.mztab2.model.MzTab} object.
095     * @return the validation messages.
096     * @throws java.io.IOException if any.
097     */
098    @Override
099    public Optional<Void> write(Path path, MzTab mzTab) throws IOException {
100        try (BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE,
101            StandardOpenOption.WRITE)) {
102            writeMzTab(mzTab, writer);
103        }
104        return Optional.empty();
105    }
106
107    void writeMzTab(MzTab mzTab, final Writer writer) throws IOException {
108        writeMetadataWithJackson(mzTab, writer);
109        writer.write("\n");
110        writeSmallMoleculeSummaryWithJackson(mzTab, writer);
111        writer.write("\n");
112        writeSmallMoleculeFeaturesWithJackson(mzTab, writer);
113        writer.write("\n");
114        writeSmallMoleculeEvidenceWithJackson(mzTab, writer);
115        writer.flush();
116    }
117
118    void writeMetadataWithJackson(MzTab mztabfile, Writer writer) throws IOException {
119        CsvMapper mapper = writerDefaults.metadataMapper();
120        CsvSchema schema = writerDefaults.metaDataSchema(mapper);
121        
122        try {
123            mapper.writer(schema).
124                writeValue(writer, mztabfile.getMetadata());
125        } catch (JsonProcessingException ex) {
126            throw new IOException(ex);
127        }
128    }
129
130    void writeSmallMoleculeSummaryWithJackson(MzTab mztabfile, Writer writer) throws IOException {
131        CsvMapper mapper = writerDefaults.smallMoleculeSummaryMapper();
132        try {
133            CsvSchema schema = writerDefaults.smallMoleculeSummarySchema(mapper,
134                mztabfile);
135            mapper.writer(schema).
136                writeValue(writer, mztabfile.getSmallMoleculeSummary());
137        } catch (JsonProcessingException | MZTabException ex) {
138            throw new IOException(ex);
139        }
140    }
141
142    void writeSmallMoleculeFeaturesWithJackson(MzTab mztabfile, Writer writer) throws IOException {
143        CsvMapper mapper = writerDefaults.smallMoleculeFeatureMapper();
144        try {
145            CsvSchema schema = writerDefaults.smallMoleculeFeatureSchema(mapper,
146                mztabfile);
147            mapper.writer(schema).
148                writeValue(writer, mztabfile.getSmallMoleculeFeature());
149        } catch (JsonProcessingException | MZTabException ex) {
150            throw new IOException(ex);
151        }
152    }
153
154    void writeSmallMoleculeEvidenceWithJackson(MzTab mztabfile, Writer writer) throws IOException {
155        CsvMapper mapper = writerDefaults.smallMoleculeEvidenceMapper();
156        try {
157            CsvSchema schema = writerDefaults.
158                smallMoleculeEvidenceSchema(mapper,
159                    mztabfile);
160            mapper.writer(schema).
161                writeValue(writer, mztabfile.getSmallMoleculeEvidence());
162        } catch (JsonProcessingException | MZTabException ex) {
163            throw new IOException(ex);
164        }
165    }
166
167}