001/*
002 * Copyright 2020 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.model.common.search;
017
018import java.util.List;
019import java.util.Objects;
020import java.util.StringJoiner;
021
022/**
023 * Represents a clustering of search results into categories.
024 * Each facet shows the number of hits within the search that match that category.
025 */
026public class Facet<T extends SearchParameter> {
027
028  private T field;
029  private List<Count> counts;
030
031  /**
032   * Null/Empty constructor.
033   */
034  public Facet() {
035  }
036
037  /**
038   * Minimal constructor.
039   */
040  public Facet(T field) {
041    this.field = field;
042  }
043
044  /**
045   * Full constructor.
046   */
047  public Facet(T field, List<Count> counts) {
048    this.field = field;
049    this.counts = counts;
050  }
051
052  /**
053   * List of the different categories/count for this facet.
054   */
055  public List<Count> getCounts() {
056    return counts;
057  }
058
059  /**
060   * Sets the list of counts/categories for this faceted field.
061   */
062  public void setCounts(List<Count> counts) {
063    this.counts = counts;
064  }
065
066  /**
067   * The facet field, it's used only for identify the facet in a possible list of facets.
068   */
069  public T getField() {
070    return field;
071  }
072
073  /**
074   * Sets the field of the facet.
075   */
076  public void setField(T field) {
077    this.field = field;
078  }
079
080  @Override
081  public boolean equals(Object o) {
082    if (this == o) {
083      return true;
084    }
085    if (o == null || getClass() != o.getClass()) {
086      return false;
087    }
088    Facet<?> facet = (Facet<?>) o;
089    return Objects.equals(field, facet.field) &&
090      Objects.equals(counts, facet.counts);
091  }
092
093  @Override
094  public int hashCode() {
095    return Objects.hash(field, counts);
096  }
097
098  @Override
099  public String toString() {
100    return new StringJoiner(", ", Facet.class.getSimpleName() + "[", "]")
101      .add("field=" + field)
102      .add("counts=" + counts)
103      .toString();
104  }
105
106  /**
107   * Nested class that represents the count of each category.
108   */
109  public static class Count {
110
111    private String name;
112    private Long count;
113
114    /**
115     * Null/empty constructor.
116     */
117    public Count() {
118    }
119
120    /**
121     * Full constructor.
122     *
123     * @param name  or label of the category
124     * @param count number of elements of this facet category
125     */
126    public Count(String name, Long count) {
127      this.name = name;
128      this.count = count;
129    }
130
131    /**
132     * Number of occurrences of the category(name).
133     */
134    public Long getCount() {
135      return count;
136    }
137
138    /**
139     * Sets the count of occurrences for this category.
140     */
141    public void setCount(Long count) {
142      this.count = count;
143    }
144
145    /**
146     * Name is the label/name/title used to distinguish this category in the list of counts.
147     * Each name should be unique in the list.
148     *
149     * @return the name or label of the category
150     */
151    public String getName() {
152      return name;
153    }
154
155    /**
156     * Sets the name value of the category/count.
157     */
158    public void setName(String name) {
159      this.name = name;
160    }
161
162    @Override
163    public boolean equals(Object o) {
164      if (this == o) {
165        return true;
166      }
167      if (o == null || getClass() != o.getClass()) {
168        return false;
169      }
170      Count count1 = (Count) o;
171      return Objects.equals(name, count1.name) &&
172        Objects.equals(count, count1.count);
173    }
174
175    @Override
176    public int hashCode() {
177      return Objects.hash(name, count);
178    }
179
180    @Override
181    public String toString() {
182      return new StringJoiner(", ", Count.class.getSimpleName() + "[", "]")
183        .add("name='" + name + "'")
184        .add("count=" + count)
185        .toString();
186    }
187  }
188}