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 io.swagger.v3.oas.annotations.Hidden; 017import io.swagger.v3.oas.annotations.media.Schema; 018 019import org.gbif.api.jackson.DownloadRequestSerde; 020import org.gbif.api.vocabulary.Extension; 021 022import java.io.Serializable; 023import java.util.Collection; 024import java.util.Collections; 025import java.util.HashSet; 026import java.util.Objects; 027import java.util.Set; 028import java.util.StringJoiner; 029import java.util.stream.Collectors; 030import java.util.stream.Stream; 031 032import javax.annotation.Nullable; 033 034import org.apache.commons.lang3.StringUtils; 035 036import com.fasterxml.jackson.annotation.JsonIgnore; 037import com.fasterxml.jackson.annotation.JsonProperty; 038import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 039 040/** 041 * Represents a request to download occurrence records. 042 * This is the base class for specific type of downloads: predicate based downloads and SQL downloads. 043 */ 044@SuppressWarnings("unused") 045@JsonDeserialize(using = DownloadRequestSerde.class) 046public abstract class DownloadRequest implements Serializable { 047 048 private static final String DELIMITER = ","; 049 050 @Schema( 051 description = "The GBIF username of the initiator of the download request." 052 ) 053 @JsonProperty("creator") 054 private String creator; 055 056 @Schema( 057 description = "A list of email addresses to notify when the download finishes." 058 ) 059 @JsonProperty("notificationAddresses") 060 private Set<String> notificationAddresses; 061 062 @Schema( 063 description = "Whether to send a notification email when the download finishes." 064 ) 065 @JsonProperty("sendNotification") 066 private Boolean sendNotification; 067 068 @Schema( 069 description = "The data format of the download." 070 ) 071 @JsonProperty("format") 072 private DownloadFormat format; 073 074 @Hidden 075 @JsonProperty("type") 076 private DownloadType type; 077 078 @Hidden 079 @JsonProperty("verbatimExtensions") 080 private Set<Extension> verbatimExtensions; 081 082 /** 083 * Default constructor. 084 */ 085 public DownloadRequest() { 086 // Empty constructor required to create instances from the data access layer. 087 } 088 089 public DownloadRequest(String creator, Collection<String> notificationAddresses, 090 Boolean sendNotification, DownloadFormat format, 091 DownloadType downloadType, 092 Set<Extension> verbatimExtensions 093 ) { 094 this.creator = creator; 095 this.notificationAddresses = notificationAddresses == null ? Collections.emptySet() : 096 Collections.unmodifiableSet(new HashSet<>(notificationAddresses)); 097 this.sendNotification = sendNotification; 098 this.format = format; 099 this.type = downloadType; 100 this.verbatimExtensions = verbatimExtensions == null? Collections.emptySet(): verbatimExtensions; 101 } 102 103 /** 104 * @return the user account that initiated the download 105 */ 106 @Nullable 107 public String getCreator() { 108 return creator; 109 } 110 111 /** 112 * @return set of email addresses for notifications 113 */ 114 @Nullable 115 public Set<String> getNotificationAddresses() { 116 return notificationAddresses; 117 } 118 119 /** 120 * Returns the notification addresses as single string. The emails are separated by ','. 121 */ 122 @Nullable 123 @JsonIgnore 124 public String getNotificationAddressesAsString() { 125 if (notificationAddresses != null) { 126 return notificationAddresses.stream() 127 .filter(Objects::nonNull) 128 .map(String::trim) 129 .collect(Collectors.joining(DELIMITER)); 130 } 131 return null; 132 } 133 134 public void setCreator(String creator) { 135 this.creator = creator; 136 } 137 138 public void setNotificationAddresses(Set<String> notificationAddresses) { 139 this.notificationAddresses = notificationAddresses; 140 } 141 142 /** 143 * Sets the notificationAddresses using a single String value that is split by ','. 144 */ 145 public void setNotificationAddressesAsString(String notificationAddressesAsString) { 146 if (notificationAddressesAsString != null) { 147 notificationAddresses = Stream.of(notificationAddressesAsString.split(DELIMITER)) 148 .filter(StringUtils::isNotEmpty) 149 .map(String::trim) 150 .collect(Collectors.toSet()); 151 } 152 } 153 154 @Nullable 155 public Boolean getSendNotification() { 156 return sendNotification; 157 } 158 159 /** 160 * This parameter determines if the requested download must be notified to the created once it's ready. 161 */ 162 public void setSendNotification(boolean sendNotification) { 163 this.sendNotification = sendNotification; 164 } 165 166 public DownloadFormat getFormat() { 167 return format; 168 } 169 170 /** 171 * This parameter determines the output format of the requested download. 172 */ 173 public void setFormat(DownloadFormat format) { 174 this.format = format; 175 } 176 177 public DownloadType getType() { 178 return type; 179 } 180 181 /** 182 * Download type: Occurrence or Event. 183 */ 184 public void setType(DownloadType type) { 185 this.type = type; 186 } 187 188 /** 189 * Requested verbatimExtensions for this download. 190 */ 191 @Nullable 192 public Set<Extension> getVerbatimExtensions() { 193 return verbatimExtensions; 194 } 195 196 public void setVerbatimExtensions(Set<Extension> verbatimExtensions) { 197 this.verbatimExtensions = verbatimExtensions; 198 } 199 200 @Override 201 public boolean equals(Object o) { 202 if (this == o) { 203 return true; 204 } 205 if (o == null || getClass() != o.getClass()) { 206 return false; 207 } 208 DownloadRequest that = (DownloadRequest) o; 209 return sendNotification == that.sendNotification && 210 Objects.equals(creator, that.creator) && 211 Objects.equals(notificationAddresses, that.notificationAddresses) && 212 format == that.format && 213 type == that.type && 214 Objects.equals(verbatimExtensions, that.verbatimExtensions); 215 } 216 217 @Override 218 public int hashCode() { 219 return Objects.hash(creator, notificationAddresses, sendNotification, format, type, verbatimExtensions); 220 } 221 222 @Override 223 public String toString() { 224 return new StringJoiner(", ", DownloadRequest.class.getSimpleName() + "[", "]") 225 .add("creator='" + creator + "'") 226 .add("notificationAddresses=" + notificationAddresses) 227 .add("sendNotification=" + sendNotification) 228 .add("format=" + format) 229 .add("type=" + type) 230 .add("verbatimExtensions=" + verbatimExtensions) 231 .toString(); 232 } 233}