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.datatype.IDataTypeAdapter; 009import gov.nist.secauto.metaschema.core.model.IBoundObject; 010import gov.nist.secauto.metaschema.core.model.IFieldInstanceAbsolute; 011import gov.nist.secauto.metaschema.core.qname.IEnhancedQName; 012import gov.nist.secauto.metaschema.core.util.ObjectUtils; 013import gov.nist.secauto.metaschema.databind.IBindingContext; 014import gov.nist.secauto.metaschema.databind.model.impl.DefinitionField; 015import gov.nist.secauto.metaschema.databind.model.impl.InstanceModelFieldComplex; 016import gov.nist.secauto.metaschema.databind.model.impl.InstanceModelFieldScalar; 017 018import java.lang.reflect.Field; 019 020import edu.umd.cs.findbugs.annotations.NonNull; 021 022public interface IBoundInstanceModelField<ITEM> extends IBoundInstanceModelNamed<ITEM>, IFieldInstanceAbsolute { 023 024 @Override 025 IBoundDefinitionModelField<ITEM> getDefinition(); 026 027 /** 028 * Create a new bound field instance. 029 * 030 * @param field 031 * the Java field the instance is bound to 032 * @param containingDefinition 033 * the definition containing the instance 034 * @return the new instance 035 */ 036 @NonNull 037 static IBoundInstanceModelField<?> newInstance( 038 @NonNull Field field, 039 @NonNull IBoundDefinitionModelAssembly containingDefinition) { 040 Class<?> itemType = IBoundInstanceModel.getItemType(field); 041 042 IBoundInstanceModelField<?> retval; 043 if (IBoundObject.class.isAssignableFrom(itemType)) { 044 IBindingContext bindingContext = containingDefinition.getBindingContext(); 045 IBoundDefinitionModel<?> definition = bindingContext.getBoundDefinitionForClass( 046 ObjectUtils.notNull(itemType.asSubclass(IBoundObject.class))); 047 if (definition == null) { 048 throw new IllegalStateException(String.format( 049 "The field '%s' on class '%s' is not bound to a Metaschema field", 050 field.toString(), 051 field.getDeclaringClass().getName())); 052 } 053 retval = InstanceModelFieldComplex.newInstance(field, (DefinitionField) definition, containingDefinition); 054 } else { 055 056 retval = InstanceModelFieldScalar.newInstance(field, containingDefinition); 057 } 058 return retval; 059 } 060 061 @Override 062 default boolean canHandleXmlQName(IEnhancedQName qname) { 063 boolean retval; 064 if (isEffectiveValueWrappedInXml()) { 065 retval = qname.equals(getQName()); 066 } else { 067 IDataTypeAdapter<?> adapter = getDefinition().getJavaTypeAdapter(); 068 // we are to parse the data type 069 retval = adapter.canHandleQName(qname); 070 } 071 return retval; 072 } 073}