001/* 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.entity; 021 022import ca.uhn.fhir.jpa.model.entity.ResourceTable; 023import ca.uhn.fhir.util.ValidateUtil; 024import jakarta.annotation.Nonnull; 025import jakarta.persistence.Column; 026import jakarta.persistence.Entity; 027import jakarta.persistence.EnumType; 028import jakarta.persistence.Enumerated; 029import jakarta.persistence.FetchType; 030import jakarta.persistence.ForeignKey; 031import jakarta.persistence.GeneratedValue; 032import jakarta.persistence.GenerationType; 033import jakarta.persistence.Id; 034import jakarta.persistence.Index; 035import jakarta.persistence.JoinColumn; 036import jakarta.persistence.OneToMany; 037import jakarta.persistence.OneToOne; 038import jakarta.persistence.SequenceGenerator; 039import jakarta.persistence.Table; 040import jakarta.persistence.Temporal; 041import jakarta.persistence.TemporalType; 042import jakarta.persistence.Transient; 043import jakarta.persistence.UniqueConstraint; 044import org.apache.commons.lang3.builder.EqualsBuilder; 045import org.apache.commons.lang3.builder.ToStringBuilder; 046import org.apache.commons.lang3.builder.ToStringStyle; 047import org.hibernate.annotations.ColumnDefault; 048 049import java.io.Serializable; 050import java.util.ArrayList; 051import java.util.Date; 052import java.util.List; 053 054import static org.apache.commons.lang3.StringUtils.left; 055import static org.apache.commons.lang3.StringUtils.length; 056 057@Table( 058 name = "TRM_VALUESET", 059 uniqueConstraints = { 060 @UniqueConstraint( 061 name = "IDX_VALUESET_URL", 062 columnNames = {"URL", "VER"}) 063 }, 064 indexes = { 065 // must have same name that indexed FK or SchemaMigrationTest complains because H2 sets this index 066 // automatically 067 @Index(name = "FK_TRMVALUESET_RES", columnList = "RES_ID") 068 }) 069@Entity() 070public class TermValueSet implements Serializable { 071 public static final int MAX_EXPANSION_STATUS_LENGTH = 50; 072 public static final int MAX_NAME_LENGTH = 200; 073 public static final int MAX_URL_LENGTH = 200; 074 public static final int MAX_VER_LENGTH = 200; 075 private static final long serialVersionUID = 1L; 076 077 @Id() 078 @SequenceGenerator(name = "SEQ_VALUESET_PID", sequenceName = "SEQ_VALUESET_PID") 079 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_VALUESET_PID") 080 @Column(name = "PID") 081 private Long myId; 082 083 @Column(name = "URL", nullable = false, length = MAX_URL_LENGTH) 084 private String myUrl; 085 086 @Column(name = "VER", nullable = true, length = MAX_VER_LENGTH) 087 private String myVersion; 088 089 @OneToOne() 090 @JoinColumn( 091 name = "RES_ID", 092 referencedColumnName = "RES_ID", 093 nullable = false, 094 updatable = false, 095 foreignKey = @ForeignKey(name = "FK_TRMVALUESET_RES")) 096 private ResourceTable myResource; 097 098 @Column(name = "RES_ID", insertable = false, updatable = false) 099 private Long myResourcePid; 100 101 @Column(name = "VSNAME", nullable = true, length = MAX_NAME_LENGTH) 102 private String myName; 103 104 @OneToMany(mappedBy = "myValueSet", fetch = FetchType.LAZY) 105 private List<TermValueSetConcept> myConcepts; 106 107 @Column(name = "TOTAL_CONCEPTS", nullable = false) 108 @ColumnDefault("0") 109 private Long myTotalConcepts; 110 111 @Column(name = "TOTAL_CONCEPT_DESIGNATIONS", nullable = false) 112 @ColumnDefault("0") 113 private Long myTotalConceptDesignations; 114 115 @Enumerated(EnumType.STRING) 116 @Column(name = "EXPANSION_STATUS", nullable = false, length = MAX_EXPANSION_STATUS_LENGTH) 117 private TermValueSetPreExpansionStatusEnum myExpansionStatus; 118 119 @Temporal(TemporalType.TIMESTAMP) 120 @Column(name = "EXPANDED_AT", nullable = true) 121 private Date myExpansionTimestamp; 122 123 @Transient 124 private transient Integer myHashCode; 125 126 public TermValueSet() { 127 super(); 128 myExpansionStatus = TermValueSetPreExpansionStatusEnum.NOT_EXPANDED; 129 myTotalConcepts = 0L; 130 myTotalConceptDesignations = 0L; 131 } 132 133 public Date getExpansionTimestamp() { 134 return myExpansionTimestamp; 135 } 136 137 public void setExpansionTimestamp(Date theExpansionTimestamp) { 138 myExpansionTimestamp = theExpansionTimestamp; 139 } 140 141 public Long getId() { 142 return myId; 143 } 144 145 public String getUrl() { 146 return myUrl; 147 } 148 149 public TermValueSet setUrl(@Nonnull String theUrl) { 150 ValidateUtil.isNotBlankOrThrowIllegalArgument(theUrl, "theUrl must not be null or empty"); 151 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 152 theUrl, MAX_URL_LENGTH, "URL exceeds maximum length (" + MAX_URL_LENGTH + "): " + length(theUrl)); 153 myUrl = theUrl; 154 return this; 155 } 156 157 public ResourceTable getResource() { 158 return myResource; 159 } 160 161 public TermValueSet setResource(ResourceTable theResource) { 162 myResource = theResource; 163 return this; 164 } 165 166 public String getName() { 167 return myName; 168 } 169 170 public TermValueSet setName(String theName) { 171 myName = left(theName, MAX_NAME_LENGTH); 172 return this; 173 } 174 175 public List<TermValueSetConcept> getConcepts() { 176 if (myConcepts == null) { 177 myConcepts = new ArrayList<>(); 178 } 179 180 return myConcepts; 181 } 182 183 public Long getTotalConcepts() { 184 return myTotalConcepts; 185 } 186 187 public TermValueSet setTotalConcepts(Long theTotalConcepts) { 188 myTotalConcepts = theTotalConcepts; 189 return this; 190 } 191 192 public TermValueSet decrementTotalConcepts() { 193 if (myTotalConcepts > 0) { 194 myTotalConcepts--; 195 } 196 return this; 197 } 198 199 public TermValueSet incrementTotalConcepts() { 200 myTotalConcepts++; 201 return this; 202 } 203 204 public Long getTotalConceptDesignations() { 205 return myTotalConceptDesignations; 206 } 207 208 public TermValueSet setTotalConceptDesignations(Long theTotalConceptDesignations) { 209 myTotalConceptDesignations = theTotalConceptDesignations; 210 return this; 211 } 212 213 public TermValueSet decrementTotalConceptDesignations() { 214 if (myTotalConceptDesignations > 0) { 215 myTotalConceptDesignations--; 216 } 217 return this; 218 } 219 220 public TermValueSet incrementTotalConceptDesignations() { 221 myTotalConceptDesignations++; 222 return this; 223 } 224 225 public TermValueSetPreExpansionStatusEnum getExpansionStatus() { 226 return myExpansionStatus; 227 } 228 229 public void setExpansionStatus(TermValueSetPreExpansionStatusEnum theExpansionStatus) { 230 myExpansionStatus = theExpansionStatus; 231 } 232 233 public String getVersion() { 234 return myVersion; 235 } 236 237 public TermValueSet setVersion(String theVersion) { 238 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 239 theVersion, 240 MAX_VER_LENGTH, 241 "Version exceeds maximum length (" + MAX_VER_LENGTH + "): " + length(theVersion)); 242 myVersion = theVersion; 243 return this; 244 } 245 246 @Override 247 public boolean equals(Object theO) { 248 if (this == theO) return true; 249 250 if (!(theO instanceof TermValueSet)) return false; 251 252 TermValueSet that = (TermValueSet) theO; 253 254 return new EqualsBuilder().append(getUrl(), that.getUrl()).isEquals(); 255 } 256 257 @Override 258 public int hashCode() { 259 if (myHashCode == null) { 260 myHashCode = getUrl().hashCode(); 261 } 262 return myHashCode; 263 } 264 265 @Override 266 public String toString() { 267 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 268 .append("id", myId) 269 .append("url", myUrl) 270 .append("version", myVersion) 271 .append("resourcePid", myResourcePid) 272 .append("name", myName) 273 .append(myConcepts != null ? ("conceptCount=" + myConcepts.size()) : ("concepts=(null)")) 274 .append("totalConcepts", myTotalConcepts) 275 .append("totalConceptDesignations", myTotalConceptDesignations) 276 .append("expansionStatus", myExpansionStatus) 277 .append(myResource != null ? ("resId=" + myResource) : ("resource=(null)")) 278 .toString(); 279 } 280}