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.registry;
017
018import org.gbif.api.util.HttpURI;
019import org.gbif.api.vocabulary.Country;
020import org.gbif.api.vocabulary.Language;
021
022import java.net.URI;
023import java.util.ArrayList;
024import java.util.Date;
025import java.util.List;
026import java.util.Objects;
027import java.util.StringJoiner;
028import java.util.UUID;
029
030import javax.annotation.Nullable;
031import javax.validation.constraints.Min;
032import javax.validation.constraints.NotNull;
033import javax.validation.constraints.Size;
034
035import com.fasterxml.jackson.annotation.JsonIgnore;
036
037import io.swagger.v3.oas.annotations.media.Schema;
038
039/**
040 * A GBIF network.
041 *
042 * Networks are collections of datasets, organized outside the Node-Organization
043 * model to serve some purpose.
044 */
045@Schema(
046  description = "Networks are collections of datasets, organized outside " +
047    "the Node-Organization model to serve some purpose."
048)
049@SuppressWarnings("unused")
050public class Network
051    implements NetworkEntity,
052    Contactable,
053    Endpointable,
054    MachineTaggable,
055    Taggable,
056    Commentable,
057    Identifiable,
058    LenientEquals<Network>,
059    Address {
060
061  @Schema(
062    description = "Unique GBIF key for the network.",
063    accessMode = Schema.AccessMode.READ_ONLY
064  )
065  private UUID key;
066
067  @Schema(
068    description = "A name for the network.\n\n" +
069      "*(NB Not required for updates.)*"
070  )
071  private String title;
072
073  @Schema(
074    description = "A description for the network."
075  )
076  private String description;
077
078  @Schema(
079    description = "The language of the network metadata.\n\n" +
080      "*(NB Not required for updates.)*"
081  )
082  private Language language;
083
084  @Schema(
085    description = "The number of datasets collected in this network."
086  )
087  private int numConstituents;
088
089  @Schema(
090    description = "Email addresses associated with this network."
091  )
092  private List<String> email;
093
094  @Schema(
095    description = "Telephone numbers associated with this network."
096  )
097  private List<String> phone;
098
099  @Schema(
100    description = "Homepages with further details on the network."
101  )
102  private List<URI> homepage;
103
104  @Schema(
105    description = "A logo for the network, accessible over HTTP."
106  )
107  private URI logoUrl;
108
109  @Schema(
110    description = "Address lines other than the city, province, country and" +
111      "postal code, which have their own fields."
112  )
113  private List<String> address;
114
115  @Schema(
116    description = "The city or similar line of the network's address."
117  )
118  private String city;
119
120  @Schema(
121    description = "The province or similar line of the network's address."
122  )
123  private String province;
124
125  @Schema(
126    description = "The country or other region of the network's address."
127  )
128  private Country country;
129
130  @Schema(
131    description = "The postal code or similar line of the network's address."
132  )
133  private String postalCode;
134
135  @Schema(
136    description = "The GBIF username of the creator of the network.",
137    accessMode = Schema.AccessMode.READ_ONLY
138  )
139  private String createdBy;
140
141  @Schema(
142    description = "The GBIF username of the last user to modify the network.",
143    accessMode = Schema.AccessMode.READ_ONLY
144  )
145  private String modifiedBy;
146
147  @Schema(
148    description = "Timestamp of when the network was created.",
149    accessMode = Schema.AccessMode.READ_ONLY
150  )
151  private Date created;
152
153  @Schema(
154    description = "Timestamp of when the network was modified.",
155    accessMode = Schema.AccessMode.READ_ONLY
156  )
157  private Date modified;
158
159  @Schema(
160    description = "If present, the network was deleted at this time. " +
161      "It is possible for it to be restored in the future.",
162    accessMode = Schema.AccessMode.READ_ONLY
163  )
164  private Date deleted;
165
166  @Schema(
167    description = "A list of contacts associated with this network.",
168    accessMode = Schema.AccessMode.READ_ONLY
169  )
170  private List<Contact> contacts = new ArrayList<>();
171
172  @Schema(
173    description = "A list of endpoints associated with this network.",
174    accessMode = Schema.AccessMode.READ_ONLY
175  )
176  private List<Endpoint> endpoints = new ArrayList<>();
177
178  @Schema(
179    description = "A list of machine tags associated with this network.",
180    accessMode = Schema.AccessMode.READ_ONLY
181  )
182  private List<MachineTag> machineTags = new ArrayList<>();
183
184  @Schema(
185    description = "A list of tags associated with this network.",
186    accessMode = Schema.AccessMode.READ_ONLY
187  )
188  private List<Tag> tags = new ArrayList<>();
189
190  @Schema(
191    description = "A list of identifiers associated with this network.",
192    accessMode = Schema.AccessMode.READ_ONLY
193  )
194  private List<Identifier> identifiers = new ArrayList<>();
195
196  @Schema(
197    description = "A list of comments associated with this network.",
198    accessMode = Schema.AccessMode.READ_ONLY
199  )
200  private List<Comment> comments = new ArrayList<>();
201
202  @Override
203  public UUID getKey() {
204    return key;
205  }
206
207  @Override
208  public void setKey(UUID key) {
209    this.key = key;
210  }
211
212  @Override
213  public String getTitle() {
214    return title;
215  }
216
217  @Override
218  public void setTitle(String title) {
219    this.title = title;
220  }
221
222  @Override
223  public String getDescription() {
224    return description;
225  }
226
227  @Override
228  public void setDescription(String description) {
229    this.description = description;
230  }
231
232  @Override
233  public Date getCreated() {
234    return created;
235  }
236
237  @Override
238  public void setCreated(Date created) {
239    this.created = created;
240  }
241
242  @Override
243  public Date getModified() {
244    return modified;
245  }
246
247  @Override
248  public void setModified(Date modified) {
249    this.modified = modified;
250  }
251
252  @Override
253  public Date getDeleted() {
254    return deleted;
255  }
256
257  @Override
258  public void setDeleted(Date deleted) {
259    this.deleted = deleted;
260  }
261
262  @NotNull
263  public Language getLanguage() {
264    return language;
265  }
266
267  public void setLanguage(Language language) {
268    this.language = language;
269  }
270
271  @Nullable
272  @Override
273  public List<String> getEmail() {
274    return email;
275  }
276
277  @Override
278  public void setEmail(List<String> email) {
279    this.email = email;
280  }
281
282  @Nullable
283  @Override
284  public List<String> getPhone() {
285    return phone;
286  }
287
288  @Override
289  public void setPhone(List<String> phone) {
290    this.phone = phone;
291  }
292
293  @Nullable
294  @Override
295  public List<URI> getHomepage() {
296    return homepage;
297  }
298
299  @Override
300  public void setHomepage(List<URI> homepage) {
301    this.homepage = homepage;
302  }
303
304  @HttpURI
305  @Nullable
306  public URI getLogoUrl() {
307    return logoUrl;
308  }
309
310  public void setLogoUrl(URI logoUrl) {
311    this.logoUrl = logoUrl;
312  }
313
314  @Nullable
315  @Override
316  public List<String> getAddress() {
317    return address;
318  }
319
320  @Override
321  public void setAddress(List<String> address) {
322    this.address = address;
323  }
324
325  @Nullable
326  @Size(min = 1)
327  @Override
328  public String getCity() {
329    return city;
330  }
331
332  @Override
333  public void setCity(String city) {
334    this.city = city;
335  }
336
337  @Nullable
338  @Size(min = 1)
339  @Override
340  public String getProvince() {
341    return province;
342  }
343
344  @Override
345  public void setProvince(String province) {
346    this.province = province;
347  }
348
349  @Nullable
350  @Override
351  public Country getCountry() {
352    return country;
353  }
354
355  @Override
356  public void setCountry(Country country) {
357    this.country = country;
358  }
359
360  @Nullable
361  @Size(min = 1)
362  @Override
363  public String getPostalCode() {
364    return postalCode;
365  }
366
367  @Override
368  public void setPostalCode(String postalCode) {
369    this.postalCode = postalCode;
370  }
371
372  @Override
373  public String getCreatedBy() {
374    return createdBy;
375  }
376
377  @Override
378  public void setCreatedBy(String createdBy) {
379    this.createdBy = createdBy;
380  }
381
382  @Override
383  public String getModifiedBy() {
384    return modifiedBy;
385  }
386
387  @Override
388  public void setModifiedBy(String modifiedBy) {
389    this.modifiedBy = modifiedBy;
390  }
391
392  @Override
393  public List<Contact> getContacts() {
394    return contacts;
395  }
396
397  @Override
398  public void setContacts(List<Contact> contacts) {
399    this.contacts = contacts;
400  }
401
402  @Override
403  public List<Endpoint> getEndpoints() {
404    return endpoints;
405  }
406
407  @Override
408  public void setEndpoints(List<Endpoint> endpoints) {
409    this.endpoints = endpoints;
410  }
411
412  @Override
413  public void addEndpoint(Endpoint endpoint) {
414    endpoints.add(endpoint);
415  }
416
417  @Override
418  public List<MachineTag> getMachineTags() {
419    return machineTags;
420  }
421
422  @Override
423  public void setMachineTags(List<MachineTag> machineTags) {
424    this.machineTags = machineTags;
425  }
426
427  @Override
428  public void addMachineTag(MachineTag machineTag) {
429    machineTags.add(machineTag);
430  }
431
432  @Override
433  public List<Tag> getTags() {
434    return tags;
435  }
436
437  @Override
438  public void setTags(List<Tag> tags) {
439    this.tags = tags;
440  }
441
442  @Override
443  public List<Identifier> getIdentifiers() {
444    return identifiers;
445  }
446
447  @Override
448  public void setIdentifiers(List<Identifier> identifiers) {
449    this.identifiers = identifiers;
450  }
451
452  @Override
453  public List<Comment> getComments() {
454    return comments;
455  }
456
457  @Override
458  public void setComments(List<Comment> comments) {
459    this.comments = comments;
460  }
461
462  @Min(0)
463  public int getNumConstituents() {
464    return numConstituents;
465  }
466
467  public void setNumConstituents(int numConstituents) {
468    this.numConstituents = numConstituents;
469  }
470
471  /**
472   * Alias for the network title
473   */
474  @Nullable
475  @Override
476  @JsonIgnore
477  public String getOrganization() {
478    return getTitle();
479  }
480
481  /**
482   * Alias for the network title
483   */
484  @Override
485  public void setOrganization(String organization) {
486    setTitle(organization);
487  }
488
489  @Override
490  public boolean equals(Object o) {
491    if (this == o) {
492      return true;
493    }
494    if (o == null || getClass() != o.getClass()) {
495      return false;
496    }
497    Network network = (Network) o;
498    return numConstituents == network.numConstituents
499        && Objects.equals(key, network.key)
500        && Objects.equals(title, network.title)
501        && Objects.equals(description, network.description)
502        && language == network.language
503        && Objects.equals(email, network.email)
504        && Objects.equals(phone, network.phone)
505        && Objects.equals(homepage, network.homepage)
506        && Objects.equals(logoUrl, network.logoUrl)
507        && Objects.equals(address, network.address)
508        && Objects.equals(city, network.city)
509        && Objects.equals(province, network.province)
510        && country == network.country
511        && Objects.equals(postalCode, network.postalCode)
512        && Objects.equals(createdBy, network.createdBy)
513        && Objects.equals(modifiedBy, network.modifiedBy)
514        && Objects.equals(created, network.created)
515        && Objects.equals(modified, network.modified)
516        && Objects.equals(deleted, network.deleted)
517        && Objects.equals(contacts, network.contacts)
518        && Objects.equals(endpoints, network.endpoints)
519        && Objects.equals(machineTags, network.machineTags)
520        && Objects.equals(tags, network.tags)
521        && Objects.equals(identifiers, network.identifiers)
522        && Objects.equals(comments, network.comments);
523  }
524
525  @Override
526  public int hashCode() {
527    return Objects.hash(
528        key,
529        title,
530        description,
531        language,
532        numConstituents,
533        email,
534        phone,
535        homepage,
536        logoUrl,
537        address,
538        city,
539        province,
540        country,
541        postalCode,
542        createdBy,
543        modifiedBy,
544        created,
545        modified,
546        deleted,
547        contacts,
548        endpoints,
549        machineTags,
550        tags,
551        identifiers,
552        comments);
553  }
554
555  @Override
556  public String toString() {
557    return new StringJoiner(", ", Network.class.getSimpleName() + "[", "]")
558        .add("key=" + key)
559        .add("title='" + title + "'")
560        .add("description='" + description + "'")
561        .add("language=" + language)
562        .add("numConstituents=" + numConstituents)
563        .add("email=" + email)
564        .add("phone=" + phone)
565        .add("homepage=" + homepage)
566        .add("logoUrl=" + logoUrl)
567        .add("address=" + address)
568        .add("city='" + city + "'")
569        .add("province='" + province + "'")
570        .add("country=" + country)
571        .add("postalCode='" + postalCode + "'")
572        .add("createdBy='" + createdBy + "'")
573        .add("modifiedBy='" + modifiedBy + "'")
574        .add("created=" + created)
575        .add("modified=" + modified)
576        .add("deleted=" + deleted)
577        .add("contacts=" + contacts)
578        .add("endpoints=" + endpoints)
579        .add("machineTags=" + machineTags)
580        .add("tags=" + tags)
581        .add("identifiers=" + identifiers)
582        .add("comments=" + comments)
583        .toString();
584  }
585
586  /**
587   * Tests persisted fields, excluding the server controlled values such as key and createdBy. Does not included nested
588   * properties in the test.
589   */
590  @Override
591  public boolean lenientEquals(Network other) {
592    if (this == other) {
593      return true;
594    }
595    return Objects.equals(this.title, other.title)
596        && Objects.equals(this.description, other.description)
597        && Objects.equals(this.language, other.language)
598        && Objects.equals(this.email, other.email)
599        && Objects.equals(this.phone, other.phone)
600        && Objects.equals(this.homepage, other.homepage)
601        && Objects.equals(this.logoUrl, other.logoUrl)
602        && Objects.equals(this.address, other.address)
603        && Objects.equals(this.city, other.city)
604        && Objects.equals(this.province, other.province)
605        && Objects.equals(this.country, other.country)
606        && Objects.equals(this.postalCode, other.postalCode);
607  }
608}