1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.databind.model;
7   
8   import gov.nist.secauto.metaschema.core.model.IAssemblyInstanceAbsolute;
9   import gov.nist.secauto.metaschema.core.model.IBoundObject;
10  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
11  import gov.nist.secauto.metaschema.databind.IBindingContext;
12  import gov.nist.secauto.metaschema.databind.io.BindingException;
13  import gov.nist.secauto.metaschema.databind.model.impl.InstanceModelAssemblyComplex;
14  import gov.nist.secauto.metaschema.databind.model.info.IFeatureComplexItemValueHandler;
15  import gov.nist.secauto.metaschema.databind.model.info.IItemReadHandler;
16  import gov.nist.secauto.metaschema.databind.model.info.IItemWriteHandler;
17  
18  import java.io.IOException;
19  import java.lang.reflect.Field;
20  
21  import edu.umd.cs.findbugs.annotations.NonNull;
22  
23  /**
24   * Represents an assembly instance bound to Java field.
25   */
26  public interface IBoundInstanceModelAssembly
27      extends IBoundInstanceModelNamed<IBoundObject>, IAssemblyInstanceAbsolute, IFeatureComplexItemValueHandler {
28    /**
29     * Create a new bound assembly instance.
30     *
31     * @param field
32     *          the Java field the instance is bound to
33     * @param containingDefinition
34     *          the definition containing the instance
35     * @return the new instance
36     */
37    @NonNull
38    static IBoundInstanceModelAssembly newInstance(
39        @NonNull Field field,
40        @NonNull IBoundDefinitionModelAssembly containingDefinition) {
41      Class<? extends IBoundObject> itemType = IBoundInstanceModel.getItemType(field, IBoundObject.class);
42      IBindingContext bindingContext = containingDefinition.getBindingContext();
43      IBoundDefinitionModel<?> definition = bindingContext.getBoundDefinitionForClass(itemType);
44      if (definition instanceof IBoundDefinitionModelAssembly) {
45        return InstanceModelAssemblyComplex.newInstance(
46            field,
47            (IBoundDefinitionModelAssembly) definition,
48            containingDefinition);
49      }
50  
51      throw new IllegalStateException(String.format(
52          "The field '%s' on class '%s' is not bound to a Metaschema assembly",
53          field.toString(),
54          field.getDeclaringClass().getName()));
55    }
56  
57    @Override
58    @NonNull
59    IBoundDefinitionModelAssembly getDefinition();
60    // @Override
61    // default Object getValue(Object parent) {
62    // return IBoundInstanceModelNamed.super.getValue(parent);
63    // }
64  
65    // @Override
66    // default void setValue(Object parentObject, Object value) {
67    // IBoundInstanceModelNamed.super.setValue(parentObject, value);
68    // }
69  
70    @Override
71    default IBoundObject readItem(IBoundObject parent, IItemReadHandler handler) throws IOException {
72      return handler.readItemAssembly(ObjectUtils.requireNonNull(parent, "parent"), this);
73    }
74  
75    @Override
76    default void writeItem(IBoundObject item, IItemWriteHandler handler) throws IOException {
77      handler.writeItemAssembly(item, this);
78    }
79  
80    @Override
81    default IBoundObject deepCopyItem(IBoundObject item, IBoundObject parentInstance) throws BindingException {
82      return getDefinition().deepCopyItem(item, parentInstance);
83    }
84  
85    @Override
86    default Class<? extends IBoundObject> getBoundClass() {
87      return getDefinition().getBoundClass();
88    }
89  
90    @Override
91    default void callBeforeDeserialize(IBoundObject targetObject, IBoundObject parentObject) throws BindingException {
92      getDefinition().callBeforeDeserialize(targetObject, parentObject);
93    }
94  
95    @Override
96    default void callAfterDeserialize(IBoundObject targetObject, IBoundObject parentObject) throws BindingException {
97      getDefinition().callAfterDeserialize(targetObject, parentObject);
98    }
99  }