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.vocabulary.TagName; 021 022import java.io.Serializable; 023import java.util.Date; 024import java.util.Objects; 025import java.util.StringJoiner; 026 027import javax.validation.constraints.NotNull; 028import javax.validation.constraints.Null; 029import javax.validation.constraints.Size; 030 031/** 032 * A tag that has a namespace, name and a value. {@code created} and {@code createdBy} are automatically set upon 033 * persisting. 034 */ 035// TODO: Document the rules regarding duplicate names and values 036@SuppressWarnings("unused") 037public class MachineTag implements LenientEquals<MachineTag>, Serializable { 038 039 private static final long serialVersionUID = 3475968899219274852L; 040 041 @Schema( 042 description = "Identifier for the machine tag.", 043 accessMode = Schema.AccessMode.READ_ONLY 044 ) 045 private Integer key; 046 047 @Schema( 048 description = "The namespace for the machine tag." 049 ) 050 private String namespace; 051 052 @Schema( 053 description = "The name (within the namespace) of the machine tag." 054 ) 055 private String name; 056 057 @Schema( 058 description = "The value of the machine tag." 059 ) 060 private String value; 061 062 @Schema( 063 description = "The GBIF username of the creator of the machine tag.", 064 accessMode = Schema.AccessMode.READ_ONLY 065 ) 066 private String createdBy; 067 068 @Schema( 069 description = "Timestamp of when the machine tag was created.", 070 accessMode = Schema.AccessMode.READ_ONLY 071 ) 072 private Date created; 073 074 public static MachineTag newInstance(String namespace, String name, String value) { 075 return new MachineTag(namespace, name, value); 076 } 077 078 public static MachineTag newInstance(TagName tagName, String value) { 079 return new MachineTag(tagName, value); 080 } 081 082 public MachineTag() { 083 // Needed 084 } 085 086 /** 087 * This is the default constructor to create new Machine Tags which takes all user settable properties. 088 */ 089 public MachineTag(String namespace, String name, String value) { 090 this.namespace = namespace; 091 this.name = name; 092 this.value = value; 093 } 094 095 /** 096 * This is the other constructor to create new Machine Tags which takes all user settable properties. 097 */ 098 public MachineTag(TagName tagName, String value) { 099 this(tagName.getNamespace().getNamespace(), tagName.getName(), value); 100 } 101 102 @Null(groups = {PrePersist.class}) 103 @NotNull(groups = {PostPersist.class}) 104 public Integer getKey() { 105 return key; 106 } 107 108 public void setKey(Integer key) { 109 this.key = key; 110 } 111 112 @NotNull 113 @Size(min = 1, max = 255) 114 public String getNamespace() { 115 return namespace; 116 } 117 118 public void setNamespace(String namespace) { 119 this.namespace = namespace; 120 } 121 122 @NotNull 123 @Size(min = 1, max = 255) 124 public String getName() { 125 return name; 126 } 127 128 public void setName(String name) { 129 this.name = name; 130 } 131 132 @NotNull 133 @Size(min = 1, max = 700) 134 public String getValue() { 135 return value; 136 } 137 138 public void setValue(String value) { 139 this.value = value; 140 } 141 142 @Size(min = 3) 143 public String getCreatedBy() { 144 return createdBy; 145 } 146 147 public void setCreatedBy(String createdBy) { 148 this.createdBy = createdBy; 149 } 150 151 @Null(groups = {PrePersist.class}) 152 @NotNull(groups = {PostPersist.class}) 153 public Date getCreated() { 154 return created; 155 } 156 157 public void setCreated(Date created) { 158 this.created = created; 159 } 160 161 @Override 162 public boolean equals(Object o) { 163 if (this == o) { 164 return true; 165 } 166 if (o == null || getClass() != o.getClass()) { 167 return false; 168 } 169 MachineTag that = (MachineTag) o; 170 return Objects.equals(key, that.key) 171 && Objects.equals(namespace, that.namespace) 172 && Objects.equals(name, that.name) 173 && Objects.equals(value, that.value) 174 && Objects.equals(createdBy, that.createdBy) 175 && Objects.equals(created, that.created); 176 } 177 178 @Override 179 public int hashCode() { 180 return Objects.hash(key, namespace, name, value, createdBy, created); 181 } 182 183 @Override 184 public String toString() { 185 return new StringJoiner(", ", MachineTag.class.getSimpleName() + "[", "]") 186 .add("key=" + key) 187 .add("namespace='" + namespace + "'") 188 .add("name='" + name + "'") 189 .add("value='" + value + "'") 190 .add("createdBy='" + createdBy + "'") 191 .add("created=" + created) 192 .toString(); 193 } 194 195 /** 196 * This implementation of the {@link #equals(Object)} method does only check <em>business equality</em> and disregards 197 * automatically set and maintained fields like {@code createdBy, key} and possibly others in the future. 198 */ 199 @Override 200 public boolean lenientEquals(MachineTag other) { 201 if (this == other) { 202 return true; 203 } 204 205 return Objects.equals(this.namespace, other.namespace) 206 && Objects.equals(this.name, other.name) 207 && Objects.equals(this.value, other.value); 208 } 209}