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 io.swagger.v3.oas.annotations.media.Schema;
019
020import org.gbif.api.util.IdentifierUtils;
021import org.gbif.api.vocabulary.IdentifierType;
022
023import java.io.Serializable;
024import java.util.Date;
025import java.util.Objects;
026import java.util.StringJoiner;
027
028import javax.annotation.Nullable;
029import javax.validation.constraints.Min;
030import javax.validation.constraints.NotNull;
031import javax.validation.constraints.Null;
032import javax.validation.constraints.Size;
033
034import com.fasterxml.jackson.annotation.JsonIgnore;
035
036public class Identifier implements Serializable, LenientEquals<Identifier> {
037
038  @Schema(
039    description = "Database identifier for the identifier",
040    accessMode = Schema.AccessMode.READ_ONLY
041  )
042  private Integer key;
043
044  private IdentifierType type;
045
046  @Schema(description = "Value for the identifier")
047  private String identifier;
048
049  @Schema(
050    description = "The GBIF username of the creator of the identifier",
051    accessMode = Schema.AccessMode.READ_ONLY
052  )
053  private String createdBy;
054
055  @Schema(
056    description = "Timestamp of when the identifier was created",
057    accessMode = Schema.AccessMode.READ_ONLY
058  )
059  private Date created;
060
061  public Identifier() {}
062
063  public Identifier(IdentifierType type, String identifier) {
064    this.type = type;
065    this.identifier = identifier;
066  }
067
068  @Null(groups = {PrePersist.class})
069  @NotNull(groups = {PostPersist.class})
070  @Min(1)
071  public Integer getKey() {
072    return key;
073  }
074
075  public void setKey(Integer key) {
076    this.key = key;
077  }
078
079  @NotNull
080  public IdentifierType getType() {
081    return type;
082  }
083
084  public void setType(IdentifierType type) {
085    this.type = type;
086  }
087
088  @NotNull
089  @Size(min = 1)
090  public String getIdentifier() {
091    return identifier;
092  }
093
094  public void setIdentifier(String identifier) {
095    this.identifier = identifier;
096  }
097
098  @Size(min = 3)
099  public String getCreatedBy() {
100    return createdBy;
101  }
102
103  public void setCreatedBy(String createdBy) {
104    this.createdBy = createdBy;
105  }
106
107  @Null(groups = {PrePersist.class})
108  @NotNull(groups = {PostPersist.class})
109  public Date getCreated() {
110    return created;
111  }
112
113  public void setCreated(Date created) {
114    this.created = created;
115  }
116
117  /**
118   * Creates a http link for an identifier if possible by passing it to some known resolvers for the specific id type.
119   * If no link can be constructed, null is returned.
120   *
121   * @return the url or null if it cannot be created
122   *
123   * @see org.gbif.api.util.IdentifierUtils#getIdentifierLink(String, org.gbif.api.vocabulary.IdentifierType)
124   */
125  @Nullable
126  @JsonIgnore
127  public String getIdentifierLink() {
128    return IdentifierUtils.getIdentifierLink(identifier, type);
129  }
130
131  @Override
132  public boolean equals(Object o) {
133    if (this == o) {
134      return true;
135    }
136    if (o == null || getClass() != o.getClass()) {
137      return false;
138    }
139    Identifier that = (Identifier) o;
140    return Objects.equals(key, that.key)
141        && type == that.type
142        && Objects.equals(identifier, that.identifier)
143        && Objects.equals(createdBy, that.createdBy)
144        && Objects.equals(created, that.created);
145  }
146
147  @Override
148  public int hashCode() {
149    return Objects.hash(key, type, identifier, createdBy, created);
150  }
151
152  @Override
153  public String toString() {
154    return new StringJoiner(", ", Identifier.class.getSimpleName() + "[", "]")
155        .add("key=" + key)
156        .add("type=" + type)
157        .add("identifier='" + identifier + "'")
158        .add("createdBy='" + createdBy + "'")
159        .add("created=" + created)
160        .toString();
161  }
162
163  /**
164   * A lenient equality check ignoring server controlled values (createdBy, key etc).
165   */
166  @Override
167  public boolean lenientEquals(Identifier other) {
168    if (this == other) {
169      return true;
170    }
171    return Objects.equals(this.type, other.type)
172        && Objects.equals(this.identifier, other.identifier);
173  }
174}