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.ForeignKey; 030import jakarta.persistence.GeneratedValue; 031import jakarta.persistence.GenerationType; 032import jakarta.persistence.Id; 033import jakarta.persistence.IdClass; 034import jakarta.persistence.Index; 035import jakarta.persistence.JoinColumn; 036import jakarta.persistence.JoinColumns; 037import jakarta.persistence.ManyToOne; 038import jakarta.persistence.OneToMany; 039import jakarta.persistence.SequenceGenerator; 040import jakarta.persistence.Table; 041import jakarta.persistence.UniqueConstraint; 042import org.apache.commons.lang3.builder.ToStringBuilder; 043import org.apache.commons.lang3.builder.ToStringStyle; 044 045import java.io.Serializable; 046import java.util.ArrayList; 047import java.util.List; 048 049import static org.apache.commons.lang3.StringUtils.length; 050 051@Entity 052@Table( 053 name = "TRM_CONCEPT_MAP", 054 uniqueConstraints = { 055 @UniqueConstraint( 056 name = "IDX_CONCEPT_MAP_URL", 057 columnNames = {"PARTITION_ID", "URL", "VER"}) 058 }, 059 indexes = { 060 // must have same name that indexed FK or SchemaMigrationTest complains because H2 sets this index 061 // automatically 062 @Index(name = "FK_TRMCONCEPTMAP_RES", columnList = "RES_ID") 063 }) 064@IdClass(IdAndPartitionId.class) 065public class TermConceptMap extends BasePartitionable implements Serializable { 066 private static final long serialVersionUID = 1L; 067 068 static final int MAX_URL_LENGTH = 200; 069 public static final int MAX_VER_LENGTH = 200; 070 071 /** 072 * Constructor 073 */ 074 public TermConceptMap() { 075 super(); 076 } 077 078 @Id() 079 @SequenceGenerator(name = "SEQ_CONCEPT_MAP_PID", sequenceName = "SEQ_CONCEPT_MAP_PID") 080 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_MAP_PID") 081 @Column(name = "PID") 082 private Long myId; 083 084 @ManyToOne() 085 @JoinColumns( 086 value = { 087 @JoinColumn( 088 name = "RES_ID", 089 referencedColumnName = "RES_ID", 090 nullable = false, 091 insertable = false, 092 updatable = false), 093 @JoinColumn( 094 name = "PARTITION_ID", 095 referencedColumnName = "PARTITION_ID", 096 nullable = false, 097 insertable = false, 098 updatable = false) 099 }, 100 foreignKey = @ForeignKey(name = "FK_TRMCONCEPTMAP_RES")) 101 private ResourceTable myResource; 102 103 @Column(name = "RES_ID", nullable = false) 104 private Long myResourcePid; 105 106 @Column(name = "SOURCE_URL", nullable = true, length = TermValueSet.MAX_URL_LENGTH) 107 private String mySource; 108 109 @Column(name = "TARGET_URL", nullable = true, length = TermValueSet.MAX_URL_LENGTH) 110 private String myTarget; 111 112 @Column(name = "URL", nullable = false, length = MAX_URL_LENGTH) 113 private String myUrl; 114 115 @Column(name = "VER", nullable = true, length = MAX_VER_LENGTH) 116 private String myVersion; 117 118 @OneToMany(mappedBy = "myConceptMap") 119 private List<TermConceptMapGroup> myConceptMapGroups; 120 121 public List<TermConceptMapGroup> getConceptMapGroups() { 122 if (myConceptMapGroups == null) { 123 myConceptMapGroups = new ArrayList<>(); 124 } 125 126 return myConceptMapGroups; 127 } 128 129 public Long getId() { 130 return myId; 131 } 132 133 public ResourceTable getResource() { 134 return myResource; 135 } 136 137 public TermConceptMap setResource(ResourceTable theResource) { 138 myResource = theResource; 139 myResourcePid = theResource.getId().getId(); 140 setPartitionId(theResource.getPartitionId()); 141 return this; 142 } 143 144 public String getSource() { 145 return mySource; 146 } 147 148 public TermConceptMap setSource(String theSource) { 149 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 150 theSource, 151 TermValueSet.MAX_URL_LENGTH, 152 "Source exceeds maximum length (" + TermValueSet.MAX_URL_LENGTH + "): " + length(theSource)); 153 mySource = theSource; 154 return this; 155 } 156 157 public String getTarget() { 158 return myTarget; 159 } 160 161 public TermConceptMap setTarget(String theTarget) { 162 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 163 theTarget, 164 TermValueSet.MAX_URL_LENGTH, 165 "Target exceeds maximum length (" + TermValueSet.MAX_URL_LENGTH + "): " + length(theTarget)); 166 myTarget = theTarget; 167 return this; 168 } 169 170 public String getUrl() { 171 return myUrl; 172 } 173 174 public TermConceptMap setUrl(@Nonnull String theUrl) { 175 ValidateUtil.isNotBlankOrThrowIllegalArgument(theUrl, "theUrl must not be null or empty"); 176 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 177 theUrl, MAX_URL_LENGTH, "URL exceeds maximum length (" + MAX_URL_LENGTH + "): " + length(theUrl)); 178 myUrl = theUrl; 179 return this; 180 } 181 182 public String getVersion() { 183 return myVersion; 184 } 185 186 public TermConceptMap setVersion(String theVersion) { 187 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 188 theVersion, 189 MAX_VER_LENGTH, 190 "Version exceeds maximum length (" + MAX_VER_LENGTH + "): " + length(theVersion)); 191 myVersion = theVersion; 192 return this; 193 } 194 195 @Override 196 public String toString() { 197 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 198 .append("myId", myId) 199 .append(myResource != null ? ("myResource=" + myResource.toString()) : ("myResource=(null)")) 200 .append("myResourcePid", myResourcePid) 201 .append("mySource", mySource) 202 .append("myTarget", myTarget) 203 .append("myUrl", myUrl) 204 .append("myVersion", myVersion) 205 .append( 206 myConceptMapGroups != null 207 ? ("myConceptMapGroups - size=" + myConceptMapGroups.size()) 208 : ("myConceptMapGroups=(null)")) 209 .toString(); 210 } 211}