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