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.ArraySchema; 018import io.swagger.v3.oas.annotations.media.Schema; 019 020import org.gbif.api.jackson.DownloadRequestSerde; 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@Schema( 045 description = "An occurrence download request.", 046 oneOf = {PredicateDownloadRequest.class, SqlDownloadRequest.class} 047) 048@SuppressWarnings("unused") 049@JsonDeserialize(using = DownloadRequestSerde.class) 050public abstract class DownloadRequest implements Serializable { 051 052 private static final String DELIMITER = ","; 053 054 @Schema( 055 description = "The GBIF username of the initiator of the download request." 056 ) 057 @JsonProperty("creator") 058 private String creator; 059 060 @ArraySchema( 061 schema = @Schema( 062 description = "An email addresses to notify when the download finishes." 063 ) 064 ) 065 @JsonProperty("notificationAddresses") 066 private Set<String> notificationAddresses; 067 068 @Schema( 069 description = "Whether to send a notification email when the download finishes." 070 ) 071 @JsonProperty("sendNotification") 072 private Boolean sendNotification; 073 074 @Schema( 075 description = "The data format of the download." 076 ) 077 @JsonProperty("format") 078 private DownloadFormat format; 079 080 @Hidden 081 @JsonProperty("type") 082 private DownloadType type; 083 084 /** 085 * Default constructor. 086 */ 087 public DownloadRequest() { 088 // Empty constructor required to create instances from the data access layer. 089 } 090 091 public DownloadRequest(String creator, Collection<String> notificationAddresses, 092 Boolean sendNotification, DownloadFormat format, 093 DownloadType downloadType 094 ) { 095 this.creator = creator; 096 this.notificationAddresses = notificationAddresses == null ? Collections.emptySet() : 097 Collections.unmodifiableSet(new HashSet<>(notificationAddresses)); 098 this.sendNotification = sendNotification; 099 this.format = format; 100 this.type = downloadType; 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 public void setCreator(String creator) { 112 this.creator = creator; 113 } 114 115 /** 116 * @return set of email addresses for notifications 117 */ 118 @Nullable 119 public Set<String> getNotificationAddresses() { 120 return notificationAddresses; 121 } 122 123 public void setNotificationAddresses(Set<String> notificationAddresses) { 124 this.notificationAddresses = notificationAddresses; 125 } 126 127 /** 128 * Returns the notification addresses as single string. The emails are separated by ','. 129 */ 130 @Nullable 131 @JsonIgnore 132 public String getNotificationAddressesAsString() { 133 if (notificationAddresses != null) { 134 return notificationAddresses.stream() 135 .filter(Objects::nonNull) 136 .map(String::trim) 137 .collect(Collectors.joining(DELIMITER)); 138 } 139 return null; 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 @JsonIgnore 189 public String getFileExtension() { 190 return format.getExtension(); 191 } 192 193 @Override 194 public boolean equals(Object o) { 195 if (this == o) { 196 return true; 197 } 198 if (o == null || getClass() != o.getClass()) { 199 return false; 200 } 201 DownloadRequest that = (DownloadRequest) o; 202 return sendNotification == that.sendNotification && 203 Objects.equals(creator, that.creator) && 204 Objects.equals(notificationAddresses, that.notificationAddresses) && 205 format == that.format && 206 type == that.type; 207 } 208 209 @Override 210 public int hashCode() { 211 return Objects.hash(creator, notificationAddresses, sendNotification, format, type); 212 } 213 214 @Override 215 public String toString() { 216 return new StringJoiner(", ", DownloadRequest.class.getSimpleName() + "[", "]") 217 .add("creator='" + creator + "'") 218 .add("notificationAddresses=" + notificationAddresses) 219 .add("sendNotification=" + sendNotification) 220 .add("format=" + format) 221 .add("type=" + type) 222 .toString(); 223 } 224}