1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.model;
7   
8   import java.util.Locale;
9   
10  import dev.metaschema.core.datatype.markup.MarkupMultiline;
11  import dev.metaschema.core.util.ObjectUtils;
12  import edu.umd.cs.findbugs.annotations.NonNull;
13  import edu.umd.cs.findbugs.annotations.Nullable;
14  
15  /**
16   * An Metaschema model instance representing a grouped set of objects consisting
17   * of heterogeneous object types.
18   */
19  public interface IChoiceGroupInstance
20      extends IModelInstanceAbsolute, IContainerModelGrouped, IJsonInstance {
21  
22    /**
23     * The default max-occurs value for a choice group. {@code -1} represents an
24     * unbounded occurance.
25     */
26    int DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS = -1;
27  
28    /**
29     * The default JSON property value used to identify the specific type of the
30     * object.
31     */
32    @NonNull
33    String DEFAULT_JSON_DISCRIMINATOR_PROPERTY_NAME = "object-type";
34  
35    /**
36     * {@inheritDoc}
37     *
38     * @see #DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS
39     */
40    @Override
41    default int getMaxOccurs() {
42      return DEFAULT_CHOICE_GROUP_GROUP_AS_MAX_OCCURS;
43    }
44  
45    /**
46     * Provides the Metaschema model type of "CHOICE".
47     *
48     * @return the model type
49     */
50    @Override
51    default ModelType getModelType() {
52      return ModelType.CHOICE_GROUP;
53    }
54  
55    @Override
56    default String getJsonName() {
57      return ObjectUtils.requireNonNull(getGroupAsName(), "Missing group-as name");
58    }
59  
60    /**
61     * Get the JSON property to use to discriminate between JSON objects.
62     *
63     * @return the discriminator property
64     * @see #DEFAULT_JSON_DISCRIMINATOR_PROPERTY_NAME
65     */
66    @NonNull
67    String getJsonDiscriminatorProperty();
68  
69    @Override
70    default boolean isEffectiveValueWrappedInXml() {
71      return true;
72    }
73  
74    /**
75     * Get the effective name of the JSON key flag, if a JSON key is configured.
76     * <p>
77     * This name is expected to be in the same namespace as the containing model
78     * element (i.e. choice group, assembly, field).
79     *
80     * @return the name of the JSON key flag if configured, or {@code null}
81     *         otherwise
82     */
83    @Nullable
84    String getJsonKeyFlagInstanceName();
85  
86    /**
87     * Get the named model instance for the provided choice group item.
88     *
89     * @param item
90     *          the item to get the instance for
91     * @return the named model instance for the provided choice group item
92     */
93    @NonNull
94    default INamedModelInstanceGrouped getItemInstance(@NonNull Object item) {
95      throw new UnsupportedOperationException("Method not needed.");
96    }
97  
98    @Override
99    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 }