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.dao;
021
022import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId;
023import ca.uhn.fhir.rest.api.server.storage.BaseResourcePersistentId;
024import jakarta.annotation.Nonnull;
025import org.apache.commons.collections4.ComparatorUtils;
026
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.Collection;
030import java.util.Comparator;
031import java.util.HashSet;
032import java.util.List;
033import java.util.Objects;
034import java.util.Set;
035
036import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
037
038/**
039 * JPA implementation of IResourcePersistentId.  JPA uses a Long as the primary key.  This class should be used in any
040 * context where the pid is known to be a Long.
041 */
042public class JpaPid extends BaseResourcePersistentId<Long> implements Comparable<JpaPid> {
043        private final Long myId;
044        private PartitionablePartitionId myPartitionablePartitionId;
045
046        private static final Comparator<JpaPid> COMPARATOR;
047
048        static {
049                Comparator<JpaPid> partitionComparator =
050                                Comparator.comparing(t -> defaultIfNull(t.getPartitionId(), Integer.MIN_VALUE));
051                Comparator<JpaPid> idComparator = Comparator.comparing(t -> t.myId);
052                COMPARATOR = ComparatorUtils.chainedComparator(List.of(partitionComparator, idComparator));
053        }
054
055        private JpaPid(Long theId) {
056                super(null);
057                myId = theId;
058        }
059
060        private JpaPid(Long theId, Long theVersion) {
061                super(theVersion, null);
062                myId = theId;
063        }
064
065        private JpaPid(Long theId, String theResourceType) {
066                super(theResourceType);
067                myId = theId;
068        }
069
070        private JpaPid(Long theId, Long theVersion, String theResourceType) {
071                super(theVersion, theResourceType);
072                myId = theId;
073        }
074
075        public PartitionablePartitionId getPartitionablePartitionId() {
076                return myPartitionablePartitionId;
077        }
078
079        public JpaPid setPartitionablePartitionId(PartitionablePartitionId thePartitionablePartitionId) {
080                myPartitionablePartitionId = thePartitionablePartitionId;
081                return this;
082        }
083
084        public void setPartitionId(Integer thePartitionId) {
085                if (myPartitionablePartitionId == null) {
086                        myPartitionablePartitionId = new PartitionablePartitionId();
087                }
088                myPartitionablePartitionId.setPartitionId(thePartitionId);
089        }
090
091        public static List<Long> toLongList(JpaPid[] thePids) {
092                return toLongList(Arrays.asList(thePids));
093        }
094
095        public static List<Long> toLongList(Collection<JpaPid> thePids) {
096                List<Long> retVal = new ArrayList<>(thePids.size());
097                for (JpaPid next : thePids) {
098                        retVal.add(next.getId());
099                }
100                return retVal;
101        }
102
103        public static Set<Long> toLongSet(Collection<JpaPid> thePids) {
104                Set<Long> retVal = new HashSet<>(thePids.size());
105                for (JpaPid next : thePids) {
106                        retVal.add(next.getId());
107                }
108                return retVal;
109        }
110
111        public static List<JpaPid> fromLongList(Collection<Long> theResultList) {
112                List<JpaPid> retVal = new ArrayList<>(theResultList.size());
113                for (Long next : theResultList) {
114                        retVal.add(fromId(next));
115                }
116                return retVal;
117        }
118
119        public static JpaPid fromId(Long theId) {
120                return new JpaPid(theId);
121        }
122
123        public static JpaPid fromId(Long theId, Integer thePartitionId) {
124                JpaPid retVal = new JpaPid(theId);
125                retVal.setPartitionablePartitionId(PartitionablePartitionId.with(thePartitionId, null));
126                return retVal;
127        }
128
129        public static JpaPid fromIdAndVersion(Long theId, Long theVersion) {
130                return new JpaPid(theId, theVersion);
131        }
132
133        public static JpaPid fromIdAndResourceType(Long theId, String theResourceType) {
134                return new JpaPid(theId, theResourceType);
135        }
136
137        public static JpaPid fromIdAndVersionAndResourceType(Long theId, Long theVersion, String theResourceType) {
138                return new JpaPid(theId, theVersion, theResourceType);
139        }
140
141        @Override
142        public boolean equals(Object theO) {
143                if (this == theO) return true;
144                if (theO == null || getClass() != theO.getClass()) return false;
145                JpaPid jpaPid = (JpaPid) theO;
146                return myId.equals(jpaPid.myId);
147        }
148
149        @Override
150        public int hashCode() {
151                return Objects.hash(myId);
152        }
153
154        @Override
155        public Long getId() {
156                return myId;
157        }
158
159        @Override
160        public String toString() {
161                return myId.toString();
162        }
163
164        @Override
165        public int compareTo(@Nonnull JpaPid theOther) {
166                return COMPARATOR.compare(this, theOther);
167        }
168
169        public Integer getPartitionId() {
170                if (getPartitionablePartitionId() == null) {
171                        return null;
172                }
173                return getPartitionablePartitionId().getPartitionId();
174        }
175}