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