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