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 static org.apache.commons.lang3.StringUtils.defaultString;
024import static org.apache.commons.lang3.StringUtils.isBlank;
025
026import java.math.BigDecimal;
027import java.util.Objects;
028
029import javax.persistence.Column;
030import javax.persistence.Embeddable;
031import javax.persistence.Entity;
032import javax.persistence.GeneratedValue;
033import javax.persistence.GenerationType;
034import javax.persistence.Id;
035import javax.persistence.Index;
036import javax.persistence.SequenceGenerator;
037import javax.persistence.Table;
038
039import org.apache.commons.lang3.builder.EqualsBuilder;
040import org.apache.commons.lang3.builder.ToStringBuilder;
041import org.apache.commons.lang3.builder.ToStringStyle;
042import org.hibernate.search.mapper.pojo.mapping.definition.annotation.ScaledNumberField;
043
044import ca.uhn.fhir.jpa.model.config.PartitionSettings;
045import ca.uhn.fhir.model.api.IQueryParameterType;
046import ca.uhn.fhir.rest.param.QuantityParam;
047
048//@formatter:off
049@Embeddable
050@Entity
051@Table(name = "HFJ_SPIDX_QUANTITY", indexes = {
052//      We used to have an index named IDX_SP_QUANTITY - Dont reuse
053        @Index(name = "IDX_SP_QUANTITY_HASH", columnList = "HASH_IDENTITY,SP_VALUE"),
054        @Index(name = "IDX_SP_QUANTITY_HASH_UN", columnList = "HASH_IDENTITY_AND_UNITS,SP_VALUE"),
055        @Index(name = "IDX_SP_QUANTITY_HASH_SYSUN", columnList = "HASH_IDENTITY_SYS_UNITS,SP_VALUE"),
056        @Index(name = "IDX_SP_QUANTITY_UPDATED", columnList = "SP_UPDATED"),
057        @Index(name = "IDX_SP_QUANTITY_RESID", columnList = "RES_ID")
058})
059public class ResourceIndexedSearchParamQuantity extends ResourceIndexedSearchParamBaseQuantity {
060
061        private static final long serialVersionUID = 1L;
062        
063        @Id
064        @SequenceGenerator(name = "SEQ_SPIDX_QUANTITY", sequenceName = "SEQ_SPIDX_QUANTITY")
065        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SPIDX_QUANTITY")
066        @Column(name = "SP_ID")
067        private Long myId;
068        
069        @Column(name = "SP_VALUE", nullable = true)
070        @ScaledNumberField
071        public Double myValue;
072
073        public ResourceIndexedSearchParamQuantity() {
074                super();
075        }
076
077        public ResourceIndexedSearchParamQuantity(PartitionSettings thePartitionSettings, String theResourceType, String theParamName, BigDecimal theValue, String theSystem, String theUnits) {
078                this();
079                setPartitionSettings(thePartitionSettings);
080                setResourceType(theResourceType);
081                setParamName(theParamName);
082                setSystem(theSystem);
083                setValue(theValue);
084                setUnits(theUnits);
085                calculateHashes();
086        }
087
088        @Override
089        public <T extends BaseResourceIndex> void copyMutableValuesFrom(T theSource) {
090                super.copyMutableValuesFrom(theSource);
091                ResourceIndexedSearchParamQuantity source = (ResourceIndexedSearchParamQuantity) theSource;
092                mySystem = source.mySystem;
093                myUnits = source.myUnits;
094                myValue = source.myValue;
095                setHashIdentity(source.getHashIdentity());
096                setHashIdentityAndUnits(source.getHashIdentityAndUnits());
097                setHashIdentitySystemAndUnits(source.getHashIdentitySystemAndUnits());
098        }
099        
100        public BigDecimal getValue() {
101                return myValue != null ? new BigDecimal(myValue) : null;
102        }
103
104        public ResourceIndexedSearchParamQuantity setValue(BigDecimal theValue) {
105                myValue = theValue != null ? theValue.doubleValue() : null;
106                return this;
107        }
108        
109        @Override
110        public Long getId() {
111                return myId;
112        }
113
114        @Override
115        public void setId(Long theId) {
116                myId = theId;
117        }
118        
119        @Override
120        public IQueryParameterType toQueryParameterType() {
121                return new QuantityParam(null, getValue(), getSystem(), getUnits());
122        }
123
124        @Override
125        public String toString() {
126                ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
127                b.append("paramName", getParamName());
128                b.append("resourceId", getResourcePid());
129                b.append("system", getSystem());
130                b.append("units", getUnits());
131                b.append("value", getValue());
132                b.append("missing", isMissing());
133                b.append("hashIdentitySystemAndUnits", getHashIdentitySystemAndUnits());
134                return b.build();
135        }
136
137        @Override
138        public boolean equals(Object theObj) {
139                if (this == theObj) {
140                        return true;
141                }
142                if (theObj == null) {
143                        return false;
144                }
145                if (!(theObj instanceof ResourceIndexedSearchParamQuantity)) {
146                        return false;
147                }
148                ResourceIndexedSearchParamQuantity obj = (ResourceIndexedSearchParamQuantity) theObj;
149                EqualsBuilder b = new EqualsBuilder();
150                b.append(getResourceType(), obj.getResourceType());
151                b.append(getParamName(), obj.getParamName());
152                b.append(getHashIdentity(), obj.getHashIdentity());
153                b.append(getHashIdentityAndUnits(), obj.getHashIdentityAndUnits());
154                b.append(getHashIdentitySystemAndUnits(), obj.getHashIdentitySystemAndUnits());
155                b.append(isMissing(), obj.isMissing());
156                b.append(getValue(), obj.getValue());
157                return b.isEquals();
158        }
159        
160        @Override
161        public boolean matches(IQueryParameterType theParam) {
162                
163                if (!(theParam instanceof QuantityParam)) {
164                        return false;
165                }
166                QuantityParam quantity = (QuantityParam) theParam;
167                boolean retval = false;
168
169                // Only match on system if it wasn't specified
170                String quantityUnitsString = defaultString(quantity.getUnits());
171                if (quantity.getSystem() == null && isBlank(quantityUnitsString)) {
172                        if (Objects.equals(getValue(), quantity.getValue())) {
173                                retval = true;
174                        }
175                } else {
176                        String unitsString = defaultString(getUnits());
177                        if (quantity.getSystem() == null) {
178                                if (unitsString.equalsIgnoreCase(quantityUnitsString) &&
179                                        Objects.equals(getValue(), quantity.getValue())) {
180                                        retval = true;
181                                }
182                        } else if (isBlank(quantityUnitsString)) {
183                                if (getSystem().equalsIgnoreCase(quantity.getSystem()) &&
184                                        Objects.equals(getValue(), quantity.getValue())) {
185                                        retval = true;
186                                }
187                        } else {
188                                if (getSystem().equalsIgnoreCase(quantity.getSystem()) &&
189                                        unitsString.equalsIgnoreCase(quantityUnitsString) &&
190                                        Objects.equals(getValue(), quantity.getValue())) {
191                                        retval = true;
192                                }
193                        }
194                }
195                
196                return retval;
197        }
198
199}