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.jpa.model.config.PartitionSettings;
023import ca.uhn.fhir.model.api.IQueryParameterType;
024import jakarta.persistence.Column;
025import jakarta.persistence.Embeddable;
026import jakarta.persistence.Entity;
027import jakarta.persistence.FetchType;
028import jakarta.persistence.ForeignKey;
029import jakarta.persistence.GeneratedValue;
030import jakarta.persistence.GenerationType;
031import jakarta.persistence.Id;
032import jakarta.persistence.Index;
033import jakarta.persistence.JoinColumn;
034import jakarta.persistence.ManyToOne;
035import jakarta.persistence.SequenceGenerator;
036import jakarta.persistence.Table;
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;
041
042@Embeddable
043@Entity
044@Table(
045                name = "HFJ_SPIDX_COORDS",
046                indexes = {
047                        @Index(
048                                        name = "IDX_SP_COORDS_HASH_V2",
049                                        columnList = "HASH_IDENTITY,SP_LATITUDE,SP_LONGITUDE,RES_ID,PARTITION_ID"),
050                        @Index(name = "IDX_SP_COORDS_UPDATED", columnList = "SP_UPDATED"),
051                        @Index(name = "IDX_SP_COORDS_RESID", columnList = "RES_ID")
052                })
053public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchParam {
054
055        public static final int MAX_LENGTH = 100;
056
057        private static final long serialVersionUID = 1L;
058
059        @Column(name = "SP_LATITUDE")
060        // @FullTextField
061        public double myLatitude;
062
063        @Column(name = "SP_LONGITUDE")
064        // @FullTextField
065        public double myLongitude;
066
067        @Id
068        @SequenceGenerator(name = "SEQ_SPIDX_COORDS", sequenceName = "SEQ_SPIDX_COORDS")
069        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SPIDX_COORDS")
070        @Column(name = "SP_ID")
071        private Long myId;
072        /**
073         * @since 3.5.0 - At some point this should be made not-null
074         */
075        @Column(name = "HASH_IDENTITY", nullable = true)
076        private Long myHashIdentity;
077
078        @ManyToOne(
079                        optional = false,
080                        fetch = FetchType.LAZY,
081                        cascade = {})
082        @JoinColumn(
083                        foreignKey = @ForeignKey(name = "FKC97MPK37OKWU8QVTCEG2NH9VN"),
084                        name = "RES_ID",
085                        referencedColumnName = "RES_ID",
086                        nullable = false)
087        private ResourceTable myResource;
088
089        public ResourceIndexedSearchParamCoords() {}
090
091        public ResourceIndexedSearchParamCoords(
092                        PartitionSettings thePartitionSettings,
093                        String theResourceType,
094                        String theParamName,
095                        double theLatitude,
096                        double theLongitude) {
097                setPartitionSettings(thePartitionSettings);
098                setResourceType(theResourceType);
099                setParamName(theParamName);
100                setLatitude(theLatitude);
101                setLongitude(theLongitude);
102                calculateHashes();
103        }
104
105        @Override
106        public void clearHashes() {
107                myHashIdentity = null;
108        }
109
110        @Override
111        public void calculateHashes() {
112                if (myHashIdentity != null) {
113                        return;
114                }
115
116                String resourceType = getResourceType();
117                String paramName = getParamName();
118                setHashIdentity(calculateHashIdentity(getPartitionSettings(), getPartitionId(), resourceType, paramName));
119        }
120
121        @Override
122        public boolean equals(Object theObj) {
123                if (this == theObj) {
124                        return true;
125                }
126                if (theObj == null) {
127                        return false;
128                }
129                if (!(theObj instanceof ResourceIndexedSearchParamCoords)) {
130                        return false;
131                }
132                ResourceIndexedSearchParamCoords obj = (ResourceIndexedSearchParamCoords) theObj;
133                EqualsBuilder b = new EqualsBuilder();
134                b.append(getResourceType(), obj.getResourceType());
135                b.append(getParamName(), obj.getParamName());
136                b.append(getLatitude(), obj.getLatitude());
137                b.append(getLongitude(), obj.getLongitude());
138                b.append(isMissing(), obj.isMissing());
139                return b.isEquals();
140        }
141
142        @Override
143        public <T extends BaseResourceIndex> void copyMutableValuesFrom(T theSource) {
144                super.copyMutableValuesFrom(theSource);
145                ResourceIndexedSearchParamCoords source = (ResourceIndexedSearchParamCoords) theSource;
146                myLatitude = source.getLatitude();
147                myLongitude = source.getLongitude();
148                myHashIdentity = source.myHashIdentity;
149        }
150
151        public void setHashIdentity(Long theHashIdentity) {
152                myHashIdentity = theHashIdentity;
153        }
154
155        @Override
156        public Long getId() {
157                return myId;
158        }
159
160        @Override
161        public void setId(Long theId) {
162                myId = theId;
163        }
164
165        public double getLatitude() {
166                return myLatitude;
167        }
168
169        public ResourceIndexedSearchParamCoords setLatitude(double theLatitude) {
170                myLatitude = theLatitude;
171                return this;
172        }
173
174        public double getLongitude() {
175                return myLongitude;
176        }
177
178        public ResourceIndexedSearchParamCoords setLongitude(double theLongitude) {
179                myLongitude = theLongitude;
180                return this;
181        }
182
183        @Override
184        public int hashCode() {
185                HashCodeBuilder b = new HashCodeBuilder();
186                b.append(getParamName());
187                b.append(getResourceType());
188                b.append(getLatitude());
189                b.append(getLongitude());
190                return b.toHashCode();
191        }
192
193        @Override
194        public IQueryParameterType toQueryParameterType() {
195                return null;
196        }
197
198        @Override
199        public String toString() {
200                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
201                b.append("paramName", getParamName());
202                b.append("resourceId", getResourcePid());
203                if (isMissing()) {
204                        b.append("missing", isMissing());
205                } else {
206                        b.append("lat", getLatitude());
207                        b.append("lon", getLongitude());
208                }
209                return b.build();
210        }
211
212        @Override
213        public ResourceTable getResource() {
214                return myResource;
215        }
216
217        @Override
218        public BaseResourceIndexedSearchParam setResource(ResourceTable theResource) {
219                myResource = theResource;
220                setResourceType(theResource.getResourceType());
221                return this;
222        }
223}