001/* 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2023 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.util.ValidateUtil; 023import org.apache.commons.lang3.builder.EqualsBuilder; 024import org.apache.commons.lang3.builder.HashCodeBuilder; 025import org.apache.commons.lang3.builder.ToStringBuilder; 026import org.apache.commons.lang3.builder.ToStringStyle; 027 028import java.io.Serializable; 029import java.util.ArrayList; 030import java.util.List; 031import javax.annotation.Nonnull; 032import javax.persistence.Column; 033import javax.persistence.Entity; 034import javax.persistence.FetchType; 035import javax.persistence.ForeignKey; 036import javax.persistence.GeneratedValue; 037import javax.persistence.GenerationType; 038import javax.persistence.Id; 039import javax.persistence.JoinColumn; 040import javax.persistence.Lob; 041import javax.persistence.ManyToOne; 042import javax.persistence.OneToMany; 043import javax.persistence.SequenceGenerator; 044import javax.persistence.Table; 045import javax.persistence.Transient; 046import javax.persistence.UniqueConstraint; 047 048import static org.apache.commons.lang3.StringUtils.left; 049import static org.apache.commons.lang3.StringUtils.length; 050 051/* 052 * DM 2019-08-01 - Do not use IDX_VALUESET_CONCEPT_CS_CD or IDX_VALUESET_CONCEPT_CS_CODE; this was previously used as an index so reusing the name will 053 * bork up migration tasks. 054 */ 055@Table( 056 name = "TRM_VALUESET_CONCEPT", 057 uniqueConstraints = { 058 @UniqueConstraint( 059 name = "IDX_VS_CONCEPT_CSCD", 060 columnNames = {"VALUESET_PID", "SYSTEM_URL", "CODEVAL"}), 061 @UniqueConstraint( 062 name = "IDX_VS_CONCEPT_ORDER", 063 columnNames = {"VALUESET_PID", "VALUESET_ORDER"}) 064 }) 065@Entity() 066public class TermValueSetConcept implements Serializable { 067 private static final long serialVersionUID = 1L; 068 069 @Id() 070 @SequenceGenerator(name = "SEQ_VALUESET_CONCEPT_PID", sequenceName = "SEQ_VALUESET_CONCEPT_PID") 071 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_VALUESET_CONCEPT_PID") 072 @Column(name = "PID") 073 private Long myId; 074 075 @ManyToOne(fetch = FetchType.LAZY) 076 @JoinColumn( 077 name = "VALUESET_PID", 078 referencedColumnName = "PID", 079 nullable = false, 080 foreignKey = @ForeignKey(name = "FK_TRM_VALUESET_PID")) 081 private TermValueSet myValueSet; 082 083 @Column(name = "VALUESET_PID", insertable = false, updatable = false, nullable = false) 084 private Long myValueSetPid; 085 086 @Column(name = "INDEX_STATUS", nullable = true) 087 private Long myIndexStatus; 088 089 @Column(name = "VALUESET_ORDER", nullable = false) 090 private int myOrder; 091 092 @Transient 093 private String myValueSetUrl; 094 095 @Transient 096 private String myValueSetName; 097 098 @Column(name = "SOURCE_PID", nullable = true) 099 private Long mySourceConceptPid; 100 101 @Lob 102 @Column(name = "SOURCE_DIRECT_PARENT_PIDS", nullable = true) 103 private String mySourceConceptDirectParentPids; 104 105 @Column(name = "SYSTEM_URL", nullable = false, length = TermCodeSystem.MAX_URL_LENGTH) 106 private String mySystem; 107 108 @Column(name = "SYSTEM_VER", nullable = true, length = TermCodeSystemVersion.MAX_VERSION_LENGTH) 109 private String mySystemVer; 110 111 @Column(name = "CODEVAL", nullable = false, length = TermConcept.MAX_CODE_LENGTH) 112 private String myCode; 113 114 @Column(name = "DISPLAY", nullable = true, length = TermConcept.MAX_DESC_LENGTH) 115 private String myDisplay; 116 117 @OneToMany(mappedBy = "myConcept", fetch = FetchType.LAZY) 118 private List<TermValueSetConceptDesignation> myDesignations; 119 120 @Transient 121 private transient Integer myHashCode; 122 123 /** 124 * Constructor 125 */ 126 public TermValueSetConcept() { 127 super(); 128 } 129 130 public Long getId() { 131 return myId; 132 } 133 134 public TermValueSet getValueSet() { 135 return myValueSet; 136 } 137 138 public TermValueSetConcept setValueSet(TermValueSet theValueSet) { 139 myValueSet = theValueSet; 140 return this; 141 } 142 143 public int getOrder() { 144 return myOrder; 145 } 146 147 public TermValueSetConcept setOrder(int theOrder) { 148 myOrder = theOrder; 149 return this; 150 } 151 152 public String getValueSetUrl() { 153 if (myValueSetUrl == null) { 154 myValueSetUrl = getValueSet().getUrl(); 155 } 156 157 return myValueSetUrl; 158 } 159 160 public String getValueSetName() { 161 if (myValueSetName == null) { 162 myValueSetName = getValueSet().getName(); 163 } 164 165 return myValueSetName; 166 } 167 168 public String getSystem() { 169 return mySystem; 170 } 171 172 public TermValueSetConcept setSystem(@Nonnull String theSystem) { 173 ValidateUtil.isNotBlankOrThrowIllegalArgument(theSystem, "theSystem must not be null or empty"); 174 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 175 theSystem, 176 TermCodeSystem.MAX_URL_LENGTH, 177 "System exceeds maximum length (" + TermCodeSystem.MAX_URL_LENGTH + "): " + length(theSystem)); 178 mySystem = theSystem; 179 return this; 180 } 181 182 public String getSystemVersion() { 183 return mySystemVer; 184 } 185 186 public TermValueSetConcept setSystemVersion(String theSystemVersion) { 187 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 188 theSystemVersion, 189 TermCodeSystemVersion.MAX_VERSION_LENGTH, 190 "System version exceeds maximum length (" + TermCodeSystemVersion.MAX_VERSION_LENGTH + "): " 191 + length(theSystemVersion)); 192 mySystemVer = theSystemVersion; 193 return this; 194 } 195 196 public String getCode() { 197 return myCode; 198 } 199 200 public TermValueSetConcept setCode(@Nonnull String theCode) { 201 ValidateUtil.isNotBlankOrThrowIllegalArgument(theCode, "theCode must not be null or empty"); 202 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 203 theCode, 204 TermConcept.MAX_CODE_LENGTH, 205 "Code exceeds maximum length (" + TermConcept.MAX_CODE_LENGTH + "): " + length(theCode)); 206 myCode = theCode; 207 return this; 208 } 209 210 public String getDisplay() { 211 return myDisplay; 212 } 213 214 public TermValueSetConcept setDisplay(String theDisplay) { 215 myDisplay = left(theDisplay, TermConcept.MAX_DESC_LENGTH); 216 return this; 217 } 218 219 public List<TermValueSetConceptDesignation> getDesignations() { 220 if (myDesignations == null) { 221 myDesignations = new ArrayList<>(); 222 } 223 224 return myDesignations; 225 } 226 227 @Override 228 public boolean equals(Object theO) { 229 if (this == theO) return true; 230 231 if (!(theO instanceof TermValueSetConcept)) return false; 232 233 TermValueSetConcept that = (TermValueSetConcept) theO; 234 235 return new EqualsBuilder() 236 .append(myValueSetPid, that.myValueSetPid) 237 .append(getSystem(), that.getSystem()) 238 .append(getCode(), that.getCode()) 239 .isEquals(); 240 } 241 242 @Override 243 public int hashCode() { 244 if (myHashCode == null) { 245 myHashCode = new HashCodeBuilder(17, 37) 246 .append(myValueSetPid) 247 .append(getSystem()) 248 .append(getCode()) 249 .toHashCode(); 250 } 251 return myHashCode; 252 } 253 254 @Override 255 public String toString() { 256 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 257 .append("id", myId) 258 .append("order", myOrder) 259 .append("system", mySystem) 260 .append("code", myCode) 261 .append("valueSet", myValueSet != null ? myValueSet.getId() : "(null)") 262 .append("valueSetPid", myValueSetPid) 263 .append("valueSetUrl", this.getValueSetUrl()) 264 .append("valueSetName", this.getValueSetName()) 265 .append("display", myDisplay) 266 .append("designationCount", myDesignations != null ? myDesignations.size() : "(null)") 267 .append("parentPids", mySourceConceptDirectParentPids) 268 .toString(); 269 } 270 271 public Long getIndexStatus() { 272 return myIndexStatus; 273 } 274 275 public void setIndexStatus(Long theIndexStatus) { 276 myIndexStatus = theIndexStatus; 277 } 278 279 public void setSourceConceptPid(Long theSourceConceptPid) { 280 mySourceConceptPid = theSourceConceptPid; 281 } 282 283 public void setSourceConceptDirectParentPids(String theSourceConceptDirectParentPids) { 284 mySourceConceptDirectParentPids = theSourceConceptDirectParentPids; 285 } 286}