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;
011import nl.talsmasoftware.lazy4j.Lazy;
012
013/**
014 * A base class for definitions defined globally within a Metaschema module.
015 *
016 * @param <MODULE>
017 *          the Java type of the containing module
018 * @param <INSTANCE>
019 *          the expected Java type of an instance of this definition
020 */
021public abstract class AbstractGlobalDefinition<MODULE extends IModule, INSTANCE extends INamedInstance>
022    implements IDefinition {
023  @NonNull
024  private final MODULE module;
025  @NonNull
026  private final Lazy<IEnhancedQName> qname;
027  @NonNull
028  private final Lazy<IEnhancedQName> definitionQName;
029
030  /**
031   * Construct a new global definition.
032   *
033   * @param module
034   *          the parent module containing this instance
035   * @param initializer
036   *          the callback used to generate qualified names
037   */
038  protected AbstractGlobalDefinition(@NonNull MODULE module, @NonNull NameInitializer initializer) {
039    this.module = module;
040    this.qname = ObjectUtils.notNull(Lazy.of(() -> initializer.apply(getEffectiveName())));
041    this.definitionQName = ObjectUtils.notNull(Lazy.of(() -> initializer.apply(getName())));
042  }
043
044  @Override
045  public final MODULE getContainingModule() {
046    return module;
047  }
048
049  @Override
050  public ISource getSource() {
051    return getContainingModule().getSource();
052  }
053
054  @SuppressWarnings("null")
055  @Override
056  public final IEnhancedQName getQName() {
057    return qname.get();
058  }
059
060  @SuppressWarnings("null")
061  @Override
062  public final IEnhancedQName getDefinitionQName() {
063    return definitionQName.get();
064  }
065
066  @Override
067  public boolean isInline() {
068    // never inline
069    return false;
070  }
071
072  @Override
073  public final INSTANCE getInlineInstance() {
074    // never inline
075    return null;
076  }
077
078  /**
079   * Provides a callback for generating a qualified name from a name.
080   */
081  @FunctionalInterface
082  public interface NameInitializer {
083    /**
084     * Produce a qualified name by parsing the provided name.
085     *
086     * @param name
087     *          the name to parse
088     * @return the qualified name for the provided name
089     */
090    @NonNull
091    IEnhancedQName apply(@NonNull String name);
092  }
093}