001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.core.model; 007 008import dev.metaschema.core.qname.IEnhancedQName; 009import dev.metaschema.core.util.ObjectUtils; 010import edu.umd.cs.findbugs.annotations.NonNull; 011 012/** 013 * A base class for a field that is a member of a containing model. 014 * 015 * @param <PARENT> 016 * the Java type of the parent model (i.e., assembly, choice, 017 * choiceGroup). 018 * @param <DEFINITION> 019 * the Java type of the definition for this member field 020 * @param <INSTANCE> 021 * the Java type of the instance for this member field 022 * @param <PARENT_DEFINITION> 023 * the Java type of the containing assembly definition 024 */ 025public abstract class AbstractFieldInstance< 026 PARENT extends IContainerModel, 027 DEFINITION extends IFieldDefinition, 028 INSTANCE extends IFieldInstance, 029 PARENT_DEFINITION extends IAssemblyDefinition> 030 extends AbstractNamedModelInstance<PARENT, PARENT_DEFINITION> 031 implements IFieldInstance, IFeatureDefinitionReferenceInstance<DEFINITION, INSTANCE> { 032 033 /** 034 * Construct a new field instance. 035 * 036 * @param parent 037 * the parent model containing this instance 038 */ 039 protected AbstractFieldInstance(@NonNull PARENT parent) { 040 super(parent); 041 } 042 043 @Override 044 public DEFINITION getDefinition() { 045 IEnhancedQName qname = getReferencedDefinitionQName(); 046 // this should always be not null 047 IFieldDefinition definition = getContainingModule().getScopedFieldDefinitionByName(qname.getIndexPosition()); 048 if (definition == null) { 049 throw new ModelInitializationException( 050 String.format("Unable to resolve field reference '%s' in definition '%s' in module '%s'", 051 qname, 052 getParentContainer().getOwningDefinition().getName(), 053 getContainingModule().getShortName())); 054 } 055 return ObjectUtils.asType(definition); 056 } 057 058 /** 059 * Generates a "coordinate" string for the assembly instance. 060 * 061 * @return the coordinate 062 */ 063 @SuppressWarnings("null") 064 @Override 065 public String toCoordinates() { 066 IDefinition definition = getDefinition(); 067 return String.format("field instance %s -> %s in module %s (@%d(%d)", 068 getQName(), 069 definition.getDefinitionQName(), 070 getContainingDefinition().getContainingModule().getShortName(), 071 hashCode(), 072 definition.hashCode()); 073 } 074}