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.util.ValidateUtil;
025import jakarta.annotation.Nonnull;
026import jakarta.persistence.Column;
027import jakarta.persistence.Entity;
028import jakarta.persistence.ForeignKey;
029import jakarta.persistence.GeneratedValue;
030import jakarta.persistence.GenerationType;
031import jakarta.persistence.Id;
032import jakarta.persistence.IdClass;
033import jakarta.persistence.Index;
034import jakarta.persistence.JoinColumn;
035import jakarta.persistence.JoinColumns;
036import jakarta.persistence.ManyToOne;
037import jakarta.persistence.OneToMany;
038import jakarta.persistence.SequenceGenerator;
039import jakarta.persistence.Table;
040import org.apache.commons.lang3.builder.EqualsBuilder;
041import org.apache.commons.lang3.builder.HashCodeBuilder;
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.left;
050import static org.apache.commons.lang3.StringUtils.length;
051
052@Entity
053@Table(
054                name = "TRM_CONCEPT_MAP_GRP_ELEMENT",
055                indexes = {
056                        @Index(name = "IDX_CNCPT_MAP_GRP_CD", columnList = "SOURCE_CODE"),
057                        @Index(name = "FK_TCMGELEMENT_GROUP", columnList = "CONCEPT_MAP_GROUP_PID")
058                })
059@IdClass(IdAndPartitionId.class)
060public class TermConceptMapGroupElement extends BasePartitionable implements Serializable {
061        private static final long serialVersionUID = 1L;
062
063        @Id()
064        @SequenceGenerator(name = "SEQ_CONCEPT_MAP_GRP_ELM_PID", sequenceName = "SEQ_CONCEPT_MAP_GRP_ELM_PID")
065        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_MAP_GRP_ELM_PID")
066        @Column(name = "PID")
067        private Long myId;
068
069        @ManyToOne()
070        @JoinColumns(
071                        value = {
072                                @JoinColumn(
073                                                name = "CONCEPT_MAP_GROUP_PID",
074                                                insertable = true,
075                                                updatable = false,
076                                                nullable = false,
077                                                referencedColumnName = "PID"),
078                                @JoinColumn(
079                                                name = "PARTITION_ID",
080                                                referencedColumnName = "PARTITION_ID",
081                                                insertable = true,
082                                                updatable = false,
083                                                nullable = false)
084                        },
085                        foreignKey = @ForeignKey(name = "FK_TCMGELEMENT_GROUP"))
086        private TermConceptMapGroup myConceptMapGroup;
087
088        @Column(name = "SOURCE_CODE", nullable = false, length = TermConcept.MAX_CODE_LENGTH)
089        private String myCode;
090
091        @Column(name = "SOURCE_DISPLAY", length = TermConcept.MAX_DISP_LENGTH)
092        private String myDisplay;
093
094        @OneToMany(mappedBy = "myConceptMapGroupElement")
095        private List<TermConceptMapGroupElementTarget> myConceptMapGroupElementTargets;
096
097        @Column(name = "CONCEPT_MAP_URL", nullable = true, length = TermConceptMap.MAX_URL_LENGTH)
098        private String myConceptMapUrl;
099
100        @Column(name = "SYSTEM_URL", nullable = true, length = TermCodeSystem.MAX_URL_LENGTH)
101        private String mySystem;
102
103        @Column(name = "SYSTEM_VERSION", nullable = true, length = TermCodeSystemVersion.MAX_VERSION_LENGTH)
104        private String mySystemVersion;
105
106        @Column(name = "VALUESET_URL", nullable = true, length = TermValueSet.MAX_URL_LENGTH)
107        private String myValueSet;
108
109        public String getCode() {
110                return myCode;
111        }
112
113        public TermConceptMapGroupElement setCode(@Nonnull String theCode) {
114                ValidateUtil.isNotBlankOrThrowIllegalArgument(theCode, "theCode must not be null or empty");
115                ValidateUtil.isNotTooLongOrThrowIllegalArgument(
116                                theCode,
117                                TermConcept.MAX_CODE_LENGTH,
118                                "Code exceeds maximum length (" + TermConcept.MAX_CODE_LENGTH + "): " + length(theCode));
119                myCode = theCode;
120                return this;
121        }
122
123        public TermConceptMapGroup getConceptMapGroup() {
124                return myConceptMapGroup;
125        }
126
127        public TermConceptMapGroupElement setConceptMapGroup(TermConceptMapGroup theTermConceptMapGroup) {
128                myConceptMapGroup = theTermConceptMapGroup;
129                setPartitionId(theTermConceptMapGroup.getPartitionId());
130                return this;
131        }
132
133        public List<TermConceptMapGroupElementTarget> getConceptMapGroupElementTargets() {
134                if (myConceptMapGroupElementTargets == null) {
135                        myConceptMapGroupElementTargets = new ArrayList<>();
136                }
137
138                return myConceptMapGroupElementTargets;
139        }
140
141        public String getConceptMapUrl() {
142                if (myConceptMapUrl == null) {
143                        myConceptMapUrl = getConceptMapGroup().getConceptMap().getUrl();
144                }
145                return myConceptMapUrl;
146        }
147
148        public String getDisplay() {
149                return myDisplay;
150        }
151
152        public TermConceptMapGroupElement setDisplay(String theDisplay) {
153                myDisplay = left(theDisplay, TermConcept.MAX_DISP_LENGTH);
154                return this;
155        }
156
157        public Long getId() {
158                return myId;
159        }
160
161        public String getSystem() {
162                if (mySystem == null) {
163                        mySystem = getConceptMapGroup().getSource();
164                }
165                return mySystem;
166        }
167
168        public String getSystemVersion() {
169                if (mySystemVersion == null) {
170                        mySystemVersion = getConceptMapGroup().getSourceVersion();
171                }
172                return mySystemVersion;
173        }
174
175        public String getValueSet() {
176                if (myValueSet == null) {
177                        myValueSet = getConceptMapGroup().getSourceValueSet();
178                }
179                return myValueSet;
180        }
181
182        @Override
183        public boolean equals(Object o) {
184                if (this == o) return true;
185
186                if (!(o instanceof TermConceptMapGroupElement)) return false;
187
188                TermConceptMapGroupElement that = (TermConceptMapGroupElement) o;
189
190                return new EqualsBuilder()
191                                .append(getCode(), that.getCode())
192                                .append(getSystem(), that.getSystem())
193                                .append(getSystemVersion(), that.getSystemVersion())
194                                .isEquals();
195        }
196
197        @Override
198        public int hashCode() {
199                return new HashCodeBuilder(17, 37)
200                                .append(getCode())
201                                .append(getSystem())
202                                .append(getSystemVersion())
203                                .toHashCode();
204        }
205
206        @Override
207        public String toString() {
208                return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
209                                .append("myId", myId)
210                                .append(
211                                                myConceptMapGroup != null
212                                                                ? ("myConceptMapGroup - id=" + myConceptMapGroup.getId())
213                                                                : ("myConceptMapGroup=(null)"))
214                                .append("myCode", myCode)
215                                .append("myDisplay", myDisplay)
216                                .append(
217                                                myConceptMapGroupElementTargets != null
218                                                                ? ("myConceptMapGroupElementTargets - size=" + myConceptMapGroupElementTargets.size())
219                                                                : ("myConceptMapGroupElementTargets=(null)"))
220                                .append("myConceptMapUrl", this.getConceptMapUrl())
221                                .append("mySystem", this.getSystem())
222                                .append("mySystemVersion", this.getSystemVersion())
223                                .append("myValueSet", this.getValueSet())
224                                .toString();
225        }
226}