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 an assembly that is a member of a containing model.
014 *
015 * @param <PARENT>
016 *          the Java type of the parent model container for this instance
017 * @param <DEFINITION>
018 *          the Java type of the related assembly definition
019 * @param <INSTANCE>
020 *          the Java type of the implementing instance type
021 * @param <PARENT_DEFINITION>
022 *          the Java type of the containing assembly definition
023 */
024public abstract class AbstractAssemblyInstance<
025    PARENT extends IContainerModel,
026    DEFINITION extends IAssemblyDefinition,
027    INSTANCE extends IAssemblyInstance,
028    PARENT_DEFINITION extends IAssemblyDefinition>
029    extends AbstractNamedModelInstance<PARENT, PARENT_DEFINITION>
030    implements IAssemblyInstance, IFeatureDefinitionReferenceInstance<DEFINITION, INSTANCE> {
031
032  /**
033   * Construct a new assembly instance that is contained with the provided parent
034   * container.
035   *
036   * @param parent
037   *          the parent container for this instance
038   */
039  protected AbstractAssemblyInstance(@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    IAssemblyDefinition definition = getContainingModule().getScopedAssemblyDefinitionByName(qname.getIndexPosition());
048    if (definition == null) {
049      throw new ModelInitializationException(
050          String.format("Unable to resolve assembly 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("assembly instance %s -> %s in module %s (@%d(%d)",
068        getQName(),
069        definition.getDefinitionQName(),
070        getContainingDefinition().getContainingModule().getShortName(),
071        hashCode(),
072        definition.hashCode());
073  }
074}