001package ca.uhn.fhir.jpa.model.entity;
002
003/*
004 * #%L
005 * HAPI FHIR JPA Model
006 * %%
007 * Copyright (C) 2014 - 2022 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.interceptor.model.RequestPartitionId;
024import ca.uhn.fhir.jpa.model.config.PartitionSettings;
025import ca.uhn.fhir.model.api.IQueryParameterType;
026import ca.uhn.fhir.rest.param.UriParam;
027import org.apache.commons.lang3.StringUtils;
028import org.apache.commons.lang3.builder.EqualsBuilder;
029import org.apache.commons.lang3.builder.HashCodeBuilder;
030import org.apache.commons.lang3.builder.ToStringBuilder;
031import org.hibernate.search.mapper.pojo.mapping.definition.annotation.FullTextField;
032
033import javax.persistence.Column;
034import javax.persistence.Embeddable;
035import javax.persistence.Entity;
036import javax.persistence.GeneratedValue;
037import javax.persistence.GenerationType;
038import javax.persistence.Id;
039import javax.persistence.Index;
040import javax.persistence.SequenceGenerator;
041import javax.persistence.Table;
042
043import static org.apache.commons.lang3.StringUtils.defaultString;
044
045@Embeddable
046@Entity
047@Table(name = "HFJ_SPIDX_URI", indexes = {
048        @Index(name = "IDX_SP_URI", columnList = "RES_TYPE,SP_NAME,SP_URI"),
049        @Index(name = "IDX_SP_URI_HASH_IDENTITY", columnList = "HASH_IDENTITY,SP_URI"),
050        @Index(name = "IDX_SP_URI_HASH_URI", columnList = "HASH_URI"),
051        @Index(name = "IDX_SP_URI_RESTYPE_NAME", columnList = "RES_TYPE,SP_NAME"),
052        @Index(name = "IDX_SP_URI_UPDATED", columnList = "SP_UPDATED"),
053        @Index(name = "IDX_SP_URI_COORDS", columnList = "RES_ID")
054})
055public class ResourceIndexedSearchParamUri extends BaseResourceIndexedSearchParam {
056
057        /*
058         * Note that MYSQL chokes on unique indexes for lengths > 255 so be careful here
059         */
060        public static final int MAX_LENGTH = 254;
061
062        private static final long serialVersionUID = 1L;
063        @Column(name = "SP_URI", nullable = true, length = MAX_LENGTH)
064        @FullTextField
065        public String myUri;
066
067        @Id
068        @SequenceGenerator(name = "SEQ_SPIDX_URI", sequenceName = "SEQ_SPIDX_URI")
069        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SPIDX_URI")
070        @Column(name = "SP_ID")
071        private Long myId;
072        /**
073         * @since 3.4.0 - At some point this should be made not-null
074         */
075        @Column(name = "HASH_URI", nullable = true)
076        private Long myHashUri;
077        /**
078         * @since 3.5.0 - At some point this should be made not-null
079         */
080        @Column(name = "HASH_IDENTITY", nullable = true)
081        private Long myHashIdentity;
082
083        /**
084         * Constructor
085         */
086        public ResourceIndexedSearchParamUri() {
087                super();
088        }
089
090        /**
091         * Constructor
092         */
093        public ResourceIndexedSearchParamUri(PartitionSettings thePartitionSettings, String theResourceType, String theParamName, String theUri) {
094                setPartitionSettings(thePartitionSettings);
095                setResourceType(theResourceType);
096                setParamName(theParamName);
097                setUri(theUri);
098                calculateHashes();
099        }
100
101        @Override
102        public <T extends BaseResourceIndex> void copyMutableValuesFrom(T theSource) {
103                super.copyMutableValuesFrom(theSource);
104                ResourceIndexedSearchParamUri source = (ResourceIndexedSearchParamUri) theSource;
105                myUri = source.myUri;
106                myHashUri = source.myHashUri;
107                myHashIdentity = source.myHashIdentity;
108        }
109
110        @Override
111        public void clearHashes() {
112                myHashIdentity = null;
113                myHashUri = null;
114        }
115
116
117        @Override
118        public void calculateHashes() {
119                if (myHashIdentity != null || myHashUri != null) {
120                        return;
121                }
122
123                String resourceType = getResourceType();
124                String paramName = getParamName();
125                String uri = getUri();
126                setHashIdentity(calculateHashIdentity(getPartitionSettings(), getPartitionId(), resourceType, paramName));
127                setHashUri(calculateHashUri(getPartitionSettings(), getPartitionId(), resourceType, paramName, uri));
128        }
129
130        @Override
131        public boolean equals(Object theObj) {
132                if (this == theObj) {
133                        return true;
134                }
135                if (theObj == null) {
136                        return false;
137                }
138                if (!(theObj instanceof ResourceIndexedSearchParamUri)) {
139                        return false;
140                }
141                ResourceIndexedSearchParamUri obj = (ResourceIndexedSearchParamUri) theObj;
142                EqualsBuilder b = new EqualsBuilder();
143                b.append(getResourceType(), obj.getResourceType());
144                b.append(getParamName(), obj.getParamName());
145                b.append(getUri(), obj.getUri());
146                b.append(getHashUri(), obj.getHashUri());
147                b.append(getHashIdentity(), obj.getHashIdentity());
148                return b.isEquals();
149        }
150
151        private Long getHashIdentity() {
152                return myHashIdentity;
153        }
154
155        private void setHashIdentity(long theHashIdentity) {
156                myHashIdentity = theHashIdentity;
157        }
158
159        public Long getHashUri() {
160                return myHashUri;
161        }
162
163        public void setHashUri(Long theHashUri) {
164                myHashUri = theHashUri;
165        }
166
167        @Override
168        public Long getId() {
169                return myId;
170        }
171
172        @Override
173        public void setId(Long theId) {
174                myId = theId;
175        }
176
177
178        public String getUri() {
179                return myUri;
180        }
181
182        public ResourceIndexedSearchParamUri setUri(String theUri) {
183                myUri = StringUtils.defaultIfBlank(theUri, null);
184                return this;
185        }
186
187        @Override
188        public int hashCode() {
189                HashCodeBuilder b = new HashCodeBuilder();
190                b.append(getResourceType());
191                b.append(getParamName());
192                b.append(getUri());
193                b.append(getHashUri());
194                b.append(getHashIdentity());
195                return b.toHashCode();
196        }
197
198        @Override
199        public IQueryParameterType toQueryParameterType() {
200                return new UriParam(getUri());
201        }
202
203        @Override
204        public String toString() {
205                ToStringBuilder b = new ToStringBuilder(this);
206                b.append("id", getId());
207                b.append("resourceId", getResourcePid());
208                b.append("paramName", getParamName());
209                b.append("uri", myUri);
210                return b.toString();
211        }
212
213        @Override
214        public boolean matches(IQueryParameterType theParam) {
215                if (!(theParam instanceof UriParam)) {
216                        return false;
217                }
218                UriParam uri = (UriParam) theParam;
219                return defaultString(getUri()).equalsIgnoreCase(uri.getValueNotNull());
220        }
221
222        public static long calculateHashUri(PartitionSettings thePartitionSettings, PartitionablePartitionId theRequestPartitionId, String theResourceType, String theParamName, String theUri) {
223                RequestPartitionId requestPartitionId = PartitionablePartitionId.toRequestPartitionId(theRequestPartitionId);
224                return calculateHashUri(thePartitionSettings, requestPartitionId, theResourceType, theParamName, theUri);
225        }
226
227        public static long calculateHashUri(PartitionSettings thePartitionSettings, RequestPartitionId theRequestPartitionId, String theResourceType, String theParamName, String theUri) {
228                return hash(thePartitionSettings, theRequestPartitionId, theResourceType, theParamName, theUri);
229        }
230
231
232}