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