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.IChoiceGroupInstance;
010import gov.nist.secauto.metaschema.core.model.IFeatureContainerModelGrouped;
011import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
012import gov.nist.secauto.metaschema.core.util.ObjectUtils;
013import gov.nist.secauto.metaschema.databind.io.BindingException;
014import gov.nist.secauto.metaschema.databind.model.impl.InstanceModelChoiceGroup;
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;
022import edu.umd.cs.findbugs.annotations.Nullable;
023
024/**
025 * Represents a choice group instance bound to Java field.
026 */
027public interface IBoundInstanceModelChoiceGroup
028    extends IBoundInstanceModel<IBoundObject>, IFeatureContainerModelGrouped<
029        IBoundInstanceModelGroupedNamed,
030        IBoundInstanceModelGroupedField,
031        IBoundInstanceModelGroupedAssembly>,
032    IChoiceGroupInstance {
033
034  /**
035   * Create a new bound choice group instance.
036   *
037   * @param field
038   *          the Java field the instance is bound to
039   * @param containingDefinition
040   *          the definition containing the instance
041   * @return the new instance
042   */
043  @NonNull
044  static IBoundInstanceModelChoiceGroup newInstance(
045      @NonNull Field field,
046      @NonNull IBoundDefinitionModelAssembly containingDefinition) {
047    return InstanceModelChoiceGroup.newInstance(field, containingDefinition);
048  }
049
050  @Override
051  default String getJsonName() {
052    // always the group-as name
053    return ObjectUtils.requireNonNull(getGroupAsName());
054  }
055
056  @Override
057  @NonNull
058  IBoundDefinitionModelAssembly getOwningDefinition();
059
060  @Override
061  default IBoundDefinitionModelAssembly getContainingDefinition() {
062    return getOwningDefinition();
063  }
064
065  /**
066   * Get the bound grouped model instance associated with the provided Java class.
067   *
068   * @param clazz
069   *          the Java class which should be bound to a grouped model instance
070   * @return the grouped model instance or {code null} if no instance was bound to
071   *         the requested class
072   */
073  @Nullable
074  IBoundInstanceModelGroupedNamed getGroupedModelInstance(@NonNull Class<?> clazz);
075
076  /**
077   * Get the bound grouped model instance associated with the provided XML
078   * qualified name.
079   *
080   * @param name
081   *          the XML qualified name which should be bound to a grouped model
082   *          instance
083   * @return the grouped model instance or {code null} if no instance was bound to
084   *         the requested XML qualified name
085   */
086  @Nullable
087  IBoundInstanceModelGroupedNamed getGroupedModelInstance(@NonNull IEnhancedQName name);
088
089  /**
090   * Get the bound grouped model instance associated with the provided JSON
091   * discriminator value.
092   *
093   * @param discriminator
094   *          the JSON discriminator value which should be bound to a grouped
095   *          model instance
096   * @return the grouped model instance or {code null} if no instance was bound to
097   *         the requested JSON discriminator value
098   */
099  @Nullable
100  IBoundInstanceModelGroupedNamed getGroupedModelInstance(@NonNull String discriminator);
101
102  /**
103   * Get the bound grouped model instance associated with the provided item.
104   *
105   * @param item
106   *          the item which should be bound to a grouped model instance
107   * @return the grouped model instance or {code null} if no instance was bound to
108   *         the requested item
109   */
110  @Override
111  @NonNull
112  default IBoundInstanceModelGroupedNamed getItemInstance(Object item) {
113    return ObjectUtils.requireNonNull(getGroupedModelInstance(item.getClass()));
114  }
115
116  @Override
117  default IBoundObject readItem(IBoundObject parent, IItemReadHandler handler) throws IOException {
118    return handler.readChoiceGroupItem(ObjectUtils.requireNonNull(parent, "parent"), this);
119  }
120
121  @Override
122  default void writeItem(IBoundObject item, IItemWriteHandler handler) throws IOException {
123    handler.writeChoiceGroupItem(item, this);
124  }
125
126  @Override
127  default IBoundObject deepCopyItem(IBoundObject item, IBoundObject parentInstance) throws BindingException {
128    IBoundInstanceModelGroupedNamed itemInstance = getItemInstance(item);
129    return itemInstance.deepCopyItem(item, parentInstance);
130  }
131
132  @Override
133  default boolean canHandleXmlQName(@NonNull IEnhancedQName qname) {
134    return getGroupedModelInstance(qname) != null;
135  }
136}