001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.api.model.checklistbank;
015
016import org.gbif.api.vocabulary.Language;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Objects;
023import java.util.StringJoiner;
024import java.util.TreeMap;
025
026import org.apache.commons.lang3.StringUtils;
027
028import com.fasterxml.jackson.annotation.JsonIgnore;
029
030import io.swagger.v3.oas.annotations.media.Schema;
031
032/**
033 * A simple class to represent a table of contents for multiple languages. It is used by species
034 * pages to generate a table of contents menu with asynchronous loading of full descriptions.
035 */
036@SuppressWarnings("unused")
037public class TableOfContents {
038
039  private static final String DEFAULT_TOPIC = "general";
040
041  private final Map<Language, Map<String, List<Integer>>> toc = new TreeMap<>();
042
043  public void addDescription(int key, Language lang, String topic) {
044    topic = StringUtils.isEmpty(topic) ? DEFAULT_TOPIC : topic.toLowerCase().trim();
045
046    if (lang == null) {
047      // default to english
048      lang = Language.ENGLISH;
049    }
050
051    if (!toc.containsKey(lang)) {
052      toc.put(lang, new TreeMap<>());
053    }
054    if (!toc.get(lang).containsKey(topic)) {
055      toc.get(lang).put(topic, new ArrayList<>());
056    }
057    toc.get(lang).get(topic).add(key);
058  }
059
060  @JsonIgnore
061  public boolean isEmpty() {
062    return toc.isEmpty();
063  }
064
065  /**
066   * @return list of all languages available for this ToC
067   */
068  @JsonIgnore
069  public List<Language> listLanguages() {
070    return new ArrayList<>(toc.keySet());
071  }
072
073  /**
074   * @return map of all topics for a given language with a list of entry keys for each language
075   */
076  @JsonIgnore
077  public Map<String, List<Integer>> listTopicEntries(Language lang) {
078    if (toc.containsKey(lang)) {
079      return toc.get(lang);
080    }
081    return new HashMap<>();
082  }
083
084  @Schema(description = "A table of contents by language, section and description.")
085  public Map<Language, Map<String, List<Integer>>> getToc() {
086    return toc;
087  }
088
089  @Override
090  public boolean equals(Object o) {
091    if (this == o) {
092      return true;
093    }
094    if (o == null || getClass() != o.getClass()) {
095      return false;
096    }
097    TableOfContents that = (TableOfContents) o;
098    return Objects.equals(toc, that.toc);
099  }
100
101  @Override
102  public int hashCode() {
103    return Objects.hash(toc);
104  }
105
106  @Override
107  public String toString() {
108    return new StringJoiner(", ", TableOfContents.class.getSimpleName() + "[", "]")
109      .add("toc=" + toc)
110      .toString();
111  }
112}