001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.model;
007
008import java.io.IOException;
009import java.lang.reflect.Field;
010
011import dev.metaschema.core.model.IAssemblyInstanceGrouped;
012import dev.metaschema.core.model.IBoundObject;
013import dev.metaschema.core.util.ObjectUtils;
014import dev.metaschema.databind.IBindingContext;
015import dev.metaschema.databind.model.annotations.BoundGroupedAssembly;
016import dev.metaschema.databind.model.impl.InstanceModelGroupedAssembly;
017import dev.metaschema.databind.model.info.IItemReadHandler;
018import dev.metaschema.databind.model.info.IItemWriteHandler;
019import edu.umd.cs.findbugs.annotations.NonNull;
020
021/**
022 * Represents an assembly model instance that is a member of a choice group
023 * instance.
024 */
025public interface IBoundInstanceModelGroupedAssembly
026    extends IBoundInstanceModelGroupedNamed, IAssemblyInstanceGrouped {
027
028  /**
029   * Create a new assembly model instance instance that is a member of a choice
030   * group instance.
031   *
032   * @param annotation
033   *          the Java annotation the instance is bound to
034   * @param container
035   *          the choice group instance containing the instance
036   * @return the new instance
037   */
038  static IBoundInstanceModelGroupedAssembly newInstance(
039      @NonNull BoundGroupedAssembly annotation,
040      @NonNull IBoundInstanceModelChoiceGroup container) {
041    Class<? extends IBoundObject> clazz = annotation.binding();
042    IBindingContext bindingContext = container.getContainingDefinition().getBindingContext();
043    IBoundDefinitionModel<?> definition = bindingContext.getBoundDefinitionForClass(clazz);
044    if (definition instanceof IBoundDefinitionModelAssembly) {
045      return new InstanceModelGroupedAssembly(annotation, (IBoundDefinitionModelAssembly) definition, container);
046    }
047
048    Field field = container.getField();
049    throw new IllegalStateException(String.format(
050        "The '%s' annotation, bound to '%s', on field '%s' on class '%s' is not bound to a Metaschema assembly",
051        annotation.getClass(),
052        annotation.binding().getName(),
053        field.toString(),
054        field.getDeclaringClass().getName()));
055  }
056
057  @Override
058  IBoundDefinitionModelAssembly getDefinition();
059
060  @Override
061  default IBoundObject readItem(IBoundObject parent, @NonNull IItemReadHandler handler) throws IOException {
062    return handler.readItemAssembly(ObjectUtils.requireNonNull(parent, "parent"), this);
063  }
064
065  @Override
066  default void writeItem(IBoundObject item, IItemWriteHandler handler) throws IOException {
067    handler.writeItemAssembly(item, this);
068  }
069}