001/* 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2025 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.BasePartitionable; 023import ca.uhn.fhir.jpa.model.entity.IdAndPartitionId; 024import ca.uhn.fhir.jpa.model.entity.ResourceTable; 025import ca.uhn.fhir.util.ValidateUtil; 026import jakarta.annotation.Nonnull; 027import jakarta.persistence.Column; 028import jakarta.persistence.Entity; 029import jakarta.persistence.FetchType; 030import jakarta.persistence.ForeignKey; 031import jakarta.persistence.GeneratedValue; 032import jakarta.persistence.GenerationType; 033import jakarta.persistence.Id; 034import jakarta.persistence.IdClass; 035import jakarta.persistence.Index; 036import jakarta.persistence.JoinColumn; 037import jakarta.persistence.JoinColumns; 038import jakarta.persistence.ManyToOne; 039import jakarta.persistence.SequenceGenerator; 040import jakarta.persistence.Table; 041import jakarta.persistence.UniqueConstraint; 042import org.apache.commons.lang3.builder.EqualsBuilder; 043import org.apache.commons.lang3.builder.HashCodeBuilder; 044import org.apache.commons.lang3.builder.ToStringBuilder; 045import org.apache.commons.lang3.builder.ToStringStyle; 046 047import java.io.Serializable; 048 049import static org.apache.commons.lang3.StringUtils.left; 050import static org.apache.commons.lang3.StringUtils.length; 051 052@Table( 053 name = "TRM_CODESYSTEM", 054 uniqueConstraints = { 055 @UniqueConstraint( 056 name = "IDX_CS_CODESYSTEM", 057 columnNames = {"PARTITION_ID", "CODE_SYSTEM_URI"}) 058 }, 059 indexes = { 060 @Index(name = "FK_TRMCODESYSTEM_RES", columnList = "RES_ID"), 061 @Index(name = "FK_TRMCODESYSTEM_CURVER", columnList = "CURRENT_VERSION_PID") 062 }) 063@Entity() 064@IdClass(IdAndPartitionId.class) 065public class TermCodeSystem extends BasePartitionable implements Serializable { 066 public static final int MAX_URL_LENGTH = 200; 067 private static final long serialVersionUID = 1L; 068 private static final int MAX_NAME_LENGTH = 200; 069 public static final String FK_TRMCODESYSTEM_CURVER = "FK_TRMCODESYSTEM_CURVER"; 070 071 @Column(name = "CODE_SYSTEM_URI", nullable = false, length = MAX_URL_LENGTH) 072 private String myCodeSystemUri; 073 074 /** 075 * Note that this uses a separate partition_id column because it needs 076 * to be nullable, unlike the PK one which has to be non-nullable 077 * when we're including partition IDs in PKs. 078 */ 079 @ManyToOne(fetch = FetchType.LAZY) 080 @JoinColumns( 081 value = { 082 @JoinColumn( 083 name = "CURRENT_VERSION_PID", 084 referencedColumnName = "PID", 085 insertable = false, 086 updatable = false, 087 nullable = true), 088 @JoinColumn( 089 name = "CURRENT_VERSION_PARTITION_ID", 090 referencedColumnName = "PARTITION_ID", 091 insertable = false, 092 updatable = false, 093 nullable = true) 094 }, 095 foreignKey = @ForeignKey(name = FK_TRMCODESYSTEM_CURVER)) 096 private TermCodeSystemVersion myCurrentVersion; 097 098 @Column(name = "CURRENT_VERSION_PID", nullable = true, insertable = true, updatable = true) 099 private Long myCurrentVersionPid; 100 101 @Column(name = "CURRENT_VERSION_PARTITION_ID", nullable = true, insertable = true, updatable = true) 102 private Integer myCurrentVersionPartitionId; 103 104 @Id() 105 @SequenceGenerator(name = "SEQ_CODESYSTEM_PID", sequenceName = "SEQ_CODESYSTEM_PID") 106 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODESYSTEM_PID") 107 @Column(name = "PID") 108 private Long myId; 109 110 @ManyToOne(fetch = FetchType.LAZY) 111 @JoinColumns( 112 value = { 113 @JoinColumn( 114 name = "RES_ID", 115 referencedColumnName = "RES_ID", 116 nullable = false, 117 updatable = false, 118 insertable = false), 119 @JoinColumn( 120 name = "PARTITION_ID", 121 referencedColumnName = "PARTITION_ID", 122 nullable = false, 123 updatable = false, 124 insertable = false) 125 }, 126 foreignKey = @ForeignKey(name = "FK_TRMCODESYSTEM_RES")) 127 private ResourceTable myResource; 128 129 @Column(name = "RES_ID", nullable = false) 130 private Long myResourcePid; 131 132 @Column(name = "CS_NAME", nullable = true, length = MAX_NAME_LENGTH) 133 private String myName; 134 135 /** 136 * Constructor 137 */ 138 public TermCodeSystem() { 139 super(); 140 } 141 142 @Override 143 public boolean equals(Object theO) { 144 if (this == theO) { 145 return true; 146 } 147 148 if (theO == null || getClass() != theO.getClass()) { 149 return false; 150 } 151 152 TermCodeSystem that = (TermCodeSystem) theO; 153 154 EqualsBuilder b = new EqualsBuilder(); 155 b.append(myCodeSystemUri, that.myCodeSystemUri); 156 return b.isEquals(); 157 } 158 159 @Override 160 public int hashCode() { 161 HashCodeBuilder b = new HashCodeBuilder(17, 37); 162 b.append(myCodeSystemUri); 163 return b.toHashCode(); 164 } 165 166 public String getCodeSystemUri() { 167 return myCodeSystemUri; 168 } 169 170 public TermCodeSystem setCodeSystemUri(@Nonnull String theCodeSystemUri) { 171 ValidateUtil.isNotBlankOrThrowIllegalArgument(theCodeSystemUri, "theCodeSystemUri must not be null or empty"); 172 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 173 theCodeSystemUri, 174 MAX_URL_LENGTH, 175 "URI exceeds maximum length (" + MAX_URL_LENGTH + "): " + length(theCodeSystemUri)); 176 myCodeSystemUri = theCodeSystemUri; 177 return this; 178 } 179 180 public String getName() { 181 return myName; 182 } 183 184 public TermCodeSystem setName(String theName) { 185 myName = left(theName, MAX_NAME_LENGTH); 186 return this; 187 } 188 189 public TermCodeSystemVersion getCurrentVersion() { 190 return myCurrentVersion; 191 } 192 193 public TermCodeSystem setCurrentVersion(TermCodeSystemVersion theCurrentVersion) { 194 if (theCurrentVersion == null) { 195 myCurrentVersion = null; 196 myCurrentVersionPid = null; 197 myCurrentVersionPartitionId = null; 198 } else { 199 myCurrentVersion = theCurrentVersion; 200 myCurrentVersionPid = theCurrentVersion.getPid(); 201 assert myCurrentVersionPid != null; 202 myCurrentVersionPartitionId = theCurrentVersion.getPartitionId().getPartitionId(); 203 } 204 return this; 205 } 206 207 public Long getPid() { 208 return myId; 209 } 210 211 public IdAndPartitionId getPartitionedId() { 212 return IdAndPartitionId.forId(myId, this); 213 } 214 215 public ResourceTable getResource() { 216 return myResource; 217 } 218 219 public TermCodeSystem setResource(ResourceTable theResource) { 220 myResource = theResource; 221 myResourcePid = theResource.getId().getId(); 222 setPartitionId(theResource.getPartitionId()); 223 return this; 224 } 225 226 @Override 227 public String toString() { 228 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 229 b.append("pid", myId); 230 b.append("codeSystemUri", myCodeSystemUri); 231 b.append("currentVersionPid", myCurrentVersionPid); 232 b.append("resourcePid", myResourcePid); 233 b.append("name", myName); 234 return b.toString(); 235 } 236}