1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.databind.model;
7   
8   import java.io.IOException;
9   import java.lang.reflect.Field;
10  
11  import dev.metaschema.core.model.IBoundObject;
12  import dev.metaschema.core.model.IFieldInstanceGrouped;
13  import dev.metaschema.core.util.ObjectUtils;
14  import dev.metaschema.databind.IBindingContext;
15  import dev.metaschema.databind.model.annotations.BoundGroupedField;
16  import dev.metaschema.databind.model.impl.DefinitionField;
17  import dev.metaschema.databind.model.impl.InstanceModelGroupedFieldComplex;
18  import dev.metaschema.databind.model.info.IItemReadHandler;
19  import dev.metaschema.databind.model.info.IItemWriteHandler;
20  import edu.umd.cs.findbugs.annotations.NonNull;
21  
22  /**
23   * Represents a field model instance that is a member of a choice group
24   * instance.
25   */
26  public interface IBoundInstanceModelGroupedField
27      extends IBoundInstanceModelGroupedNamed, IFieldInstanceGrouped {
28  
29    /**
30     * Create a new field model instance instance that is a member of a choice group
31     * instance.
32     *
33     * @param annotation
34     *          the Java annotation the instance is bound to
35     * @param container
36     *          the choice group instance containing the instance
37     * @return the new instance
38     */
39    @NonNull
40    static IBoundInstanceModelGroupedField newInstance(
41        @NonNull BoundGroupedField annotation,
42        @NonNull IBoundInstanceModelChoiceGroup container) {
43      Class<? extends IBoundObject> clazz = annotation.binding();
44      IBindingContext bindingContext = container.getContainingDefinition().getBindingContext();
45      IBoundDefinitionModel<?> definition = bindingContext.getBoundDefinitionForClass(clazz);
46  
47      if (!(definition instanceof DefinitionField)) {
48        Field field = container.getField();
49        throw new IllegalStateException(String.format(
50            "The '%s' annotation, bound to '%s', field '%s' on class '%s' is not bound to a Metaschema field",
51            annotation.getClass(),
52            annotation.binding().getName(),
53            field.toString(),
54            field.getDeclaringClass().getName()));
55      }
56      return new InstanceModelGroupedFieldComplex(annotation, (DefinitionField) definition, container);
57    }
58  
59    @Override
60    IBoundDefinitionModelFieldComplex getDefinition();
61  
62    @Override
63    default IBoundObject readItem(IBoundObject parent, @NonNull IItemReadHandler handler) throws IOException {
64      return handler.readItemField(ObjectUtils.requireNonNull(parent, "parent"), this);
65    }
66  
67    @Override
68    default void writeItem(IBoundObject item, IItemWriteHandler handler) throws IOException {
69      handler.writeItemField(item, this);
70    }
71  }