001package ca.uhn.fhir.jpa.dao.dstu3; 002 003/*- 004 * #%L 005 * HAPI FHIR Storage api 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.i18n.Msg; 024import ca.uhn.fhir.context.FhirContext; 025import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; 026import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; 027import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; 028import ca.uhn.fhir.util.BundleUtil; 029import org.hl7.fhir.dstu3.model.Bundle; 030import org.hl7.fhir.dstu3.model.OperationOutcome; 031import org.hl7.fhir.dstu3.model.Resource; 032import org.hl7.fhir.exceptions.FHIRException; 033import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; 034import org.hl7.fhir.instance.model.api.IBaseResource; 035 036import java.util.Date; 037import java.util.List; 038 039import static org.apache.commons.lang3.StringUtils.isBlank; 040 041public class TransactionProcessorVersionAdapterDstu3 implements ITransactionProcessorVersionAdapter<Bundle, Bundle.BundleEntryComponent> { 042 @Override 043 public void setResponseStatus(Bundle.BundleEntryComponent theBundleEntry, String theStatus) { 044 theBundleEntry.getResponse().setStatus(theStatus); 045 } 046 047 @Override 048 public void setResponseLastModified(Bundle.BundleEntryComponent theBundleEntry, Date theLastModified) { 049 theBundleEntry.getResponse().setLastModified(theLastModified); 050 } 051 052 @Override 053 public void setResource(Bundle.BundleEntryComponent theBundleEntry, IBaseResource theResource) { 054 theBundleEntry.setResource((Resource) theResource); 055 } 056 057 @Override 058 public IBaseResource getResource(Bundle.BundleEntryComponent theBundleEntry) { 059 return theBundleEntry.getResource(); 060 } 061 062 @Override 063 public String getBundleType(Bundle theRequest) { 064 if (theRequest.getType() == null) { 065 return null; 066 } 067 return theRequest.getTypeElement().getValue().toCode(); 068 } 069 070 @Override 071 public void populateEntryWithOperationOutcome(BaseServerResponseException theCaughtEx, Bundle.BundleEntryComponent theEntry) { 072 OperationOutcome oo = new OperationOutcome(); 073 oo.addIssue() 074 .setSeverity(OperationOutcome.IssueSeverity.ERROR) 075 .setDiagnostics(theCaughtEx.getMessage()) 076 .setCode(OperationOutcome.IssueType.EXCEPTION); 077 theEntry.getResponse().setOutcome(oo); 078 } 079 080 @Override 081 public Bundle createBundle(String theBundleType) { 082 Bundle resp = new Bundle(); 083 try { 084 resp.setType(Bundle.BundleType.fromCode(theBundleType)); 085 } catch (FHIRException theE) { 086 throw new InternalErrorException(Msg.code(548) + "Unknown bundle type: " + theBundleType); 087 } 088 return resp; 089 } 090 091 @Override 092 public List<Bundle.BundleEntryComponent> getEntries(Bundle theRequest) { 093 return theRequest.getEntry(); 094 } 095 096 @Override 097 public void addEntry(Bundle theBundle, Bundle.BundleEntryComponent theEntry) { 098 theBundle.addEntry(theEntry); 099 } 100 101 @Override 102 public Bundle.BundleEntryComponent addEntry(Bundle theBundle) { 103 return theBundle.addEntry(); 104 } 105 106 @Override 107 public String getEntryRequestVerb(FhirContext theContext, Bundle.BundleEntryComponent theEntry) { 108 String retVal = null; 109 Bundle.HTTPVerb value = theEntry.getRequest().getMethodElement().getValue(); 110 if (value != null) { 111 retVal = value.toCode(); 112 } 113 114 /* 115 * This is a workaround for the fact that PATCH isn't a valid constant for 116 * DSTU3 Bundle.entry.request.method (it was added in R4) 117 */ 118 if (isBlank(retVal)) { 119 Resource resource = theEntry.getResource(); 120 boolean isPatch = BundleUtil.isDstu3TransactionPatch(theContext, resource); 121 122 if (isPatch) { 123 retVal = "PATCH"; 124 } 125 } 126 return retVal; 127 } 128 129 @Override 130 public String getFullUrl(Bundle.BundleEntryComponent theEntry) { 131 return theEntry.getFullUrl(); 132 } 133 134 @Override 135 public void setFullUrl(Bundle.BundleEntryComponent theEntry, String theFullUrl) { 136 theEntry.setFullUrl(theFullUrl); 137 } 138 139 @Override 140 public String getEntryIfNoneExist(Bundle.BundleEntryComponent theEntry) { 141 return theEntry.getRequest().getIfNoneExist(); 142 } 143 144 @Override 145 public String getEntryRequestUrl(Bundle.BundleEntryComponent theEntry) { 146 return theEntry.getRequest().getUrl(); 147 } 148 149 @Override 150 public void setResponseLocation(Bundle.BundleEntryComponent theEntry, String theResponseLocation) { 151 theEntry.getResponse().setLocation(theResponseLocation); 152 } 153 154 @Override 155 public void setResponseETag(Bundle.BundleEntryComponent theEntry, String theEtag) { 156 theEntry.getResponse().setEtag(theEtag); 157 } 158 159 @Override 160 public String getEntryRequestIfMatch(Bundle.BundleEntryComponent theEntry) { 161 return theEntry.getRequest().getIfMatch(); 162 } 163 164 @Override 165 public String getEntryRequestIfNoneExist(Bundle.BundleEntryComponent theEntry) { 166 return theEntry.getRequest().getIfNoneExist(); 167 } 168 169 @Override 170 public String getEntryRequestIfNoneMatch(Bundle.BundleEntryComponent theEntry) { 171 return theEntry.getRequest().getIfNoneMatch(); 172 } 173 174 @Override 175 public void setResponseOutcome(Bundle.BundleEntryComponent theEntry, IBaseOperationOutcome theOperationOutcome) { 176 theEntry.getResponse().setOutcome((Resource) theOperationOutcome); 177 } 178 179 @Override 180 public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) { 181 theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb)); 182 } 183 184 @Override 185 public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) { 186 theEntry.getRequest().setUrl(theUrl); 187 } 188 189}