001/*- 002 * #%L 003 * HAPI FHIR JPA Model 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.model.entity; 021 022import ca.uhn.fhir.interceptor.model.RequestPartitionId; 023import ca.uhn.fhir.jpa.model.config.PartitionSettings; 024import jakarta.persistence.Column; 025import jakarta.persistence.Entity; 026import jakarta.persistence.ForeignKey; 027import jakarta.persistence.GeneratedValue; 028import jakarta.persistence.GenerationType; 029import jakarta.persistence.Id; 030import jakarta.persistence.Index; 031import jakarta.persistence.JoinColumn; 032import jakarta.persistence.ManyToOne; 033import jakarta.persistence.PrePersist; 034import jakarta.persistence.Table; 035import jakarta.persistence.Transient; 036import org.apache.commons.lang3.Validate; 037import org.apache.commons.lang3.builder.EqualsBuilder; 038import org.apache.commons.lang3.builder.HashCodeBuilder; 039import org.apache.commons.lang3.builder.ToStringBuilder; 040import org.apache.commons.lang3.builder.ToStringStyle; 041import org.hibernate.annotations.GenericGenerator; 042 043import java.io.Serializable; 044 045import static ca.uhn.fhir.jpa.model.util.SearchParamHash.hashSearchParam; 046 047@Entity 048@Table( 049 name = "HFJ_RES_PARAM_PRESENT", 050 indexes = { 051 // We used to have a constraint named IDX_RESPARMPRESENT_SPID_RESID - Don't reuse 052 @Index(name = "IDX_RESPARMPRESENT_RESID", columnList = "RES_ID"), 053 @Index(name = "IDX_RESPARMPRESENT_HASHPRES", columnList = "HASH_PRESENCE") 054 }) 055public class SearchParamPresentEntity extends BasePartitionable implements Serializable { 056 057 private static final long serialVersionUID = 1L; 058 059 @Id 060 @GenericGenerator( 061 name = "SEQ_RESPARMPRESENT_ID", 062 type = ca.uhn.fhir.jpa.model.dialect.HapiSequenceStyleGenerator.class) 063 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_RESPARMPRESENT_ID") 064 @Column(name = "PID") 065 private Long myId; 066 067 @Column(name = "SP_PRESENT", nullable = false) 068 private boolean myPresent; 069 070 @ManyToOne() 071 @JoinColumn( 072 name = "RES_ID", 073 referencedColumnName = "RES_ID", 074 nullable = false, 075 foreignKey = @ForeignKey(name = "FK_RESPARMPRES_RESID")) 076 private ResourceTable myResource; 077 078 @Column(name = "RES_ID", nullable = false, insertable = false, updatable = false) 079 private Long myResourcePid; 080 081 @Transient 082 private transient String myParamName; 083 084 @Column(name = "HASH_PRESENCE") 085 private Long myHashPresence; 086 087 @Transient 088 private transient PartitionSettings myPartitionSettings; 089 090 /** 091 * Constructor 092 */ 093 public SearchParamPresentEntity() { 094 super(); 095 } 096 097 /** 098 * Constructor 099 */ 100 public SearchParamPresentEntity(String theParamName, boolean thePresent) { 101 myParamName = theParamName; 102 myPresent = thePresent; 103 } 104 105 @SuppressWarnings("unused") 106 @PrePersist 107 public void calculateHashes() { 108 if (myHashPresence == null && getParamName() != null) { 109 String resourceType = getResource().getResourceType(); 110 String paramName = getParamName(); 111 boolean present = myPresent; 112 setHashPresence( 113 calculateHashPresence(getPartitionSettings(), getPartitionId(), resourceType, paramName, present)); 114 } 115 } 116 117 public Long getHashPresence() { 118 Validate.notNull(myHashPresence); 119 return myHashPresence; 120 } 121 122 public void setHashPresence(Long theHashPresence) { 123 myHashPresence = theHashPresence; 124 } 125 126 public String getParamName() { 127 return myParamName; 128 } 129 130 public void setParamName(String theParamName) { 131 myParamName = theParamName; 132 } 133 134 public ResourceTable getResource() { 135 return myResource; 136 } 137 138 public void setResource(ResourceTable theResourceTable) { 139 myResource = theResourceTable; 140 } 141 142 public boolean isPresent() { 143 return myPresent; 144 } 145 146 public void setPresent(boolean thePresent) { 147 myPresent = thePresent; 148 } 149 150 @Override 151 public boolean equals(Object theO) { 152 if (this == theO) return true; 153 154 if (theO == null || getClass() != theO.getClass()) return false; 155 156 SearchParamPresentEntity that = (SearchParamPresentEntity) theO; 157 158 EqualsBuilder b = new EqualsBuilder(); 159 b.append(getHashPresence(), that.getHashPresence()); 160 return b.isEquals(); 161 } 162 163 @Override 164 public int hashCode() { 165 HashCodeBuilder b = new HashCodeBuilder(17, 37); 166 b.append(getHashPresence()); 167 return b.toHashCode(); 168 } 169 170 @Override 171 public String toString() { 172 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 173 174 b.append("resPid", myResource.getIdDt().toUnqualifiedVersionless().getValue()); 175 b.append("paramName", myParamName); 176 b.append("present", myPresent); 177 b.append("partition", getPartitionId()); 178 return b.build(); 179 } 180 181 public PartitionSettings getPartitionSettings() { 182 return myPartitionSettings; 183 } 184 185 public void setPartitionSettings(PartitionSettings thePartitionSettings) { 186 myPartitionSettings = thePartitionSettings; 187 } 188 189 /** 190 * Copy all mutable values from the given source 191 */ 192 public void updateValues(SearchParamPresentEntity theSource) { 193 super.setPartitionId(theSource.getPartitionId()); 194 setResource(theSource.getResource()); 195 setPartitionSettings(theSource.getPartitionSettings()); 196 setHashPresence(theSource.getHashPresence()); 197 setParamName(theSource.getParamName()); 198 setPresent(theSource.isPresent()); 199 } 200 201 public static long calculateHashPresence( 202 PartitionSettings thePartitionSettings, 203 PartitionablePartitionId theRequestPartitionId, 204 String theResourceType, 205 String theParamName, 206 Boolean thePresent) { 207 RequestPartitionId requestPartitionId = PartitionablePartitionId.toRequestPartitionId(theRequestPartitionId); 208 return calculateHashPresence( 209 thePartitionSettings, requestPartitionId, theResourceType, theParamName, thePresent); 210 } 211 212 public static long calculateHashPresence( 213 PartitionSettings thePartitionSettings, 214 RequestPartitionId theRequestPartitionId, 215 String theResourceType, 216 String theParamName, 217 Boolean thePresent) { 218 String string = thePresent != null ? Boolean.toString(thePresent) : Boolean.toString(false); 219 return hashSearchParam(thePartitionSettings, theRequestPartitionId, theResourceType, theParamName, string); 220 } 221}