1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.core.model;
7   
8   import java.util.function.Predicate;
9   
10  import edu.umd.cs.findbugs.annotations.NonNull;
11  import edu.umd.cs.findbugs.annotations.Nullable;
12  
13  /**
14   * Represents a named instance of a field or assembly within a model.
15   * <p>
16   * Provides access to the instance's definition and JSON key configuration for
17   * serialization purposes.
18   */
19  public interface INamedModelInstance extends IModelInstance, INamedInstance {
20  
21    /**
22     * Tests if the provided instance represents complex data. The data is complex
23     * if one of the following is true:
24     * <ul>
25     * <li>The instance is a {@link IAssemblyInstance}.
26     * <li>The instance is a {@link IFieldInstance} that has flags.
27     * </ul>
28     *
29     * This method can be used as a {@link Predicate}.
30     *
31     * @param instance
32     *          the instance to test
33     * @return {@code true} if the data is complex, or {@code false} otherwise
34     */
35    static boolean complexObjectFilter(INamedModelInstance instance) {
36      boolean retval = true;
37      if (instance instanceof IFieldInstance) {
38        IFieldInstance field = (IFieldInstance) instance;
39        retval = !field.getDefinition().getFlagInstances().isEmpty();
40      }
41      return retval;
42    }
43  
44    @Override
45    @NonNull
46    IModelDefinition getDefinition();
47  
48    /**
49     * Indicates if a flag's value can be used as a property name in the containing
50     * object in JSON whose value will be the object containing the flag. In such
51     * cases, the flag will not appear in the object. This is only allowed if the
52     * flag is required, as determined by a {@code true} result from
53     * {@link IFlagInstance#isRequired()}. The {@link IFlagInstance} can be
54     * retrieved using {@link #getEffectiveJsonKey()}.
55     *
56     * @return {@code true} if the flag's value can be used as a property name, or
57     *         {@code false} otherwise
58     * @see #getEffectiveJsonKey()
59     */
60    // TODO: remove once moved to the instance side
61    default boolean hasJsonKey() {
62      return getEffectiveJsonKey() != null;
63    }
64  
65    /**
66     * Get the JSON key flag instance for this model instance, if one is configured.
67     *
68     * @return the JSON key flag instance or {@code null} if no JSON key is
69     *         configured
70     */
71    @Nullable
72    IFlagInstance getEffectiveJsonKey();
73  
74    /**
75     * Get the JSON key associated with this instance.
76     *
77     * @return the configured JSON key or {@code null} if no JSON key is configured
78     */
79    @Nullable
80    IFlagInstance getJsonKey();
81  }