001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.databind.model.annotations;
007
008import static java.lang.annotation.ElementType.FIELD;
009import static java.lang.annotation.ElementType.METHOD;
010import static java.lang.annotation.RetentionPolicy.RUNTIME;
011
012import java.lang.annotation.Documented;
013import java.lang.annotation.Retention;
014import java.lang.annotation.Target;
015
016import dev.metaschema.core.datatype.IDataTypeAdapter;
017import dev.metaschema.core.model.IFieldInstance;
018import dev.metaschema.core.model.IGroupable;
019import edu.umd.cs.findbugs.annotations.NonNull;
020
021/**
022 * Identifies that the annotation target is a bound property that references a
023 * Module field.
024 * <p>
025 * For XML serialization, the {@link #useName()} identifies the name of the
026 * element to use for this element.
027 * <p>
028 * For JSON and YAML serializations, the {@link #useName()} identifies the
029 * property/item name to use.
030 * <p>
031 * The field must be either:
032 * <ol>
033 * <li>A Module data type or a collection whose item value is Module data type,
034 * with a non-null {@link #typeAdapter()}.
035 * <li>A type or a collection whose item value is a type based on a class with a
036 * {@link MetaschemaField} annotation, with a property annotated with
037 * {@link BoundFieldValue}.
038 * </ol>
039 */
040@Documented
041@Retention(RUNTIME)
042@Target({ FIELD, METHOD })
043public @interface BoundField {
044  /**
045   * Get the documentary formal name of the field.
046   * <p>
047   * If the value is "##none", then the description will be considered
048   * {@code null}.
049   *
050   * @return a markdown string or {@code "##none"} if no formal name is provided
051   */
052  @NonNull
053  String formalName() default ModelUtil.NO_STRING_VALUE;
054
055  /**
056   * Get the documentary description of the field.
057   * <p>
058   * If the value is "##none", then the description will be considered
059   * {@code null}.
060   *
061   * @return a markdown string or {@code "##none"} if no description is provided
062   */
063  @NonNull
064  String description() default ModelUtil.NO_STRING_VALUE;
065
066  /**
067   * The model name to use for JSON/YAML singleton values and associated XML
068   * elements.
069   * <p>
070   * If the value is "##none", then the use name will be provided by the
071   * definition or by the field name if the item value class is missing the
072   * {@link MetaschemaField} annotation.
073   *
074   * @return the name
075   */
076  @NonNull
077  String useName() default ModelUtil.NO_STRING_VALUE;
078
079  /**
080   * The binary use name of the field.
081   * <p>
082   * The value {@link Integer#MIN_VALUE} indicates that there is no use name.
083   *
084   * @return the index value
085   */
086  int useIndex() default Integer.MIN_VALUE;
087
088  /**
089   * The Metaschema data type adapter for the field's value.
090   *
091   * @return the data type adapter
092   */
093  @NonNull
094  Class<? extends IDataTypeAdapter<?>> typeAdapter() default NullJavaTypeAdapter.class;
095
096  /**
097   * The default value of the field represented as a string.
098   * <p>
099   * The value {@link ModelUtil#NULL_VALUE} is used to indicate if no default
100   * value is provided.
101   *
102   * @return the default value
103   */
104  @NonNull
105  String defaultValue() default ModelUtil.NULL_VALUE;
106
107  /**
108   * If the data type allows it, determines if the field's value must be wrapped
109   * with an XML element.
110   *
111   * @return {@code true} if the field must be wrapped, or {@code false} otherwise
112   */
113  boolean inXmlWrapped() default IFieldInstance.DEFAULT_FIELD_IN_XML_WRAPPED;
114
115  /**
116   * A non-negative number that indicates the minimum occurrence of the model
117   * instance.
118   *
119   * @return a non-negative number
120   */
121  int minOccurs() default IGroupable.DEFAULT_GROUP_AS_MIN_OCCURS;
122
123  /**
124   * A number that indicates the maximum occurrence of the model instance.
125   *
126   * @return a positive number or {@code -1} to indicate "unbounded"
127   */
128  int maxOccurs() default IGroupable.DEFAULT_GROUP_AS_MAX_OCCURS;
129
130  /**
131   * An optional set of associated properties.
132   *
133   * @return the properties or an empty array with no properties
134   */
135  Property[] properties() default {};
136
137  /**
138   * Get any remarks for this field.
139   *
140   * @return a markdown string or {@code "##none"} if no remarks are provided
141   */
142  @NonNull
143  String remarks() default ModelUtil.NO_STRING_VALUE;
144
145  /**
146   * Used to provide grouping information.
147   * <p>
148   * This annotation is required when the value of {@link #maxOccurs()} is greater
149   * than 1.
150   *
151   * @return the configured {@link GroupAs} or the default value with a
152   *         {@code null} {@link GroupAs#name()}
153   */
154  @NonNull
155  GroupAs groupAs() default @GroupAs(name = ModelUtil.NULL_VALUE);
156
157  /**
158   * Get the value constraints defined for this Metaschema field inline
159   * definition.
160   *
161   * @return the value constraints
162   */
163  ValueConstraints valueConstraints() default @ValueConstraints;
164}