001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.io;
007
008import java.io.IOException;
009
010import dev.metaschema.core.model.IBoundObject;
011import dev.metaschema.databind.model.IBoundDefinitionModelComplex;
012import dev.metaschema.databind.model.info.IFeatureComplexItemValueHandler;
013import edu.umd.cs.findbugs.annotations.NonNull;
014
015/**
016 * Provides the context for writing bound objects to a specific output format.
017 *
018 * @param <WRITER>
019 *          the type of writer used for output
020 */
021public interface IWritingContext<WRITER> {
022  /**
023   * Get the writer associated with the writing context.
024   *
025   * @return the writer
026   */
027  @NonNull
028  WRITER getWriter();
029
030  /**
031   * Write the data described by the provided {@code targetObject} as an XML
032   * element.
033   *
034   * @param definition
035   *          the bound Module definition describing the data to write
036   * @param targetObject
037   *          the Java object data to write
038   * @throws IOException
039   *           if an error occurred while writing
040   */
041  void write(
042      @NonNull IBoundDefinitionModelComplex definition,
043      @NonNull IBoundObject targetObject) throws IOException;
044
045  /**
046   * A functional interface for writing object properties.
047   *
048   * @param <T>
049   *          the type of handler used for property writing
050   */
051  @FunctionalInterface
052  interface ObjectWriter<T extends IFeatureComplexItemValueHandler> {
053
054    /**
055     * Write the properties of the provided parent item using the given handler.
056     *
057     * @param parentItem
058     *          the parent object whose properties are being written
059     * @param handler
060     *          the handler that provides property writing capabilities
061     * @throws IOException
062     *           if an error occurred while writing
063     */
064    void accept(@NonNull IBoundObject parentItem, @NonNull T handler) throws IOException;
065
066    /**
067     * Perform a series of property write operations, starting first with this
068     * operation and followed by the {@code after} operation.
069     *
070     * @param after
071     *          the secondary property write operation to perform
072     * @return an aggregate property write operation
073     */
074    @NonNull
075    default ObjectWriter<T> andThen(@NonNull ObjectWriter<? super T> after) {
076      return (parentItem, handler) -> {
077        accept(parentItem, handler);
078        after.accept(parentItem, handler);
079      };
080    }
081  }
082}