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 com.fasterxml.jackson.databind.ObjectMapper; 019 020import org.gbif.api.vocabulary.MetadataType; 021 022import java.io.Serializable; 023import java.util.Date; 024import java.util.Objects; 025import java.util.StringJoiner; 026import java.util.UUID; 027 028import jakarta.validation.constraints.Min; 029import jakarta.validation.constraints.NotNull; 030import jakarta.validation.constraints.Size; 031import jakarta.validation.constraints.AssertTrue; 032 033public class Metadata implements Serializable, LenientEquals<Metadata> { 034 035 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 036 037 private Integer key; 038 private UUID datasetKey; 039 private MetadataType type; 040 private String content; 041 private String contentJson; 042 043 private String createdBy; 044 private String modifiedBy; 045 private Date created; 046 private Date modified; 047 048 @Min(1) 049 public Integer getKey() { 050 return key; 051 } 052 053 public void setKey(Integer key) { 054 this.key = key; 055 } 056 057 @NotNull 058 public UUID getDatasetKey() { 059 return datasetKey; 060 } 061 062 public void setDatasetKey(UUID datasetKey) { 063 this.datasetKey = datasetKey; 064 } 065 066 @NotNull 067 public MetadataType getType() { 068 return type; 069 } 070 071 public void setType(MetadataType type) { 072 this.type = type; 073 } 074 075 @NotNull 076 @Size(min = 1) 077 public String getContent() { 078 return content; 079 } 080 081 public void setContent(String content) { 082 this.content = content; 083 } 084 085 public String getContentJson() { 086 return contentJson; 087 } 088 089 public void setContentJson(String contentJson) { 090 this.contentJson = contentJson; 091 } 092 093 @AssertTrue(message = "contentJson must be valid JSON") 094 public boolean isContentJsonValid() { 095 if (contentJson == null || contentJson.trim().isEmpty()) { 096 return true; 097 } 098 099 try { 100 OBJECT_MAPPER.readTree(contentJson); 101 return true; 102 } catch (Exception e) { 103 return false; 104 } 105 } 106 107 @NotNull 108 @Size(min = 3) 109 public String getCreatedBy() { 110 return createdBy; 111 } 112 113 public void setCreatedBy(String createdBy) { 114 this.createdBy = createdBy; 115 } 116 117 @NotNull 118 @Size(min = 3) 119 public String getModifiedBy() { 120 return modifiedBy; 121 } 122 123 public void setModifiedBy(String modifiedBy) { 124 this.modifiedBy = modifiedBy; 125 } 126 127 @NotNull 128 public Date getCreated() { 129 return created; 130 } 131 132 public void setCreated(Date created) { 133 this.created = created; 134 } 135 136 @NotNull 137 public Date getModified() { 138 return modified; 139 } 140 141 public void setModified(Date modified) { 142 this.modified = modified; 143 } 144 145 @Override 146 public boolean equals(Object o) { 147 if (this == o) { 148 return true; 149 } 150 if (o == null || getClass() != o.getClass()) { 151 return false; 152 } 153 Metadata metadata = (Metadata) o; 154 return Objects.equals(key, metadata.key) 155 && Objects.equals(datasetKey, metadata.datasetKey) 156 && type == metadata.type 157 && Objects.equals(content, metadata.content) 158 && Objects.equals(contentJson, metadata.contentJson) 159 && Objects.equals(createdBy, metadata.createdBy) 160 && Objects.equals(modifiedBy, metadata.modifiedBy) 161 && Objects.equals(created, metadata.created) 162 && Objects.equals(modified, metadata.modified); 163 } 164 165 @Override 166 public int hashCode() { 167 return Objects.hash(key, datasetKey, type, content, contentJson, createdBy, modifiedBy, created, modified); 168 } 169 170 @Override 171 public String toString() { 172 return new StringJoiner(", ", Metadata.class.getSimpleName() + "[", "]") 173 .add("key=" + key) 174 .add("datasetKey=" + datasetKey) 175 .add("type=" + type) 176 .add("content='" + content + "'") 177 .add("contentJson='" + contentJson + "'") 178 .add("createdBy='" + createdBy + "'") 179 .add("modifiedBy='" + modifiedBy + "'") 180 .add("created=" + created) 181 .add("modified=" + modified) 182 .toString(); 183 } 184 185 /** 186 * Does not include the key or server controlled values (created, createdBy etc). 187 */ 188 @Override 189 public boolean lenientEquals(Metadata other) { 190 if (this == other) { 191 return true; 192 } 193 if (other == null) return false; 194 return Objects.equals(this.datasetKey, other.datasetKey) 195 && Objects.equals(this.type, other.type) 196 && Objects.equals(this.content, other.content) 197 && Objects.equals(this.contentJson, other.contentJson); 198 } 199}