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