001package ca.uhn.fhir.jpa.entity;
002
003/*
004 * #%L
005 * HAPI FHIR JPA Server
006 * %%
007 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.jpa.model.entity.ResourceTable;
024import ca.uhn.fhir.util.ValidateUtil;
025import org.apache.commons.lang3.builder.EqualsBuilder;
026import org.apache.commons.lang3.builder.HashCodeBuilder;
027import org.apache.commons.lang3.builder.ToStringBuilder;
028import org.apache.commons.lang3.builder.ToStringStyle;
029
030import javax.persistence.Column;
031import javax.persistence.Entity;
032import javax.persistence.FetchType;
033import javax.persistence.ForeignKey;
034import javax.persistence.GeneratedValue;
035import javax.persistence.GenerationType;
036import javax.persistence.Id;
037import javax.persistence.JoinColumn;
038import javax.persistence.ManyToOne;
039import javax.persistence.OneToMany;
040import javax.persistence.OneToOne;
041import javax.persistence.SequenceGenerator;
042import javax.persistence.Table;
043import javax.persistence.UniqueConstraint;
044import java.io.Serializable;
045import java.util.ArrayList;
046import java.util.Collection;
047
048import static org.apache.commons.lang3.StringUtils.length;
049
050@Table(name = "TRM_CODESYSTEM_VER",
051        // Note, we used to have a constraint named IDX_CSV_RESOURCEPID_AND_VER (don't reuse this)
052        uniqueConstraints = {
053        @UniqueConstraint(name = TermCodeSystemVersion.IDX_CODESYSTEM_AND_VER, columnNames = {"CODESYSTEM_PID", "CS_VERSION_ID"})
054})
055@Entity()
056public class TermCodeSystemVersion implements Serializable {
057        public static final String IDX_CODESYSTEM_AND_VER = "IDX_CODESYSTEM_AND_VER";
058        public static final int MAX_VERSION_LENGTH = 200;
059        private static final long serialVersionUID = 1L;
060
061        @OneToMany(fetch = FetchType.LAZY, mappedBy = "myCodeSystem")
062        private Collection<TermConcept> myConcepts;
063
064        @Id()
065        @SequenceGenerator(name = "SEQ_CODESYSTEMVER_PID", sequenceName = "SEQ_CODESYSTEMVER_PID")
066        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODESYSTEMVER_PID")
067        @Column(name = "PID")
068        private Long myId;
069
070        @OneToOne(fetch = FetchType.LAZY)
071        @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_CODESYSVER_RES_ID"))
072        private ResourceTable myResource;
073
074        @Column(name = "RES_ID", nullable = false, insertable = false, updatable = false)
075        private Long myResourcePid;
076
077        @Column(name = "CS_VERSION_ID", nullable = true, updatable = true, length = MAX_VERSION_LENGTH)
078        private String myCodeSystemVersionId;
079
080        /**
081         * This was added in HAPI FHIR 3.3.0 and is nullable just to avoid migration
082         * issued. It should be made non-nullable at some point.
083         */
084        @ManyToOne(fetch = FetchType.LAZY)
085        @JoinColumn(name = "CODESYSTEM_PID", referencedColumnName = "PID", nullable = true, foreignKey = @ForeignKey(name = "FK_CODESYSVER_CS_ID"))
086        private TermCodeSystem myCodeSystem;
087
088        @Column(name = "CODESYSTEM_PID", insertable = false, updatable = false)
089        private Long myCodeSystemPid;
090
091        @SuppressWarnings("unused")
092        @OneToOne(mappedBy = "myCurrentVersion", optional = true, fetch = FetchType.LAZY)
093        private TermCodeSystem myCodeSystemHavingThisVersionAsCurrentVersionIfAny;
094
095        @Column(name = "CS_DISPLAY", nullable = true, updatable = true, length = MAX_VERSION_LENGTH)
096        private String myCodeSystemDisplayName;
097
098        /**
099         * Constructor
100         */
101        public TermCodeSystemVersion() {
102                super();
103        }
104
105
106        public TermCodeSystem getCodeSystem() {
107                return myCodeSystem;
108        }
109
110        public TermCodeSystemVersion setCodeSystem(TermCodeSystem theCodeSystem) {
111                myCodeSystem = theCodeSystem;
112                return this;
113        }
114
115        public String getCodeSystemVersionId() {
116                return myCodeSystemVersionId;
117        }
118
119        public TermCodeSystemVersion setCodeSystemVersionId(String theCodeSystemVersionId) {
120                ValidateUtil.isNotTooLongOrThrowIllegalArgument(
121                        theCodeSystemVersionId, MAX_VERSION_LENGTH,
122                        "Version ID exceeds maximum length (" + MAX_VERSION_LENGTH + "): " + length(theCodeSystemVersionId));
123                myCodeSystemVersionId = theCodeSystemVersionId;
124                return this;
125        }
126
127        public Collection<TermConcept> getConcepts() {
128                if (myConcepts == null) {
129                        myConcepts = new ArrayList<>();
130                }
131                return myConcepts;
132        }
133
134        public Long getPid() {
135                return myId;
136        }
137
138        public ResourceTable getResource() {
139                return myResource;
140        }
141
142        public TermCodeSystemVersion setResource(ResourceTable theResource) {
143                myResource = theResource;
144                return this;
145        }
146
147        public TermCodeSystemVersion setId(Long theId) {
148                myId = theId;
149                return this;
150        }
151
152        @Override
153        public boolean equals(Object theO) {
154                if (this == theO) {
155                        return true;
156                }
157
158                if (theO == null || getClass() != theO.getClass()) {
159                        return false;
160                }
161
162                TermCodeSystemVersion that = (TermCodeSystemVersion) theO;
163
164                return new EqualsBuilder()
165                        .append(myCodeSystemVersionId, that.myCodeSystemVersionId)
166                        .append(myCodeSystemPid, that.myCodeSystemPid)
167                        .isEquals();
168        }
169
170        @Override
171        public int hashCode() {
172                HashCodeBuilder b = new HashCodeBuilder(17, 37);
173                b.append(myCodeSystemVersionId);
174                b.append(myCodeSystemPid);
175                return b.toHashCode();
176        }
177
178        public String getCodeSystemDisplayName() {
179                return myCodeSystemDisplayName;
180        }
181
182        public void setCodeSystemDisplayName(String theCodeSystemDisplayName) {
183                ValidateUtil.isNotTooLongOrThrowIllegalArgument(
184                        theCodeSystemDisplayName, MAX_VERSION_LENGTH,
185                        "Version ID exceeds maximum length (" + MAX_VERSION_LENGTH + "): " + length(theCodeSystemDisplayName));
186                myCodeSystemDisplayName = theCodeSystemDisplayName;
187        }
188
189        public TermConcept addConcept() {
190                TermConcept concept = new TermConcept();
191                concept.setCodeSystemVersion(this);
192                getConcepts().add(concept);
193                return concept;
194        }
195
196        @Override
197        public String toString() {
198                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
199                b.append("pid", myId);
200                b.append("displayName", myCodeSystemDisplayName);
201                b.append("codeSystemResourcePid", myResourcePid);
202                b.append("codeSystemPid", myCodeSystemPid);
203                b.append("codeSystemVersionId", myCodeSystemVersionId);
204                return b.toString();
205        }
206
207        TermCodeSystemVersion setCodeSystemPidForUnitTest(long theCodeSystemPid) {
208                myCodeSystemPid = theCodeSystemPid;
209                return this;
210        }
211}