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.persistence.Column; 025import jakarta.persistence.Entity; 026import jakarta.persistence.FetchType; 027import jakarta.persistence.ForeignKey; 028import jakarta.persistence.GeneratedValue; 029import jakarta.persistence.GenerationType; 030import jakarta.persistence.Id; 031import jakarta.persistence.Index; 032import jakarta.persistence.JoinColumn; 033import jakarta.persistence.ManyToOne; 034import jakarta.persistence.OneToMany; 035import jakarta.persistence.OneToOne; 036import jakarta.persistence.SequenceGenerator; 037import jakarta.persistence.Table; 038import jakarta.persistence.UniqueConstraint; 039import org.apache.commons.lang3.builder.EqualsBuilder; 040import org.apache.commons.lang3.builder.HashCodeBuilder; 041import org.apache.commons.lang3.builder.ToStringBuilder; 042import org.apache.commons.lang3.builder.ToStringStyle; 043 044import java.io.Serializable; 045import java.util.ArrayList; 046import java.util.Collection; 047 048import static org.apache.commons.lang3.StringUtils.length; 049 050@Table( 051 name = "TRM_CODESYSTEM_VER", 052 // Note, we used to have a constraint named IDX_CSV_RESOURCEPID_AND_VER (don't reuse this) 053 uniqueConstraints = { 054 @UniqueConstraint( 055 name = TermCodeSystemVersion.IDX_CODESYSTEM_AND_VER, 056 columnNames = {"CODESYSTEM_PID", "CS_VERSION_ID"}) 057 }, 058 indexes = { 059 @Index(name = "FK_CODESYSVER_RES_ID", columnList = "RES_ID"), 060 @Index(name = "FK_CODESYSVER_CS_ID", columnList = "CODESYSTEM_PID") 061 }) 062@Entity() 063public class TermCodeSystemVersion implements Serializable { 064 public static final String IDX_CODESYSTEM_AND_VER = "IDX_CODESYSTEM_AND_VER"; 065 public static final int MAX_VERSION_LENGTH = 200; 066 private static final long serialVersionUID = 1L; 067 068 @OneToMany(fetch = FetchType.LAZY, mappedBy = "myCodeSystem") 069 private Collection<TermConcept> myConcepts; 070 071 @Id() 072 @SequenceGenerator(name = "SEQ_CODESYSTEMVER_PID", sequenceName = "SEQ_CODESYSTEMVER_PID") 073 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODESYSTEMVER_PID") 074 @Column(name = "PID") 075 private Long myId; 076 077 @OneToOne(fetch = FetchType.LAZY) 078 @JoinColumn( 079 name = "RES_ID", 080 referencedColumnName = "RES_ID", 081 nullable = false, 082 updatable = false, 083 foreignKey = @ForeignKey(name = "FK_CODESYSVER_RES_ID")) 084 private ResourceTable myResource; 085 086 @Column(name = "RES_ID", nullable = false, insertable = false, updatable = false) 087 private Long myResourcePid; 088 089 @Column(name = "CS_VERSION_ID", nullable = true, updatable = true, length = MAX_VERSION_LENGTH) 090 private String myCodeSystemVersionId; 091 092 /** 093 * This was added in HAPI FHIR 3.3.0 and is nullable just to avoid migration 094 * issued. It should be made non-nullable at some point. 095 */ 096 @ManyToOne(fetch = FetchType.LAZY) 097 @JoinColumn( 098 name = "CODESYSTEM_PID", 099 referencedColumnName = "PID", 100 nullable = true, 101 foreignKey = @ForeignKey(name = "FK_CODESYSVER_CS_ID")) 102 private TermCodeSystem myCodeSystem; 103 104 @Column(name = "CODESYSTEM_PID", insertable = false, updatable = false) 105 private Long myCodeSystemPid; 106 107 @SuppressWarnings("unused") 108 @OneToOne(mappedBy = "myCurrentVersion", optional = true, fetch = FetchType.LAZY) 109 private TermCodeSystem myCodeSystemHavingThisVersionAsCurrentVersionIfAny; 110 111 @Column(name = "CS_DISPLAY", nullable = true, updatable = true, length = MAX_VERSION_LENGTH) 112 private String myCodeSystemDisplayName; 113 114 /** 115 * Constructor 116 */ 117 public TermCodeSystemVersion() { 118 super(); 119 } 120 121 public TermCodeSystem getCodeSystem() { 122 return myCodeSystem; 123 } 124 125 public TermCodeSystemVersion setCodeSystem(TermCodeSystem theCodeSystem) { 126 myCodeSystem = theCodeSystem; 127 return this; 128 } 129 130 public String getCodeSystemVersionId() { 131 return myCodeSystemVersionId; 132 } 133 134 public TermCodeSystemVersion setCodeSystemVersionId(String theCodeSystemVersionId) { 135 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 136 theCodeSystemVersionId, 137 MAX_VERSION_LENGTH, 138 "Version ID exceeds maximum length (" + MAX_VERSION_LENGTH + "): " + length(theCodeSystemVersionId)); 139 myCodeSystemVersionId = theCodeSystemVersionId; 140 return this; 141 } 142 143 public Collection<TermConcept> getConcepts() { 144 if (myConcepts == null) { 145 myConcepts = new ArrayList<>(); 146 } 147 return myConcepts; 148 } 149 150 public Long getPid() { 151 return myId; 152 } 153 154 public ResourceTable getResource() { 155 return myResource; 156 } 157 158 public TermCodeSystemVersion setResource(ResourceTable theResource) { 159 myResource = theResource; 160 return this; 161 } 162 163 public TermCodeSystemVersion setId(Long theId) { 164 myId = theId; 165 return this; 166 } 167 168 @Override 169 public boolean equals(Object theO) { 170 if (this == theO) { 171 return true; 172 } 173 174 if (theO == null || getClass() != theO.getClass()) { 175 return false; 176 } 177 178 TermCodeSystemVersion that = (TermCodeSystemVersion) theO; 179 180 return new EqualsBuilder() 181 .append(myCodeSystemVersionId, that.myCodeSystemVersionId) 182 .append(myCodeSystemPid, that.myCodeSystemPid) 183 .isEquals(); 184 } 185 186 @Override 187 public int hashCode() { 188 HashCodeBuilder b = new HashCodeBuilder(17, 37); 189 b.append(myCodeSystemVersionId); 190 b.append(myCodeSystemPid); 191 return b.toHashCode(); 192 } 193 194 public String getCodeSystemDisplayName() { 195 return myCodeSystemDisplayName; 196 } 197 198 public void setCodeSystemDisplayName(String theCodeSystemDisplayName) { 199 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 200 theCodeSystemDisplayName, 201 MAX_VERSION_LENGTH, 202 "Version ID exceeds maximum length (" + MAX_VERSION_LENGTH + "): " + length(theCodeSystemDisplayName)); 203 myCodeSystemDisplayName = theCodeSystemDisplayName; 204 } 205 206 public TermConcept addConcept() { 207 TermConcept concept = new TermConcept(); 208 concept.setCodeSystemVersion(this); 209 getConcepts().add(concept); 210 return concept; 211 } 212 213 @Override 214 public String toString() { 215 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 216 b.append("pid", myId); 217 b.append("displayName", myCodeSystemDisplayName); 218 b.append("codeSystemResourcePid", myResourcePid); 219 b.append("codeSystemPid", myCodeSystemPid); 220 b.append("codeSystemVersionId", myCodeSystemVersionId); 221 return b.toString(); 222 } 223 224 TermCodeSystemVersion setCodeSystemPidForUnitTest(long theCodeSystemPid) { 225 myCodeSystemPid = theCodeSystemPid; 226 return this; 227 } 228}