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.registry; 015 016import lombok.Data; 017import lombok.NoArgsConstructor; 018 019import org.gbif.api.model.common.DOI; 020import org.gbif.api.model.registry.eml.Collection; 021import org.gbif.api.model.registry.eml.DataDescription; 022import org.gbif.api.model.registry.eml.KeywordCollection; 023import org.gbif.api.model.registry.eml.Project; 024import org.gbif.api.model.registry.eml.SamplingDescription; 025import org.gbif.api.model.registry.eml.TaxonomicCoverages; 026import org.gbif.api.model.registry.eml.curatorial.CuratorialUnitComposite; 027import org.gbif.api.model.registry.eml.geospatial.GeospatialCoverage; 028import org.gbif.api.model.registry.eml.temporal.TemporalCoverage; 029import org.gbif.api.util.HttpURI; 030import org.gbif.api.vocabulary.Country; 031import org.gbif.api.vocabulary.DatasetSubtype; 032import org.gbif.api.vocabulary.DatasetType; 033import org.gbif.api.vocabulary.Language; 034import org.gbif.api.vocabulary.License; 035import org.gbif.api.vocabulary.MaintenanceUpdateFrequency; 036 037import java.net.URI; 038import java.util.ArrayList; 039import java.util.Date; 040import java.util.HashSet; 041import java.util.List; 042import java.util.Objects; 043import java.util.Set; 044import java.util.StringJoiner; 045import java.util.UUID; 046 047import javax.annotation.Nullable; 048import javax.validation.Valid; 049import javax.validation.constraints.Min; 050import javax.validation.constraints.NotNull; 051import javax.validation.constraints.Null; 052import javax.validation.constraints.Size; 053 054import io.swagger.v3.oas.annotations.media.Schema; 055 056/** 057 * A GBIF dataset which provides occurrence data, checklist data, sampling event data or metadata. 058 * This Dataset class is covering all the GBIF metadata profile v1.3, but only a few properties are kept in the 059 * database table: 060 * <ul> 061 * <li>key</li> 062 * <li>parentDatasetKey</li> 063 * <li>duplicateOfDatasetKey</li> 064 * <li>version</li> 065 * <li>installationKey</li> 066 * <li>publishingOrganizationKey</li> 067 * <li>publishingOrganizationName</li> 068 * <li>networkKeys</li> 069 * <li>license</li> 070 * <li>maintenanceUpdateFrequency</li> 071 * <li>external</li> 072 * <li>numConstituents</li> 073 * <li>type</li> 074 * <li>subtype</li> 075 * <li>title</li> 076 * <li>alias</li> 077 * <li>abbreviation</li> 078 * <li>description</li> 079 * <li>language</li> 080 * <li>homepage</li> 081 * <li>logoUrl</li> 082 * <li>citation</li> 083 * <li>rights</li> 084 * <li>lockedForAutoUpdate</li> 085 * <li>createdBy</li> 086 * <li>modifiedBy</li> 087 * <li>created</li> 088 * <li>modified</li> 089 * <li>deleted</li> 090 * </ul> 091 * 092 * @see <a href="http://rs.gbif.org/schema/eml-gbif-profile/dev/eml.xsd">GBIF EML Profile XML Schema</a> 093 */ 094@SuppressWarnings({"unused", "LombokSetterMayBeUsed", "LombokGetterMayBeUsed"}) 095public class Dataset 096 implements NetworkEntity, 097 Contactable, 098 Endpointable, 099 MachineTaggable, 100 Taggable, 101 Identifiable, 102 Commentable, 103 LenientEquals<Dataset> { 104 105 @Schema( 106 description = "Unique GBIF key for the dataset. This is used in the" + 107 "GBIF API, but outside GBIF it is best to refer to a dataset by its DOI.", 108 accessMode = Schema.AccessMode.READ_ONLY 109 ) 110 private UUID key; 111 112 @Schema( 113 description = "If set, this dataset is a sub-dataset of the parent." 114 ) 115 private UUID parentDatasetKey; 116 117 @Schema( 118 description = "A dataset of which this dataset is a duplicate. Typically, " + 119 "this means this dataset is an old version of the duplicated dataset, " + 120 "which has replaced this dataset. Therefore **this link is usually found " + 121 "on deleted datasets**." 122 ) 123 private UUID duplicateOfDatasetKey; 124 125 @Schema( 126 description = "The installation providing access to the source dataset.\n\n" + 127 "*(NB Not required for updates.)*" 128 ) 129 private UUID installationKey; 130 131 @Schema( 132 description = "The publishing organization publishing this dataset.\n\n" + 133 "*(NB Not required for updates.)*" 134 ) 135 private UUID publishingOrganizationKey; 136 137 @Schema( 138 description = "The publishing organization name.\n\n" + 139 "*(NB Not required for updates.)*" 140 ) 141 private String publishingOrganizationName; 142 143 @Schema( 144 description = "A list of GBIF Networks to which this dataset belongs." 145 ) 146 private List<UUID> networkKeys; 147 148 @Schema( 149 description = "The primary Digital Object Identifier (DOI) for this dataset.", 150 implementation = String.class, 151 pattern = "(10(?:\\.[0-9]+)+)" + "/(.+)" 152 ) 153 private DOI doi; 154 155 @Schema( 156 description = "The version of the published dataset." 157 ) 158 private String version; 159 160 @Schema( 161 description = "Not currently used." 162 ) 163 private boolean external; 164 165 @Schema( 166 description = "If set, the number of sub-datasets of this parent dataset." 167 ) 168 private int numConstituents; 169 170 @Schema( 171 description = "The primary type of the dataset.\n\n" + 172 "*(NB Not required for updates.)*" 173 ) 174 private DatasetType type; 175 176 @Schema( 177 description = "The sub-type of the dataset." 178 ) 179 private DatasetSubtype subtype; 180 181 @Schema( 182 description = "Concise name of the dataset." 183 ) 184 private String shortName; 185 186 @Schema( 187 description = "The title of the dataset.\n\n" + 188 "*(NB Not required for updates.)*" 189 ) 190 private String title; 191 192 @Schema( 193 description = "An alias for this dataset. Rarely used." 194 ) 195 private String alias; 196 197 @Schema( 198 description = "An abbreviation for this dataset. Rarely used." 199 ) 200 private String abbreviation; 201 202 @Schema( 203 description = "A description of the dataset." 204 ) 205 private String description; 206 207 @Schema( 208 description = "The language of the dataset metadata.\n\n" + 209 "*(NB Not required for updates.)*" 210 ) 211 private Language language = Language.ENGLISH; // sensible default as it is not null 212 213 @Schema( 214 description = "A homepage with further details on the dataset." 215 ) 216 private URI homepage; 217 218 @Schema( 219 description = "A logo for the dataset, accessible over HTTP." 220 ) 221 private URI logoUrl; 222 223 @Schema( 224 description = "The citation recommended by GBIF for use when citing this dataset." 225 ) 226 private Citation citation = new Citation(); 227 228 @Schema( 229 description = "Contacts use to generate a citation." 230 ) 231 private List<CitationContact> contactsCitation = new ArrayList<>(); 232 233 @Schema( 234 description = "Intellectual property rights applied to this dataset.\n\n" + 235 "*Rarely used, see `license` instead.*" 236 ) 237 private String rights; 238 239 @Schema( 240 description = "If true, any new or updated metadata is ignored.\n\n" + 241 "This is generally used when the publisher has technical problems or " + 242 "limitations with their publication system.", 243 accessMode = Schema.AccessMode.READ_ONLY 244 ) 245 private boolean lockedForAutoUpdate; 246 247 @Schema( 248 description = "The GBIF username of the creator of the dataset.", 249 accessMode = Schema.AccessMode.READ_ONLY 250 ) 251 private String createdBy; 252 253 @Schema( 254 description = "The GBIF username of the last user to modify the dataset.", 255 accessMode = Schema.AccessMode.READ_ONLY 256 ) 257 private String modifiedBy; 258 259 @Schema( 260 description = "Timestamp of when the dataset was created.", 261 accessMode = Schema.AccessMode.READ_ONLY 262 ) 263 private Date created; 264 265 @Schema( 266 description = "Timestamp of when the dataset was modified.", 267 accessMode = Schema.AccessMode.READ_ONLY 268 ) 269 private Date modified; 270 271 @Schema( 272 description = "If present, the dataset was deleted at this time. " + 273 "It is possible for it to be restored in the future.", 274 accessMode = Schema.AccessMode.READ_ONLY 275 ) 276 private Date deleted; 277 278 @Schema( 279 description = "A list of contacts associated with this dataset.", 280 accessMode = Schema.AccessMode.READ_ONLY 281 ) 282 private List<Contact> contacts = new ArrayList<>(); 283 284 @Schema( 285 description = "A list of endpoints associated with this dataset.", 286 accessMode = Schema.AccessMode.READ_ONLY 287 ) 288 private List<Endpoint> endpoints = new ArrayList<>(); 289 290 @Schema( 291 description = "A list of machine tags associated with this dataset.", 292 accessMode = Schema.AccessMode.READ_ONLY 293 ) 294 private List<MachineTag> machineTags = new ArrayList<>(); 295 296 @Schema( 297 description = "A list of tags associated with this dataset.", 298 accessMode = Schema.AccessMode.READ_ONLY 299 ) 300 private List<Tag> tags = new ArrayList<>(); 301 302 @Schema( 303 description = "A list of identifiers associated with this dataset.", 304 accessMode = Schema.AccessMode.READ_ONLY 305 ) 306 private List<Identifier> identifiers = new ArrayList<>(); 307 308 @Schema( 309 description = "A list of comments associated with this dataset.", 310 accessMode = Schema.AccessMode.READ_ONLY 311 ) 312 private List<Comment> comments = new ArrayList<>(); 313 314 // EML specific properties which are not persisted on the dataset table! 315 @Schema( 316 description = "Citations retrieved from this dataset's metadata documents.", 317 accessMode = Schema.AccessMode.READ_ONLY 318 ) 319 private List<Citation> bibliographicCitations = new ArrayList<>(); 320 321 @Schema( 322 description = "Curatorial unit information retrieved from this dataset's metadata documents.", 323 accessMode = Schema.AccessMode.READ_ONLY 324 ) 325 private List<CuratorialUnitComposite> curatorialUnits = new ArrayList<>(); 326 327 @Schema( 328 description = "Taxonomic coverage information retrieved from this dataset's metadata documents.", 329 accessMode = Schema.AccessMode.READ_ONLY 330 ) 331 private List<TaxonomicCoverages> taxonomicCoverages = new ArrayList<>(); 332 333 @Schema( 334 description = "Geographic coverage description retrieved from this dataset's metadata documents.", 335 accessMode = Schema.AccessMode.READ_ONLY 336 ) 337 private String geographicCoverageDescription; 338 339 @Schema( 340 description = "Geospatial coverage information retrieved from this dataset's metadata documents.", 341 accessMode = Schema.AccessMode.READ_ONLY 342 ) 343 private List<GeospatialCoverage> geographicCoverages = new ArrayList<>(); 344 345 @Schema( 346 description = "Temporal coverage information retrieved from this dataset's metadata documents.", 347 accessMode = Schema.AccessMode.READ_ONLY 348 ) 349 private List<TemporalCoverage> temporalCoverages = new ArrayList<>(); 350 351 @Schema( 352 description = "Keyword collections retrieved from this dataset's metadata documents.", 353 accessMode = Schema.AccessMode.READ_ONLY 354 ) 355 private List<KeywordCollection> keywordCollections = new ArrayList<>(); 356 357 @Schema( 358 description = "Project information retrieved from this dataset's metadata documents.", 359 accessMode = Schema.AccessMode.READ_ONLY 360 ) 361 private Project project; 362 363 @Schema( 364 description = "Sampling description retrieved from this dataset's metadata documents.", 365 accessMode = Schema.AccessMode.READ_ONLY 366 ) 367 private SamplingDescription samplingDescription; 368 369 @Schema( 370 description = "Country coverage information retrieved from this dataset's metadata documents.", 371 accessMode = Schema.AccessMode.READ_ONLY 372 ) 373 private Set<Country> countryCoverage = new HashSet<>(); 374 375 @Schema( 376 description = "Collection information retrieved from this dataset's metadata documents.", 377 accessMode = Schema.AccessMode.READ_ONLY 378 ) 379 private List<Collection> collections = new ArrayList<>(); 380 381 @Schema( 382 description = "Data description information retrieved from this dataset's metadata documents.", 383 accessMode = Schema.AccessMode.READ_ONLY 384 ) 385 private List<DataDescription> dataDescriptions = new ArrayList<>(); 386 387 @Schema( 388 description = "Data language information retrieved from this dataset's metadata documents.", 389 accessMode = Schema.AccessMode.READ_ONLY 390 ) 391 private Language dataLanguage; 392 393 @Schema( 394 description = "Purpose information retrieved from this dataset's metadata documents.", 395 accessMode = Schema.AccessMode.READ_ONLY 396 ) 397 private String purpose; 398 399 @Schema( 400 description = "An overview of the background and context for the dataset.", 401 accessMode = Schema.AccessMode.READ_ONLY 402 ) 403 private String introduction; 404 405 @Schema( 406 description = "A high level overview of interpretation, structure, and content of the dataset.", 407 accessMode = Schema.AccessMode.READ_ONLY 408 ) 409 private String gettingStarted; 410 411 @Schema( 412 description = "Text that acknowledges funders and other key contributors.", 413 accessMode = Schema.AccessMode.READ_ONLY 414 ) 415 private String acknowledgements; 416 417 @Schema( 418 description = "Additional information retrieved from this dataset's metadata documents.", 419 accessMode = Schema.AccessMode.READ_ONLY 420 ) 421 private String additionalInfo; 422 423 @Schema( 424 description = "The publication date retrieved from this dataset's metadata documents.", 425 accessMode = Schema.AccessMode.READ_ONLY 426 ) 427 private Date pubDate; 428 429 @Schema( 430 description = "The maintenance update frequency retrieved from this dataset's metadata documents.", 431 accessMode = Schema.AccessMode.READ_ONLY 432 ) 433 private MaintenanceUpdateFrequency maintenanceUpdateFrequency; 434 435 @Schema( 436 description = "The maintenance description retrieved from this dataset's metadata documents.", 437 accessMode = Schema.AccessMode.READ_ONLY 438 ) 439 private String maintenanceDescription; 440 441 @Schema( 442 description = "The data and metadata license retrieved from this dataset's metadata documents.", 443 accessMode = Schema.AccessMode.READ_ONLY 444 ) 445 private License license; 446 447 @Schema( 448 description = "Basic metadata of the Darwin Core Archive (DwC-A) associated with this dataset.", 449 accessMode = Schema.AccessMode.READ_ONLY 450 ) 451 private DwcA dwca; 452 453 @Schema( 454 description = "Category of this dataset.", 455 accessMode = Schema.AccessMode.READ_ONLY 456 ) 457 private Set<String> category; 458 459 @Override 460 public UUID getKey() { 461 return key; 462 } 463 464 /** 465 * Persisted in the database table. 466 */ 467 @Override 468 public void setKey(UUID key) { 469 this.key = key; 470 } 471 472 @Nullable 473 public String getVersion() { 474 return version; 475 } 476 477 public void setVersion(String version) { 478 this.version = version; 479 } 480 481 @Override 482 public String getTitle() { 483 return title; 484 } 485 486 /** 487 * Persisted in the database table. 488 */ 489 @Override 490 public void setTitle(String title) { 491 this.title = title; 492 } 493 494 @Override 495 @Nullable 496 public String getDescription() { 497 return description; 498 } 499 500 /** 501 * Persisted in the database table. 502 */ 503 @Override 504 public void setDescription(String description) { 505 this.description = description; 506 } 507 508 @Override 509 public Date getCreated() { 510 return created; 511 } 512 513 /** 514 * Autoassigned in the database table, ignored when persisted. 515 */ 516 @Override 517 public void setCreated(Date created) { 518 this.created = created; 519 } 520 521 @Override 522 public Date getModified() { 523 return modified; 524 } 525 526 /** 527 * Persisted in the database table. 528 */ 529 @Override 530 public void setModified(Date modified) { 531 this.modified = modified; 532 } 533 534 @Override 535 @Nullable 536 public Date getDeleted() { 537 return deleted; 538 } 539 540 /** 541 * Persisted in the database table. 542 */ 543 @Override 544 public void setDeleted(Date deleted) { 545 this.deleted = deleted; 546 } 547 548 @Nullable 549 public UUID getParentDatasetKey() { 550 return parentDatasetKey; 551 } 552 553 /** 554 * Persisted in the database table. 555 */ 556 public void setParentDatasetKey(UUID parentDatasetKey) { 557 this.parentDatasetKey = parentDatasetKey; 558 } 559 560 /** 561 * If a dataset is registered with GBIF through more than one place we'll mark all but one as a duplicate by pointing 562 * it to the canonical dataset. That is done using this field. If it is {@code null} then this is not a known 563 * duplicate. 564 */ 565 @Nullable 566 public UUID getDuplicateOfDatasetKey() { 567 return duplicateOfDatasetKey; 568 } 569 570 /** 571 * Persisted in the database table. 572 */ 573 public void setDuplicateOfDatasetKey(UUID duplicateOfDatasetKey) { 574 this.duplicateOfDatasetKey = duplicateOfDatasetKey; 575 } 576 577 @NotNull 578 public UUID getInstallationKey() { 579 return installationKey; 580 } 581 582 /** 583 * Persisted in the database table. 584 */ 585 public void setInstallationKey(UUID installationKey) { 586 this.installationKey = installationKey; 587 } 588 589 @NotNull 590 public UUID getPublishingOrganizationKey() { 591 return publishingOrganizationKey; 592 } 593 594 /** 595 * Persisted in the database table. 596 */ 597 public void setPublishingOrganizationKey(UUID publishingOrganizationKey) { 598 this.publishingOrganizationKey = publishingOrganizationKey; 599 } 600 601 @Nullable 602 public String getPublishingOrganizationName() { 603 return publishingOrganizationName; 604 } 605 606 public void setPublishingOrganizationName(String publishingOrganizationName) { 607 this.publishingOrganizationName = publishingOrganizationName; 608 } 609 610 /** 611 * Networks in which this dataset is a constituent. 612 */ 613 public List<UUID> getNetworkKeys() { 614 return networkKeys; 615 } 616 617 public void setNetworkKeys(List<UUID> networkKeys) { 618 this.networkKeys = networkKeys; 619 } 620 621 /** 622 * Persisted in the database table. 623 * 624 * @return the frequency with which changes are made to the dataset 625 */ 626 @Nullable 627 public MaintenanceUpdateFrequency getMaintenanceUpdateFrequency() { 628 return maintenanceUpdateFrequency; 629 } 630 /** 631 * Persisted in the database table. 632 */ 633 public void setMaintenanceUpdateFrequency(MaintenanceUpdateFrequency maintenanceUpdateFrequency) { 634 this.maintenanceUpdateFrequency = maintenanceUpdateFrequency; 635 } 636 637 /** 638 * A description of the maintenance frequency of this resource. 639 * 640 * @return the description of the maintenance frequency of this resource 641 */ 642 public String getMaintenanceDescription() { 643 return maintenanceDescription; 644 } 645 646 public void setMaintenanceDescription(String maintenanceDescription) { 647 this.maintenanceDescription = maintenanceDescription; 648 } 649 650 /** 651 * Persisted in the database table. 652 * </br> 653 * Note for backwards compatibility, we cannot apply @NotNull to license. Otherwise existing users of our API 654 * would have to ensure Dataset objects always populate license. 655 * </br> 656 * In the Registry DB, Dataset.license defaults to CC-BY 4.0. Therefore license must be excluded from lenientEquals 657 * method. 658 * 659 * @return the License applied to the dataset 660 * 661 * @see <a href="http://dev.gbif.org/issues/browse/POR-3133">POR-3133</a> 662 */ 663 public License getLicense() { 664 return license; 665 } 666 667 /** 668 * Persisted in the database table. Can be interpreted from EML.intellectualRights using machine readable format: 669 * <pre> 670 * {@code 671 * <intellectualRights> 672 * <para>This work is licensed under a <ulink url="http://creativecommons.org/licenses/by/4.0/legalcode"><citetitle>Creative Commons Attribution (CC-BY) 4.0 License</citetitle></ulink>.</para> 673 * </intellectualRights> 674 * } 675 * </pre> 676 */ 677 public void setLicense(License license) { 678 this.license = license; 679 } 680 681 /** 682 * @return the primary DOI for this dataset regardless if issued by GBIF or publisher 683 */ 684 public DOI getDoi() { 685 return doi; 686 } 687 688 public void setDoi(DOI doi) { 689 this.doi = doi; 690 } 691 692 public boolean isExternal() { 693 return external; 694 } 695 696 /** 697 * Persisted in the database table. 698 */ 699 public void setExternal(boolean external) { 700 this.external = external; 701 } 702 703 @Min(0) 704 public int getNumConstituents() { 705 return numConstituents; 706 } 707 708 /** 709 * Not persisted in the database table, but calculated on the fly. 710 */ 711 public void setNumConstituents(int numConstituents) { 712 this.numConstituents = numConstituents; 713 } 714 715 @NotNull 716 public DatasetType getType() { 717 return type; 718 } 719 720 /** 721 * Persisted in the database table. 722 */ 723 public void setType(DatasetType type) { 724 this.type = type; 725 } 726 727 @Nullable 728 public DatasetSubtype getSubtype() { 729 return subtype; 730 } 731 732 /** 733 * Persisted in the database table. 734 */ 735 public void setSubtype(DatasetSubtype subtype) { 736 this.subtype = subtype; 737 } 738 739 @Nullable 740 public String getShortName() { 741 return shortName; 742 } 743 744 public void setShortName(String shortName) { 745 this.shortName = shortName; 746 } 747 748 /** 749 * TODO: Document what this is 750 */ 751 @Nullable 752 @Size(min = 2, max = 50) 753 public String getAlias() { 754 return alias; 755 } 756 757 /** 758 * Persisted in the database table. 759 */ 760 public void setAlias(String alias) { 761 this.alias = alias; 762 } 763 764 /** 765 * TODO: Document what this is 766 * TODO: are both alias & abbreviation needed? 767 */ 768 @Nullable 769 @Size(min = 1, max = 50) 770 public String getAbbreviation() { 771 return abbreviation; 772 } 773 774 /** 775 * Persisted in the database table. 776 */ 777 public void setAbbreviation(String abbreviation) { 778 this.abbreviation = abbreviation; 779 } 780 781 @NotNull 782 public Language getLanguage() { 783 return language; 784 } 785 786 /** 787 * Persisted in the database table. 788 */ 789 public void setLanguage(Language language) { 790 this.language = language; 791 } 792 793 @HttpURI 794 @Nullable 795 public URI getHomepage() { 796 return homepage; 797 } 798 799 /** 800 * Persisted in the database table. 801 */ 802 public void setHomepage(URI homepage) { 803 this.homepage = homepage; 804 } 805 806 @HttpURI 807 @Nullable 808 public URI getLogoUrl() { 809 return logoUrl; 810 } 811 812 /** 813 * Persisted in the database table. 814 */ 815 public void setLogoUrl(URI logoUrl) { 816 this.logoUrl = logoUrl; 817 } 818 819 /** 820 * The exact form of how to cite this dataset. 821 */ 822 @Nullable 823 @Valid 824 public Citation getCitation() { 825 return citation; 826 } 827 828 /** 829 * Persisted in the database table. 830 */ 831 public void setCitation(Citation citation) { 832 this.citation = citation; 833 } 834 835 /** 836 * A generated list of contacts used in the citation text when it is generated by the GBIF API. 837 */ 838 @Nullable 839 public List<CitationContact> getContactsCitation() { 840 return contactsCitation; 841 } 842 843 public void setContactsCitation(List<CitationContact> contactsCitation) { 844 this.contactsCitation = contactsCitation; 845 } 846 847 /** 848 * Any kind of (copy)rights/IPR statements that apply to the datasets data. 849 */ 850 @Nullable 851 @Size(min = 1) 852 public String getRights() { 853 return rights; 854 } 855 856 /** 857 * Persisted in the database table. 858 */ 859 public void setRights(String rights) { 860 this.rights = rights; 861 } 862 863 public boolean isLockedForAutoUpdate() { 864 return lockedForAutoUpdate; 865 } 866 867 /** 868 * Persisted in the database table. 869 */ 870 public void setLockedForAutoUpdate(boolean lockedForAutoUpdate) { 871 this.lockedForAutoUpdate = lockedForAutoUpdate; 872 } 873 874 @Override 875 public String getCreatedBy() { 876 return createdBy; 877 } 878 879 /** 880 * Persisted in the database table. 881 */ 882 @Override 883 public void setCreatedBy(String createdBy) { 884 this.createdBy = createdBy; 885 } 886 887 @Override 888 public String getModifiedBy() { 889 return modifiedBy; 890 } 891 892 /** 893 * Persisted in the database table. 894 */ 895 @Override 896 public void setModifiedBy(String modifiedBy) { 897 this.modifiedBy = modifiedBy; 898 } 899 900 @Override 901 public List<Contact> getContacts() { 902 return contacts; 903 } 904 905 @Override 906 public void setContacts(List<Contact> contacts) { 907 this.contacts = contacts; 908 } 909 910 @Override 911 public List<Endpoint> getEndpoints() { 912 return endpoints; 913 } 914 915 @Override 916 public void setEndpoints(List<Endpoint> endpoints) { 917 this.endpoints = endpoints; 918 } 919 920 @Override 921 public void addEndpoint(Endpoint endpoint) { 922 endpoints.add(endpoint); 923 } 924 925 @Override 926 public List<MachineTag> getMachineTags() { 927 return machineTags; 928 } 929 930 @Override 931 public void setMachineTags(List<MachineTag> machineTags) { 932 this.machineTags = machineTags; 933 } 934 935 @Override 936 public void addMachineTag(MachineTag machineTag) { 937 machineTags.add(machineTag); 938 } 939 940 @Override 941 public List<Tag> getTags() { 942 return tags; 943 } 944 945 @Override 946 public void setTags(List<Tag> tags) { 947 this.tags = tags; 948 } 949 950 @Override 951 public List<Identifier> getIdentifiers() { 952 return identifiers; 953 } 954 955 @Override 956 public void setIdentifiers(List<Identifier> identifiers) { 957 this.identifiers = identifiers; 958 } 959 960 @Override 961 public List<Comment> getComments() { 962 return comments; 963 } 964 965 @Override 966 public void setComments(List<Comment> comments) { 967 this.comments = comments; 968 } 969 970 public List<Citation> getBibliographicCitations() { 971 return bibliographicCitations; 972 } 973 974 public void setBibliographicCitations(List<Citation> bibliographicCitations) { 975 this.bibliographicCitations = bibliographicCitations; 976 } 977 978 public List<CuratorialUnitComposite> getCuratorialUnits() { 979 return curatorialUnits; 980 } 981 982 public void setCuratorialUnits(List<CuratorialUnitComposite> curatorialUnits) { 983 this.curatorialUnits = curatorialUnits; 984 } 985 986 public List<TaxonomicCoverages> getTaxonomicCoverages() { 987 return taxonomicCoverages; 988 } 989 990 public void setTaxonomicCoverages(List<TaxonomicCoverages> taxonomicCoverages) { 991 this.taxonomicCoverages = taxonomicCoverages; 992 } 993 994 public String getGeographicCoverageDescription() { 995 return geographicCoverageDescription; 996 } 997 998 public void setGeographicCoverageDescription(String geographicCoverageDescription) { 999 this.geographicCoverageDescription = geographicCoverageDescription; 1000 } 1001 1002 public List<GeospatialCoverage> getGeographicCoverages() { 1003 return geographicCoverages; 1004 } 1005 1006 public void setGeographicCoverages(List<GeospatialCoverage> geographicCoverages) { 1007 this.geographicCoverages = geographicCoverages; 1008 } 1009 1010 public List<TemporalCoverage> getTemporalCoverages() { 1011 return temporalCoverages; 1012 } 1013 1014 public void setTemporalCoverages(List<TemporalCoverage> temporalCoverages) { 1015 this.temporalCoverages = temporalCoverages; 1016 } 1017 1018 public List<KeywordCollection> getKeywordCollections() { 1019 return keywordCollections; 1020 } 1021 1022 public void setKeywordCollections(List<KeywordCollection> keywordCollections) { 1023 this.keywordCollections = keywordCollections; 1024 } 1025 1026 public Project getProject() { 1027 return project; 1028 } 1029 1030 public void setProject(Project project) { 1031 this.project = project; 1032 } 1033 1034 public SamplingDescription getSamplingDescription() { 1035 return samplingDescription; 1036 } 1037 1038 public void setSamplingDescription(SamplingDescription samplingDescription) { 1039 this.samplingDescription = samplingDescription; 1040 } 1041 1042 public Set<Country> getCountryCoverage() { 1043 return countryCoverage; 1044 } 1045 1046 public void setCountryCoverage(Set<Country> countryCoverage) { 1047 this.countryCoverage = countryCoverage; 1048 } 1049 1050 public List<Collection> getCollections() { 1051 return collections; 1052 } 1053 1054 public void setCollections(List<Collection> collections) { 1055 this.collections = collections; 1056 } 1057 1058 public List<DataDescription> getDataDescriptions() { 1059 return dataDescriptions; 1060 } 1061 1062 public void setDataDescriptions(List<DataDescription> dataDescriptions) { 1063 this.dataDescriptions = dataDescriptions; 1064 } 1065 1066 public Language getDataLanguage() { 1067 return dataLanguage; 1068 } 1069 1070 public void setDataLanguage(Language dataLanguage) { 1071 this.dataLanguage = dataLanguage; 1072 } 1073 1074 public String getPurpose() { 1075 return purpose; 1076 } 1077 1078 public void setPurpose(String purpose) { 1079 this.purpose = purpose; 1080 } 1081 1082 @Nullable 1083 public String getIntroduction() { 1084 return introduction; 1085 } 1086 1087 public void setIntroduction(String introduction) { 1088 this.introduction = introduction; 1089 } 1090 1091 @Nullable 1092 public String getGettingStarted() { 1093 return gettingStarted; 1094 } 1095 1096 public void setGettingStarted(String gettingStarted) { 1097 this.gettingStarted = gettingStarted; 1098 } 1099 1100 @Nullable 1101 public String getAcknowledgements() { 1102 return acknowledgements; 1103 } 1104 1105 public void setAcknowledgements(String acknowledgements) { 1106 this.acknowledgements = acknowledgements; 1107 } 1108 1109 public String getAdditionalInfo() { 1110 return additionalInfo; 1111 } 1112 1113 public void setAdditionalInfo(String additionalInfo) { 1114 this.additionalInfo = additionalInfo; 1115 } 1116 1117 public Date getPubDate() { 1118 return pubDate; 1119 } 1120 1121 public void setPubDate(Date pubDate) { 1122 this.pubDate = pubDate; 1123 } 1124 1125 @Nullable 1126 @Valid 1127 public DwcA getDwca() { 1128 return dwca; 1129 } 1130 1131 public void setDwca(DwcA dwca) { 1132 this.dwca = dwca; 1133 } 1134 1135 public Set<String> getCategory() { 1136 return category; 1137 } 1138 1139 public void setCategory(Set<String> category) { 1140 this.category = category; 1141 } 1142 1143 @Override 1144 public boolean equals(Object o) { 1145 if (this == o) { 1146 return true; 1147 } 1148 if (o == null || getClass() != o.getClass()) { 1149 return false; 1150 } 1151 Dataset dataset = (Dataset) o; 1152 return external == dataset.external 1153 && numConstituents == dataset.numConstituents 1154 && lockedForAutoUpdate == dataset.lockedForAutoUpdate 1155 && Objects.equals(key, dataset.key) 1156 && Objects.equals(parentDatasetKey, dataset.parentDatasetKey) 1157 && Objects.equals(duplicateOfDatasetKey, dataset.duplicateOfDatasetKey) 1158 && Objects.equals(installationKey, dataset.installationKey) 1159 && Objects.equals(publishingOrganizationKey, dataset.publishingOrganizationKey) 1160 && Objects.equals(publishingOrganizationName, dataset.publishingOrganizationName) 1161 && Objects.equals(networkKeys, dataset.networkKeys) 1162 && Objects.equals(doi, dataset.doi) 1163 && Objects.equals(version, dataset.version) 1164 && type == dataset.type 1165 && subtype == dataset.subtype 1166 && Objects.equals(shortName, dataset.shortName) 1167 && Objects.equals(title, dataset.title) 1168 && Objects.equals(alias, dataset.alias) 1169 && Objects.equals(abbreviation, dataset.abbreviation) 1170 && Objects.equals(description, dataset.description) 1171 && language == dataset.language 1172 && Objects.equals(homepage, dataset.homepage) 1173 && Objects.equals(logoUrl, dataset.logoUrl) 1174 && Objects.equals(citation, dataset.citation) 1175 && Objects.equals(contactsCitation, dataset.contactsCitation) 1176 && Objects.equals(rights, dataset.rights) 1177 && Objects.equals(createdBy, dataset.createdBy) 1178 && Objects.equals(modifiedBy, dataset.modifiedBy) 1179 && Objects.equals(created, dataset.created) 1180 && Objects.equals(modified, dataset.modified) 1181 && Objects.equals(deleted, dataset.deleted) 1182 && Objects.equals(contacts, dataset.contacts) 1183 && Objects.equals(endpoints, dataset.endpoints) 1184 && Objects.equals(machineTags, dataset.machineTags) 1185 && Objects.equals(tags, dataset.tags) 1186 && Objects.equals(identifiers, dataset.identifiers) 1187 && Objects.equals(comments, dataset.comments) 1188 && Objects.equals(bibliographicCitations, dataset.bibliographicCitations) 1189 && Objects.equals(curatorialUnits, dataset.curatorialUnits) 1190 && Objects.equals(taxonomicCoverages, dataset.taxonomicCoverages) 1191 && Objects.equals(geographicCoverageDescription, dataset.geographicCoverageDescription) 1192 && Objects.equals(geographicCoverages, dataset.geographicCoverages) 1193 && Objects.equals(temporalCoverages, dataset.temporalCoverages) 1194 && Objects.equals(keywordCollections, dataset.keywordCollections) 1195 && Objects.equals(project, dataset.project) 1196 && Objects.equals(samplingDescription, dataset.samplingDescription) 1197 && Objects.equals(countryCoverage, dataset.countryCoverage) 1198 && Objects.equals(collections, dataset.collections) 1199 && Objects.equals(dataDescriptions, dataset.dataDescriptions) 1200 && dataLanguage == dataset.dataLanguage 1201 && Objects.equals(purpose, dataset.purpose) 1202 && Objects.equals(introduction, dataset.introduction) 1203 && Objects.equals(gettingStarted, dataset.gettingStarted) 1204 && Objects.equals(acknowledgements, dataset.acknowledgements) 1205 && Objects.equals(additionalInfo, dataset.additionalInfo) 1206 && Objects.equals(pubDate, dataset.pubDate) 1207 && maintenanceUpdateFrequency == dataset.maintenanceUpdateFrequency 1208 && Objects.equals(maintenanceDescription, dataset.maintenanceDescription) 1209 && license == dataset.license 1210 && Objects.equals(dwca, dataset.dwca) 1211 && Objects.equals(category, dataset.category); 1212 } 1213 1214 @Override 1215 public int hashCode() { 1216 return Objects.hash( 1217 key, 1218 parentDatasetKey, 1219 duplicateOfDatasetKey, 1220 installationKey, 1221 publishingOrganizationKey, 1222 publishingOrganizationName, 1223 networkKeys, 1224 doi, 1225 version, 1226 external, 1227 numConstituents, 1228 type, 1229 subtype, 1230 shortName, 1231 title, 1232 alias, 1233 abbreviation, 1234 description, 1235 language, 1236 homepage, 1237 logoUrl, 1238 citation, 1239 contactsCitation, 1240 rights, 1241 lockedForAutoUpdate, 1242 createdBy, 1243 modifiedBy, 1244 created, 1245 modified, 1246 deleted, 1247 contacts, 1248 endpoints, 1249 machineTags, 1250 tags, 1251 identifiers, 1252 comments, 1253 bibliographicCitations, 1254 curatorialUnits, 1255 taxonomicCoverages, 1256 geographicCoverageDescription, 1257 geographicCoverages, 1258 temporalCoverages, 1259 keywordCollections, 1260 project, 1261 samplingDescription, 1262 countryCoverage, 1263 collections, 1264 dataDescriptions, 1265 dataLanguage, 1266 purpose, 1267 introduction, 1268 gettingStarted, 1269 acknowledgements, 1270 additionalInfo, 1271 pubDate, 1272 maintenanceUpdateFrequency, 1273 maintenanceDescription, 1274 license, 1275 dwca, 1276 category); 1277 } 1278 1279 @Override 1280 public String toString() { 1281 return new StringJoiner(", ", Dataset.class.getSimpleName() + "[", "]") 1282 .add("key=" + key) 1283 .add("parentDatasetKey=" + parentDatasetKey) 1284 .add("duplicateOfDatasetKey=" + duplicateOfDatasetKey) 1285 .add("installationKey=" + installationKey) 1286 .add("publishingOrganizationKey=" + publishingOrganizationKey) 1287 .add("publishingOrganizationName=" + publishingOrganizationName) 1288 .add("networkKeys=" + networkKeys) 1289 .add("doi=" + doi) 1290 .add("version='" + version + "'") 1291 .add("external=" + external) 1292 .add("numConstituents=" + numConstituents) 1293 .add("type=" + type) 1294 .add("subtype=" + subtype) 1295 .add("shortName='" + shortName + "'") 1296 .add("title='" + title + "'") 1297 .add("alias='" + alias + "'") 1298 .add("abbreviation='" + abbreviation + "'") 1299 .add("description='" + description + "'") 1300 .add("language=" + language) 1301 .add("homepage=" + homepage) 1302 .add("logoUrl=" + logoUrl) 1303 .add("citation=" + citation) 1304 .add("contactsCitation=" + contactsCitation) 1305 .add("rights='" + rights + "'") 1306 .add("lockedForAutoUpdate=" + lockedForAutoUpdate) 1307 .add("createdBy='" + createdBy + "'") 1308 .add("modifiedBy='" + modifiedBy + "'") 1309 .add("created=" + created) 1310 .add("modified=" + modified) 1311 .add("deleted=" + deleted) 1312 .add("contacts=" + contacts) 1313 .add("endpoints=" + endpoints) 1314 .add("machineTags=" + machineTags) 1315 .add("tags=" + tags) 1316 .add("identifiers=" + identifiers) 1317 .add("comments=" + comments) 1318 .add("bibliographicCitations=" + bibliographicCitations) 1319 .add("curatorialUnits=" + curatorialUnits) 1320 .add("taxonomicCoverages=" + taxonomicCoverages) 1321 .add("geographicCoverageDescription='" + geographicCoverageDescription + "'") 1322 .add("geographicCoverages=" + geographicCoverages) 1323 .add("temporalCoverages=" + temporalCoverages) 1324 .add("keywordCollections=" + keywordCollections) 1325 .add("project=" + project) 1326 .add("samplingDescription=" + samplingDescription) 1327 .add("countryCoverage=" + countryCoverage) 1328 .add("collections=" + collections) 1329 .add("dataDescriptions=" + dataDescriptions) 1330 .add("dataLanguage=" + dataLanguage) 1331 .add("purpose='" + purpose + "'") 1332 .add("introduction='" + introduction + "'") 1333 .add("gettingStarted='" + gettingStarted + "'") 1334 .add("acknowledgements='" + acknowledgements + "'") 1335 .add("additionalInfo='" + additionalInfo + "'") 1336 .add("pubDate=" + pubDate) 1337 .add("maintenanceUpdateFrequency=" + maintenanceUpdateFrequency) 1338 .add("maintenanceDescription='" + maintenanceDescription + "'") 1339 .add("license=" + license) 1340 .add("dwca=" + dwca) 1341 .add("category=" + category) 1342 .toString(); 1343 } 1344 1345 /** 1346 * Only checks the persisted properties, excluding the server controlled fields (key, created, license etc). 1347 * Does not include the nested properties. 1348 */ 1349 @Override 1350 public boolean lenientEquals(Dataset other) { 1351 if (this == other) { 1352 return true; 1353 } 1354 return Objects.equals(this.parentDatasetKey, other.parentDatasetKey) 1355 && Objects.equals(this.duplicateOfDatasetKey, other.duplicateOfDatasetKey) 1356 && Objects.equals(this.installationKey, other.installationKey) 1357 && Objects.equals(this.publishingOrganizationKey, other.publishingOrganizationKey) 1358 && Objects.equals(this.publishingOrganizationName, other.publishingOrganizationName) 1359 && Objects.equals(this.doi, other.doi) 1360 && Objects.equals(this.external, other.external) 1361 && Objects.equals(this.type, other.type) 1362 && Objects.equals(this.subtype, other.subtype) 1363 && Objects.equals(this.title, other.title) 1364 && Objects.equals(this.alias, other.alias) 1365 && Objects.equals(this.abbreviation, other.abbreviation) 1366 && Objects.equals(this.description, other.description) 1367 && Objects.equals(this.language, other.language) 1368 && Objects.equals(this.homepage, other.homepage) 1369 && Objects.equals(this.logoUrl, other.logoUrl) 1370 && Objects.equals(this.citation, other.citation) 1371 && Objects.equals(this.rights, other.rights) 1372 && Objects.equals(this.lockedForAutoUpdate, other.lockedForAutoUpdate) 1373 && Objects.equals(this.deleted, other.deleted) 1374 && Objects.equals(this.maintenanceUpdateFrequency, other.maintenanceUpdateFrequency) 1375 && Objects.equals(this.maintenanceDescription, other.maintenanceDescription) 1376 && Objects.equals(this.dwca, other.dwca) 1377 && Objects.equals(this.category, other.category); 1378 } 1379 1380 /** 1381 * Metadata of dataset that has been published as a Darwin Core Archive (DwC-A). 1382 */ 1383 @NoArgsConstructor 1384 @Data 1385 public static class DwcA { 1386 @Schema( 1387 description = "This attribute, within the <core>, indicates the specific " + 1388 "type of data being represented in the core data file.**." 1389 ) 1390 private String coreType; 1391 1392 @Schema( 1393 description = "This attribute, within the <extensions>, indicates the specific " + 1394 "type of data being represented in the associated extension data file.**." 1395 ) 1396 private List<String> extensions; 1397 1398 @Schema( 1399 description = "Timestamp of when the dataset was modified.", 1400 accessMode = Schema.AccessMode.READ_ONLY 1401 ) 1402 @Null(groups = {PrePersist.class}) 1403 private Date modified; 1404 1405 1406 public String getCoreType() { 1407 return coreType; 1408 } 1409 1410 public void setCoreType(String coreType) { 1411 this.coreType = coreType; 1412 } 1413 1414 @Nullable 1415 public List<String> getExtensions() { 1416 return extensions; 1417 } 1418 1419 public void setExtensions(List<String> extensions) { 1420 this.extensions = extensions; 1421 } 1422 1423 @Nullable 1424 public Date getModified() { 1425 return modified; 1426 } 1427 1428 public void setModified(Date modified) { 1429 this.modified = modified; 1430 } 1431 } 1432}