001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.core.qname;
007
008import java.util.Map;
009import java.util.Map.Entry;
010import java.util.concurrent.ConcurrentHashMap;
011import java.util.function.Function;
012import java.util.stream.Collectors;
013
014import dev.metaschema.core.metapath.MetapathConstants;
015import dev.metaschema.core.util.CollectionUtil;
016import dev.metaschema.core.util.ObjectUtils;
017import edu.umd.cs.findbugs.annotations.NonNull;
018import edu.umd.cs.findbugs.annotations.Nullable;
019import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
020
021/**
022 * Maintains a mapping between well known namespace URIs and associated
023 * prefixes.
024 */
025public final class WellKnown {
026  @NonNull
027  private static final Map<String, String> WELL_KNOWN_NAMESPACES;
028  @NonNull
029  private static final Map<String, String> WELL_KNOWN_URI_TO_PREFIX;
030
031  static {
032    Map<String, String> knownNamespaces = new ConcurrentHashMap<>();
033    knownNamespaces.put(
034        MetapathConstants.PREFIX_METAPATH,
035        MetapathConstants.NS_METAPATH);
036    knownNamespaces.put(
037        MetapathConstants.PREFIX_METAPATH_FUNCTIONS,
038        MetapathConstants.NS_METAPATH_FUNCTIONS);
039    knownNamespaces.put(
040        MetapathConstants.PREFIX_METAPATH_FUNCTIONS_MATH,
041        MetapathConstants.NS_METAPATH_FUNCTIONS_MATH);
042    knownNamespaces.put(
043        MetapathConstants.PREFIX_METAPATH_FUNCTIONS_ARRAY,
044        MetapathConstants.NS_METAPATH_FUNCTIONS_ARRAY);
045    knownNamespaces.put(
046        MetapathConstants.PREFIX_METAPATH_FUNCTIONS_MAP,
047        MetapathConstants.NS_METAPATH_FUNCTIONS_MAP);
048    WELL_KNOWN_NAMESPACES = CollectionUtil.unmodifiableMap(knownNamespaces);
049
050    WELL_KNOWN_NAMESPACES.forEach(
051        (prefix, namespace) -> NamespaceCache.instance().indexOf(ObjectUtils.notNull(namespace)));
052
053    WELL_KNOWN_URI_TO_PREFIX = ObjectUtils.notNull(WELL_KNOWN_NAMESPACES.entrySet().stream()
054        .collect(Collectors.toUnmodifiableMap(
055            (Function<? super Entry<String, String>, ? extends String>) Entry::getValue,
056            Map.Entry::getKey,
057            (v1, v2) -> v1)));
058  }
059
060  /**
061   * Get the mapping of prefix to namespace URI for all well-known namespaces
062   * provided by default to the static context.
063   * <p>
064   * This method has been deprecated. It is generally preferred to call
065   * {@link WellKnown#getWellKnownUriForPrefix(String)} instead.
066   *
067   * @return the mapping of prefix to namespace URI for all well-known namespaces
068   */
069  @NonNull
070  @Deprecated(since = "2.2.0", forRemoval = true)
071  @SuppressFBWarnings(value = "MS_EXPOSE_REP", justification = "Internal state is immutable")
072  public static Map<String, String> getWellKnownPrefixesToNamespaces() {
073    return WELL_KNOWN_NAMESPACES;
074  }
075
076  /**
077   * Get the mapping of namespace URIs to prefixes for all well-known namespaces
078   * provided by default to the static context.
079   * <p>
080   * This method has been deprecated. It is generally preferred to call
081   * {@link WellKnown#getWellKnownPrefixForUri(String)} instead.
082   *
083   * @return the mapping of namespace URI to prefix for all well-known namespaces
084   */
085  @NonNull
086  @Deprecated(since = "2.2.0", forRemoval = true)
087  @SuppressFBWarnings(value = "MS_EXPOSE_REP", justification = "Internal state is immutable")
088  public static Map<String, String> getWellKnownURIsToPrefixes() {
089    return WELL_KNOWN_URI_TO_PREFIX;
090  }
091
092  /**
093   * Get the namespace prefix associated with the provided URI, if the URI is
094   * well-known.
095   *
096   * @param uri
097   *          the URI to get the prefix for
098   * @return the prefix or {@code null} if the provided URI is not well-known
099   */
100  @Nullable
101  public static String getWellKnownPrefixForUri(@NonNull String uri) {
102    return WELL_KNOWN_URI_TO_PREFIX.get(uri);
103  }
104
105  /**
106   * Get the namespace associated with the provided prefix, if the prefix is
107   * well-known.
108   *
109   * @param prefix
110   *          the prefix
111   * @return the URI associated with the prefix or {@code null} if the provided
112   *         prefix is not well-known
113   */
114  @Nullable
115  public static String getWellKnownUriForPrefix(@NonNull String prefix) {
116    return WELL_KNOWN_NAMESPACES.get(prefix);
117  }
118
119  private WellKnown() {
120    // disable construction
121  }
122}