001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.core.model;
007
008import java.util.Locale;
009
010import dev.metaschema.core.datatype.markup.MarkupMultiline;
011import dev.metaschema.core.util.ObjectUtils;
012import edu.umd.cs.findbugs.annotations.NonNull;
013import edu.umd.cs.findbugs.annotations.Nullable;
014
015/**
016 * An Metaschema model instance representing a grouped set of objects consisting
017 * of heterogeneous object types.
018 */
019public interface IChoiceGroupInstance
020    extends IModelInstanceAbsolute, IContainerModelGrouped, IJsonInstance {
021
022  /**
023   * The default max-occurs value for a choice group. {@code -1} represents an
024   * unbounded occurance.
025   */
026  int DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS = -1;
027
028  /**
029   * The default JSON property value used to identify the specific type of the
030   * object.
031   */
032  @NonNull
033  String DEFAULT_JSON_DISCRIMINATOR_PROPERTY_NAME = "object-type";
034
035  /**
036   * {@inheritDoc}
037   *
038   * @see #DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS
039   */
040  @Override
041  default int getMaxOccurs() {
042    return DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS;
043  }
044
045  /**
046   * Provides the Metaschema model type of "CHOICE".
047   *
048   * @return the model type
049   */
050  @Override
051  default ModelType getModelType() {
052    return ModelType.CHOICE_GROUP;
053  }
054
055  @Override
056  default String getJsonName() {
057    return ObjectUtils.requireNonNull(getGroupAsName(), "Missing group-as name");
058  }
059
060  /**
061   * Get the JSON property to use to discriminate between JSON objects.
062   *
063   * @return the discriminator property
064   * @see #DEFAULT_JSON_DISCRIMINATOR_PROPERTY_NAME
065   */
066  @NonNull
067  String getJsonDiscriminatorProperty();
068
069  @Override
070  default boolean isEffectiveValueWrappedInXml() {
071    return true;
072  }
073
074  /**
075   * Get the effective name of the JSON key flag, if a JSON key is configured.
076   * <p>
077   * This name is expected to be in the same namespace as the containing model
078   * element (i.e. choice group, assembly, field).
079   *
080   * @return the name of the JSON key flag if configured, or {@code null}
081   *         otherwise
082   */
083  @Nullable
084  String getJsonKeyFlagInstanceName();
085
086  /**
087   * Get the named model instance for the provided choice group item.
088   *
089   * @param item
090   *          the item to get the instance for
091   * @return the named model instance for the provided choice group item
092   */
093  @NonNull
094  default INamedModelInstanceGrouped getItemInstance(@NonNull Object item) {
095    throw new UnsupportedOperationException("Method not needed.");
096  }
097
098  @Override
099  default MarkupMultiline getRemarks() {
100    // no remarks
101    return null;
102  }
103
104  @SuppressWarnings("null")
105  @Override
106  default String toCoordinates() {
107    return String.format("%s-instance:%s:%s/%s@%d",
108        getModelType().toString().toLowerCase(Locale.ROOT),
109        getContainingDefinition().getContainingModule().getShortName(),
110        getContainingDefinition().getName(),
111        getGroupAsName(),
112        hashCode());
113  }
114
115  /**
116   * A visitor callback.
117   *
118   * @param <CONTEXT>
119   *          the type of the context parameter
120   * @param <RESULT>
121   *          the type of the visitor result
122   * @param visitor
123   *          the calling visitor
124   * @param context
125   *          a parameter used to pass contextual information between visitors
126   * @return the visitor result
127   */
128  @Override
129  default <CONTEXT, RESULT> RESULT accept(@NonNull IModelElementVisitor<CONTEXT, RESULT> visitor, CONTEXT context) {
130    return visitor.visitChoiceGroupInstance(this, context);
131  }
132}