001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.core.model;
007
008import java.net.URI;
009
010import dev.metaschema.core.metapath.StaticContext;
011import dev.metaschema.core.model.constraint.impl.InternalModelSource;
012import dev.metaschema.core.model.constraint.impl.StaticContextSource;
013import dev.metaschema.core.util.ObjectUtils;
014import edu.umd.cs.findbugs.annotations.NonNull;
015import edu.umd.cs.findbugs.annotations.Nullable;
016
017/**
018 * A descriptor that identifies where a given constraint was defined.
019 */
020public interface ISource {
021  /**
022   * The relative location of the source.
023   */
024  enum SourceLocation {
025    /**
026     * A constraint embedded in a model.
027     */
028    MODEL,
029    /**
030     * A constraint defined externally from a model.
031     */
032    EXTERNAL;
033  }
034
035  /**
036   * Get the descriptor for a
037   * {@link dev.metaschema.core.model.ISource.SourceLocation#MODEL} source with as
038   * associated resource.
039   *
040   * @param module
041   *          the Metaschema module the constraint was defined in
042   * @return the source descriptor
043   * @since 2.0.0
044   */
045  @NonNull
046  static ISource moduleSource(@NonNull IModule module) {
047    return InternalModelSource.instance(module);
048  }
049
050  /**
051   * Get the descriptor for a
052   * {@link dev.metaschema.core.model.ISource.SourceLocation#EXTERNAL} source for
053   * the provided resource.
054   *
055   * @param location
056   *          the resource used as the source
057   *
058   * @return the source descriptor
059   */
060  @NonNull
061  static ISource externalSource(@NonNull String location) {
062    return externalSource(ObjectUtils.notNull(URI.create(location)));
063  }
064
065  /**
066   * Get the descriptor for a
067   * {@link dev.metaschema.core.model.ISource.SourceLocation#EXTERNAL} source for
068   * the provided resource.
069   *
070   * @param location
071   *          the resource used as the source
072   *
073   * @return the source descriptor
074   */
075  @NonNull
076  static ISource externalSource(@NonNull URI location) {
077    return StaticContextSource.instance(
078        StaticContext.builder()
079            .baseUri(location)
080            .build(),
081        true);
082  }
083
084  /**
085   * Get the descriptor for a
086   * {@link dev.metaschema.core.model.ISource.SourceLocation#EXTERNAL} source with
087   * as associated resource.
088   * <p>
089   * The provided static context idenfies the location of this source based on the
090   * {@link StaticContext#getBaseUri()} method.
091   *
092   * @param staticContext
093   *          the static Metapath context to use for compiling Metapath
094   *          expressions in this source
095   * @param useCached
096   *          if {@code true} use a previously cached source, otherwise create a
097   *          new one
098   *
099   * @return the source descriptor
100   */
101  @NonNull
102  static ISource externalSource(
103      @NonNull StaticContext staticContext,
104      boolean useCached) {
105    if (staticContext.getBaseUri() == null) {
106      throw new IllegalArgumentException("The static content must define a baseUri identifing the source resource.");
107    }
108    return StaticContextSource.instance(staticContext, useCached);
109  }
110
111  /**
112   * Get the type of source.
113   *
114   * @return the type
115   */
116  @NonNull
117  ISource.SourceLocation getSourceType();
118
119  /**
120   * Get the resource where the constraint was defined, if known.
121   *
122   * @return the resource or {@code null} if the resource is not known
123   */
124  @Nullable
125  URI getSource();
126
127  /**
128   * Get a hint about where the source is location.
129   * <p>
130   * This value will typically be a URI or class name.
131   *
132   * @return the hint
133   */
134  @NonNull
135  String getLocationHint();
136
137  /**
138   * Get the static Metapath context to use when compiling Metapath expressions.
139   *
140   * @return the static Metapath context
141   */
142  @NonNull
143  StaticContext getStaticContext();
144}