001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.core.model;
007
008import edu.umd.cs.findbugs.annotations.NonNull;
009import edu.umd.cs.findbugs.annotations.Nullable;
010
011/**
012 * Represents a field definition in a Metaschema module.
013 * <p>
014 * A field is a structured data object that may have flags (attributes) and a
015 * simple typed value. Field definitions specify the allowed flags, value type,
016 * and JSON serialization behavior for field instances.
017 */
018public interface IFieldDefinition extends IModelDefinition, IValuedDefinition, IField {
019
020  @Override
021  default boolean isInline() {
022    // not inline by default
023    return false;
024  }
025
026  @Override
027  default IFieldInstance getInlineInstance() {
028    // not inline by default
029    return null;
030  }
031
032  /**
033   * Retrieves the key to use as the field name for this field's value in JSON.
034   *
035   * @return a string or a FlagInstance value
036   */
037  @Nullable
038  default Object getJsonValueKey() {
039    Object retval = getJsonValueKeyFlagInstance();
040    if (retval == null) {
041      retval = getEffectiveJsonValueKeyName();
042    }
043    return retval;
044  }
045
046  /**
047   * Check if a JSON value key flag is configured.
048   *
049   * @return {@code true} if a JSON value key flag is configured, or {@code false}
050   *         otherwise
051   */
052  default boolean hasJsonValueKeyFlagInstance() {
053    return getJsonValueKeyFlagInstance() != null;
054  }
055
056  /**
057   * Retrieves the flag instance whose value will be used as the "value key".
058   *
059   * @return the configured flag instance, or {@code null} if a flag is not
060   *         configured as the "value key"
061   */
062  @Nullable
063  IFlagInstance getJsonValueKeyFlagInstance();
064
065  /**
066   * Retrieves the configured static label to use as the value key, or the type
067   * specific name if a label is not configured.
068   *
069   * @return the value key label
070   */
071  @Nullable
072  String getJsonValueKeyName();
073
074  /**
075   * Retrieves the configured static label to use as the value key, or the type
076   * specific name if a label is not configured.
077   *
078   * @return the value key label
079   */
080  @NonNull
081  default String getEffectiveJsonValueKeyName() {
082    String retval = getJsonValueKeyName();
083    if (retval == null || retval.isEmpty()) {
084      retval = getJavaTypeAdapter().getDefaultJsonValueKey();
085    }
086    return retval;
087  }
088
089  /**
090   * Get the value of the field's value from the field item object.
091   *
092   * @param item
093   *          the field item
094   * @return the field's value or {@code null} if it has no value
095   */
096  default Object getFieldValue(@NonNull Object item) {
097    // no value by default
098    return null;
099  }
100
101  /**
102   * A visitor callback.
103   *
104   * @param <CONTEXT>
105   *          the type of the context parameter
106   * @param <RESULT>
107   *          the type of the visitor result
108   * @param visitor
109   *          the calling visitor
110   * @param context
111   *          a parameter used to pass contextual information between visitors
112   * @return the visitor result
113   */
114  @Override
115  default <CONTEXT, RESULT> RESULT accept(@NonNull IModelElementVisitor<CONTEXT, RESULT> visitor, CONTEXT context) {
116    return visitor.visitFieldDefinition(this, context);
117  }
118}