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