001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to you under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package gudusoft.gsqlparser.ext.sqlnamematcher;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024/**
025 * Checks whether two names are the same according to a case-sensitivity policy.
026 *
027 * <p>Originally derived from Apache Calcite's name matching framework.
028 *
029 * @see SqlNameMatchers
030 */
031public interface SqlNameMatcher {
032  /** Returns whether name matching is case-sensitive. */
033  boolean isCaseSensitive();
034
035  /** Returns whether a name matches another.
036   *
037   * @param string Name written in code
038   * @param name Name of object we are trying to match
039   * @return Whether matches
040   */
041  boolean matches(String string, String name);
042
043  /** Looks up an item in a map.
044   *
045   * @param map Map to search
046   * @param prefixNames Prefix names to prepend
047   * @param names Names to search for
048   * @return Value if found, null otherwise
049   */
050  <K extends List<String>, V> V get(Map<K, V> map, List<String> prefixNames,
051      List<String> names);
052
053  /** Returns the most recent match.
054   *
055   * <p>In the default implementation,
056   * throws {@link UnsupportedOperationException}. */
057  String bestString();
058
059  /** Returns how many times a string occurs in a collection.
060   *
061   * <p>Similar to {@link java.util.Collections#frequency}. */
062  int frequency(Iterable<String> names, String name);
063
064  /** Returns a copy of a collection, removing duplicates and retaining
065   * iteration order. */
066  default List<String> distinctCopy(Iterable<String> names) {
067    final List<String> list = new ArrayList<>();
068    final Set<String> set = createSet();
069    for (String name : names) {
070      if (set.add(name)) {
071        list.add(name);
072      }
073    }
074    return list;
075  }
076
077  /** Returns the index of the first element of a collection that matches. */
078  default int indexOf(Iterable<String> names, String name) {
079    int i = 0;
080    for (String n : names) {
081      if (matches(n, name)) {
082        return i;
083      }
084      i++;
085    }
086    return -1;
087  }
088
089  /** Creates a set that has the same case-sensitivity as this matcher. */
090  Set<String> createSet();
091}