001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.io;
007
008import java.io.File;
009import java.io.IOException;
010import java.io.OutputStream;
011import java.io.OutputStreamWriter;
012import java.io.Writer;
013import java.nio.charset.StandardCharsets;
014import java.nio.file.Files;
015import java.nio.file.OpenOption;
016import java.nio.file.Path;
017import java.nio.file.StandardOpenOption;
018
019import dev.metaschema.core.configuration.IConfiguration;
020import dev.metaschema.core.configuration.IMutableConfiguration;
021import dev.metaschema.core.model.IBoundObject;
022import dev.metaschema.core.util.ObjectUtils;
023import edu.umd.cs.findbugs.annotations.NonNull;
024
025/**
026 * Implementations of this interface are able to write data in a bound object
027 * instance of the parameterized type to a structured data format.
028 *
029 * @param <CLASS>
030 *          the Java type from which data can be written
031 */
032public interface ISerializer<CLASS extends IBoundObject> extends IMutableConfiguration<SerializationFeature<?>> {
033
034  @Override
035  ISerializer<CLASS> enableFeature(SerializationFeature<?> feature);
036
037  @Override
038  ISerializer<CLASS> disableFeature(SerializationFeature<?> feature);
039
040  @Override
041  ISerializer<CLASS> applyConfiguration(IConfiguration<SerializationFeature<?>> other);
042
043  @Override
044  ISerializer<CLASS> set(SerializationFeature<?> feature, Object value);
045
046  /**
047   * Write data from a bound class instance to the {@link OutputStream}.
048   * <p>
049   * This method does not have ownership of the the provided output stream and
050   * will not close it.
051   *
052   * @param data
053   *          the instance data
054   * @param os
055   *          the output stream to write to
056   * @throws IOException
057   *           if an error occurred while writing data to the stream
058   */
059  default void serialize(@NonNull IBoundObject data, @NonNull OutputStream os) throws IOException {
060    OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8);
061    serialize(data, writer);
062    writer.flush();
063  }
064
065  /**
066   * Write data from a bound class instance to the {@link File}.
067   *
068   * @param data
069   *          the instance data
070   * @param path
071   *          the file to write to
072   * @param openOptions
073   *          options specifying how the file is opened
074   * @throws IOException
075   *           if an error occurred while writing data to the file indicated by
076   *           the {@code path} parameter
077   */
078  default void serialize(@NonNull IBoundObject data, @NonNull Path path, OpenOption... openOptions) throws IOException {
079    try (Writer writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, openOptions)) {
080      assert writer != null;
081      serialize(data, writer);
082    }
083  }
084
085  /**
086   * Write data from a bound class instance to the {@link File}.
087   *
088   * @param data
089   *          the instance data
090   * @param file
091   *          the file to write to
092   * @throws IOException
093   *           if an error occurred while writing data to the stream
094   */
095  default void serialize(@NonNull IBoundObject data, @NonNull File file) throws IOException {
096    serialize(data, ObjectUtils.notNull(file.toPath()), StandardOpenOption.CREATE, StandardOpenOption.WRITE,
097        StandardOpenOption.TRUNCATE_EXISTING);
098  }
099
100  /**
101   * Write data from a bound class instance to the {@link Writer}.
102   *
103   * @param data
104   *          the instance data
105   * @param writer
106   *          the writer to write to
107   * @throws IOException
108   *           if an error occurred while writing data to the stream
109   */
110  void serialize(@NonNull IBoundObject data, @NonNull Writer writer) throws IOException;
111}