001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.metaschema.databind.model;
007
008import gov.nist.secauto.metaschema.core.model.IBoundObject;
009import gov.nist.secauto.metaschema.databind.io.BindingException;
010import gov.nist.secauto.metaschema.databind.model.info.IFeatureComplexItemValueHandler;
011
012import java.lang.reflect.InvocationTargetException;
013import java.lang.reflect.Method;
014import java.util.Map;
015import java.util.function.Predicate;
016
017import edu.umd.cs.findbugs.annotations.NonNull;
018import edu.umd.cs.findbugs.annotations.Nullable;
019
020/**
021 * Represents a field or assembly instance bound to Java class.
022 */
023public interface IBoundDefinitionModelComplex
024    extends IBoundDefinitionModel<IBoundObject>, IFeatureComplexItemValueHandler {
025
026  @NonNull
027  Map<String, IBoundProperty<?>> getJsonProperties(@Nullable Predicate<IBoundInstanceFlag> flagFilter);
028
029  @Nullable
030  Method getBeforeDeserializeMethod();
031
032  /**
033   * Calls the method named "beforeDeserialize" on each class in the object's
034   * hierarchy if the method exists on the class.
035   * <p>
036   * These methods can be used to set the initial state of the target bound object
037   * before data is read and applied during deserialization.
038   *
039   * @param targetObject
040   *          the data object target to call the method(s) on
041   * @param parentObject
042   *          the object target's parent object, which is used as the method
043   *          argument
044   * @throws BindingException
045   *           if an error occurs while calling the method
046   */
047  @Override
048  default void callBeforeDeserialize(IBoundObject targetObject, IBoundObject parentObject) throws BindingException {
049    Method beforeDeserializeMethod = getBeforeDeserializeMethod();
050    if (beforeDeserializeMethod != null) {
051      try {
052        beforeDeserializeMethod.invoke(targetObject, parentObject);
053      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
054        throw new BindingException(ex);
055      }
056    }
057  }
058
059  @Nullable
060  Method getAfterDeserializeMethod();
061
062  /**
063   * Calls the method named "afterDeserialize" on each class in the object's
064   * hierarchy if the method exists.
065   * <p>
066   * These methods can be used to modify the state of the target bound object
067   * after data is read and applied during deserialization.
068   *
069   * @param targetObject
070   *          the data object target to call the method(s) on
071   * @param parentObject
072   *          the object target's parent object, which is used as the method
073   *          argument
074   * @throws BindingException
075   *           if an error occurs while calling the method
076   */
077  @Override
078  default void callAfterDeserialize(IBoundObject targetObject, IBoundObject parentObject) throws BindingException {
079    Method afterDeserializeMethod = getAfterDeserializeMethod();
080    if (afterDeserializeMethod != null) {
081      try {
082        afterDeserializeMethod.invoke(targetObject, parentObject);
083      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
084        throw new BindingException(ex);
085      }
086    }
087  }
088
089  // @Override
090  // public String getJsonKeyFlagName() {
091  // // definition items never have a JSON key
092  // return null;
093  // }
094
095}