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.occurrence;
015
016import com.fasterxml.jackson.annotation.JsonCreator;
017import com.fasterxml.jackson.annotation.JsonProperty;
018import com.fasterxml.jackson.databind.JsonNode;
019import io.swagger.v3.oas.annotations.ExternalDocumentation;
020import io.swagger.v3.oas.annotations.media.ArraySchema;
021
022import lombok.Getter;
023
024import lombok.Setter;
025
026import org.gbif.api.model.predicate.ConjunctionPredicate;
027import org.gbif.api.model.predicate.DisjunctionPredicate;
028import org.gbif.api.model.predicate.EqualsPredicate;
029import org.gbif.api.model.predicate.GeoDistancePredicate;
030import org.gbif.api.model.predicate.GreaterThanOrEqualsPredicate;
031import org.gbif.api.model.predicate.GreaterThanPredicate;
032import org.gbif.api.model.predicate.InPredicate;
033import org.gbif.api.model.predicate.IsNotNullPredicate;
034import org.gbif.api.model.predicate.IsNullPredicate;
035import org.gbif.api.model.predicate.LessThanOrEqualsPredicate;
036import org.gbif.api.model.predicate.LessThanPredicate;
037import org.gbif.api.model.predicate.LikePredicate;
038import org.gbif.api.model.predicate.NotPredicate;
039import org.gbif.api.model.predicate.Predicate;
040import org.gbif.api.model.predicate.WithinPredicate;
041import org.gbif.api.vocabulary.Extension;
042
043import java.util.Collection;
044import java.util.Collections;
045import java.util.Objects;
046import java.util.Set;
047import java.util.StringJoiner;
048
049import jakarta.annotation.Nullable;
050import jakarta.validation.Valid;
051
052import com.fasterxml.jackson.annotation.JsonCreator;
053import com.fasterxml.jackson.annotation.JsonProperty;
054
055import io.swagger.v3.oas.annotations.media.Schema;
056
057/**
058 * An occurrence download request whose filters are based on predicates ( see {@link Predicate}).
059 */
060@Schema(
061  description = "An occurrence download request whose filters are based on predicates."
062)
063public class PredicateDownloadRequest extends DownloadRequest {
064
065  //Default download format.
066  private static final DownloadFormat DEFAULT_DOWNLOAD_FORMAT = DownloadFormat.SIMPLE_CSV;
067
068  @Schema(
069    description = "A predicate defining the filters to apply to the download.",
070    externalDocs = @ExternalDocumentation(url = "https://techdocs.gbif.org/en/data-use/api-downloads#predicates"),
071    oneOf = {
072      ConjunctionPredicate.class,
073      DisjunctionPredicate.class,
074      EqualsPredicate.class,
075      GeoDistancePredicate.class,
076      GreaterThanOrEqualsPredicate.class,
077      GreaterThanPredicate.class,
078      InPredicate.class,
079      IsNotNullPredicate.class,
080      IsNullPredicate.class,
081      LessThanOrEqualsPredicate.class,
082      LessThanPredicate.class,
083      LikePredicate.class,
084      NotPredicate.class,
085      WithinPredicate.class
086    }
087  )
088  private Predicate predicate;
089
090  @Getter
091  @Setter
092  @ArraySchema(
093    schema = @Schema(
094      description = "A verbatim (unprocessed) extension to include on a Darwin Core Archive download."
095    )
096  )
097  @JsonProperty("verbatimExtensions")
098  private Set<Extension> verbatimExtensions;
099
100  @Getter
101  @Setter
102  @ArraySchema(
103    schema = @Schema(
104      description = "An interpreted extension to include on a Darwin Core Archive download."
105    )
106  )
107  @JsonProperty("interpretedExtensions")
108  private Set<Extension> interpretedExtensions;
109
110
111  public PredicateDownloadRequest() {
112
113  }
114
115  /**
116   * Full constructor. Used to create instances using JSON serialization.
117   */
118  @JsonCreator
119  public PredicateDownloadRequest(
120    @JsonProperty("predicate") Predicate predicate,
121    @JsonProperty("creator") @Nullable String creator,
122    @JsonProperty("notificationAddresses") @Nullable Collection<String> notificationAddresses,
123    @JsonProperty("sendNotification") @Nullable Boolean sendNotification,
124    @JsonProperty("format") @Nullable DownloadFormat format,
125    @JsonProperty("type") @Nullable DownloadType type,
126    @JsonProperty("description") @Nullable String description,
127    @JsonProperty("machineDescription") @Nullable JsonNode machineDescription,
128    @JsonProperty("verbatimExtensions") @Nullable Set<Extension> verbatimExtensions,
129    @JsonProperty("interpretedExtensions") @Nullable Set<Extension> interpretedExtensions,
130    @JsonProperty("checklistKey") @Nullable String checklistKey
131    ) {
132    super(
133      creator,
134      notificationAddresses,
135      sendNotification == null ? Boolean.TRUE : sendNotification,
136      format == null ? DEFAULT_DOWNLOAD_FORMAT : format,
137      type == null ? DownloadType.OCCURRENCE : type,
138      description,
139      machineDescription,
140      checklistKey
141    );
142    this.predicate = predicate;
143    this.verbatimExtensions =
144        verbatimExtensions == null ? Collections.emptySet() : verbatimExtensions;
145    this.interpretedExtensions =
146        interpretedExtensions == null ? Collections.emptySet() : interpretedExtensions;
147  }
148
149  /**
150   * @return the download filter
151   */
152  @Nullable
153  @Valid
154  public Predicate getPredicate() {
155    return predicate;
156  }
157
158  public void setPredicate(Predicate predicate) {
159    this.predicate = predicate;
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    if (!super.equals(o)) {
171      return false;
172    }
173    PredicateDownloadRequest that = (PredicateDownloadRequest) o;
174    return Objects.equals(predicate, that.predicate)
175        && Objects.equals(verbatimExtensions, that.verbatimExtensions)
176        && Objects.equals(interpretedExtensions, that.interpretedExtensions);
177  }
178
179  @Override
180  public int hashCode() {
181    return Objects.hash(super.hashCode(), predicate, verbatimExtensions, interpretedExtensions);
182  }
183
184  @Override
185  public String toString() {
186    return new StringJoiner(", ", PredicateDownloadRequest.class.getSimpleName() + "[", "]")
187      .add("predicate=" + predicate)
188      .add("creator='" + getCreator() + "'")
189      .add("notificationAddresses=" + getNotificationAddresses())
190      .add("sendNotification=" + getSendNotification())
191      .add("format=" + getFormat())
192      .add("type=" + getType())
193      .add("verbatimExtensions=" + verbatimExtensions)
194      .add("interpretedExtensions=" + interpretedExtensions)
195      .toString();
196  }
197}