001/* 002 * #%L 003 * HAPI FHIR - Server Framework 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.rest.server; 021 022import ca.uhn.fhir.model.primitive.InstantDt; 023import ca.uhn.fhir.rest.api.server.IBundleProvider; 024import ca.uhn.fhir.rest.server.method.ResponsePage; 025import jakarta.annotation.Nonnull; 026import org.apache.commons.lang3.builder.ToStringBuilder; 027import org.hl7.fhir.instance.model.api.IBaseResource; 028import org.hl7.fhir.instance.model.api.IPrimitiveType; 029 030import java.util.Arrays; 031import java.util.Collections; 032import java.util.Date; 033import java.util.List; 034 035public class SimpleBundleProvider implements IBundleProvider { 036 037 private final List<? extends IBaseResource> myList; 038 private final String myUuid; 039 private Integer myPreferredPageSize; 040 private Integer mySize; 041 private IPrimitiveType<Date> myPublished = InstantDt.withCurrentTime(); 042 private Integer myCurrentPageOffset; 043 private Integer myCurrentPageSize; 044 private ResponsePage.ResponsePageBuilder myPageBuilder; 045 046 /** 047 * The actual number of resources we have tried to fetch. 048 * This value will only be populated if there is a 049 * _count query parameter provided. 050 * In which case, it will be the total number of resources 051 * we tried to fetch (should be _count + 1 for accurate paging) 052 */ 053 private int myTotalResourcesRequestedReturned = -1; 054 055 /** 056 * Constructor 057 */ 058 public SimpleBundleProvider(IBaseResource theResource) { 059 this(Collections.singletonList(theResource)); 060 } 061 062 /** 063 * Create an empty bundle 064 */ 065 public SimpleBundleProvider() { 066 this(Collections.emptyList()); 067 } 068 069 /** 070 * Constructor 071 */ 072 public SimpleBundleProvider(List<? extends IBaseResource> theList) { 073 this(theList, null); 074 } 075 076 /** 077 * Constructor 078 * 079 * @since 6.8.0 080 */ 081 public SimpleBundleProvider(IBaseResource... theList) { 082 this(Arrays.asList(theList), null); 083 } 084 085 public SimpleBundleProvider(List<? extends IBaseResource> theList, String theUuid) { 086 myList = theList; 087 myUuid = theUuid; 088 setSize(theList.size()); 089 } 090 091 /** 092 * Constructor that provides only a size but no actual data (useful for _count = 0) 093 */ 094 public SimpleBundleProvider(int theSize) { 095 myList = Collections.emptyList(); 096 myUuid = null; 097 setSize(theSize); 098 } 099 100 /** 101 * @since 5.5.0 102 */ 103 @Override 104 public Integer getCurrentPageOffset() { 105 return myCurrentPageOffset; 106 } 107 108 /** 109 * @since 5.5.0 110 */ 111 public void setCurrentPageOffset(Integer theCurrentPageOffset) { 112 myCurrentPageOffset = theCurrentPageOffset; 113 } 114 115 /** 116 * @since 5.5.0 117 */ 118 @Override 119 public Integer getCurrentPageSize() { 120 return myCurrentPageSize; 121 } 122 123 /** 124 * @since 5.5.0 125 */ 126 public void setCurrentPageSize(Integer theCurrentPageSize) { 127 myCurrentPageSize = theCurrentPageSize; 128 } 129 130 /** 131 * Returns the results stored in this provider 132 */ 133 protected List<? extends IBaseResource> getList() { 134 return myList; 135 } 136 137 @Override 138 public IPrimitiveType<Date> getPublished() { 139 return myPublished; 140 } 141 142 /** 143 * By default this class uses the object creation date/time (for this object) 144 * to determine {@link #getPublished() the published date} but this 145 * method may be used to specify an alternate date/time 146 */ 147 public void setPublished(IPrimitiveType<Date> thePublished) { 148 myPublished = thePublished; 149 } 150 151 @SuppressWarnings("unchecked") 152 @Nonnull 153 @Override 154 public List<IBaseResource> getResources( 155 int theFromIndex, int theToIndex, @Nonnull ResponsePage.ResponsePageBuilder theResponsePageBuilder) { 156 theResponsePageBuilder.setTotalRequestedResourcesFetched(myTotalResourcesRequestedReturned); 157 return (List<IBaseResource>) 158 myList.subList(Math.min(theFromIndex, myList.size()), Math.min(theToIndex, myList.size())); 159 } 160 161 @Override 162 public String getUuid() { 163 return myUuid; 164 } 165 166 public void setTotalResourcesRequestedReturned(int theAmount) { 167 myTotalResourcesRequestedReturned = theAmount; 168 } 169 170 /** 171 * Defaults to null 172 */ 173 @Override 174 public Integer preferredPageSize() { 175 return myPreferredPageSize; 176 } 177 178 /** 179 * Sets the preferred page size to be returned by {@link #preferredPageSize()}. 180 * Default is <code>null</code>. 181 */ 182 public void setPreferredPageSize(Integer thePreferredPageSize) { 183 myPreferredPageSize = thePreferredPageSize; 184 } 185 186 /** 187 * Sets the total number of results, if this provider 188 * corresponds to a single page within a larger search result 189 */ 190 public SimpleBundleProvider setSize(Integer theSize) { 191 mySize = theSize; 192 return this; 193 } 194 195 @Override 196 public Integer size() { 197 return mySize; 198 } 199 200 @Override 201 public String toString() { 202 return new ToStringBuilder(this).append("mySize", mySize).toString(); 203 } 204}