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.IBoundObject;
012import dev.metaschema.core.model.IFieldInstanceGrouped;
013import dev.metaschema.core.util.ObjectUtils;
014import dev.metaschema.databind.IBindingContext;
015import dev.metaschema.databind.model.annotations.BoundGroupedField;
016import dev.metaschema.databind.model.impl.DefinitionField;
017import dev.metaschema.databind.model.impl.InstanceModelGroupedFieldComplex;
018import dev.metaschema.databind.model.info.IItemReadHandler;
019import dev.metaschema.databind.model.info.IItemWriteHandler;
020import edu.umd.cs.findbugs.annotations.NonNull;
021
022/**
023 * Represents a field model instance that is a member of a choice group
024 * instance.
025 */
026public interface IBoundInstanceModelGroupedField
027    extends IBoundInstanceModelGroupedNamed, IFieldInstanceGrouped {
028
029  /**
030   * Create a new field model instance instance that is a member of a choice group
031   * instance.
032   *
033   * @param annotation
034   *          the Java annotation the instance is bound to
035   * @param container
036   *          the choice group instance containing the instance
037   * @return the new instance
038   */
039  @NonNull
040  static IBoundInstanceModelGroupedField newInstance(
041      @NonNull BoundGroupedField annotation,
042      @NonNull IBoundInstanceModelChoiceGroup container) {
043    Class<? extends IBoundObject> clazz = annotation.binding();
044    IBindingContext bindingContext = container.getContainingDefinition().getBindingContext();
045    IBoundDefinitionModel<?> definition = bindingContext.getBoundDefinitionForClass(clazz);
046
047    if (!(definition instanceof DefinitionField)) {
048      Field field = container.getField();
049      throw new IllegalStateException(String.format(
050          "The '%s' annotation, bound to '%s', field '%s' on class '%s' is not bound to a Metaschema field",
051          annotation.getClass(),
052          annotation.binding().getName(),
053          field.toString(),
054          field.getDeclaringClass().getName()));
055    }
056    return new InstanceModelGroupedFieldComplex(annotation, (DefinitionField) definition, container);
057  }
058
059  @Override
060  IBoundDefinitionModelFieldComplex getDefinition();
061
062  @Override
063  default IBoundObject readItem(IBoundObject parent, @NonNull IItemReadHandler handler) throws IOException {
064    return handler.readItemField(ObjectUtils.requireNonNull(parent, "parent"), this);
065  }
066
067  @Override
068  default void writeItem(IBoundObject item, IItemWriteHandler handler) throws IOException {
069    handler.writeItemField(item, this);
070  }
071}