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}