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