001package ca.uhn.fhir.rest.server.method; 002 003import ca.uhn.fhir.i18n.Msg; 004import static org.apache.commons.lang3.StringUtils.isBlank; 005/* 006 * #%L 007 * HAPI FHIR - Server Framework 008 * %% 009 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 010 * %% 011 * Licensed under the Apache License, Version 2.0 (the "License"); 012 * you may not use this file except in compliance with the License. 013 * You may obtain a copy of the License at 014 * 015 * http://www.apache.org/licenses/LICENSE-2.0 016 * 017 * Unless required by applicable law or agreed to in writing, software 018 * distributed under the License is distributed on an "AS IS" BASIS, 019 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 020 * See the License for the specific language governing permissions and 021 * limitations under the License. 022 * #L% 023 */ 024import static org.apache.commons.lang3.StringUtils.isNotBlank; 025 026import java.lang.reflect.Method; 027import java.util.Collections; 028import java.util.Set; 029 030import org.hl7.fhir.instance.model.api.IBaseResource; 031import org.hl7.fhir.instance.model.api.IIdType; 032 033import ca.uhn.fhir.context.FhirContext; 034import ca.uhn.fhir.rest.annotation.Update; 035import ca.uhn.fhir.rest.api.Constants; 036import ca.uhn.fhir.rest.api.MethodOutcome; 037import ca.uhn.fhir.rest.api.RequestTypeEnum; 038import ca.uhn.fhir.rest.api.RestOperationTypeEnum; 039import ca.uhn.fhir.rest.api.server.RequestDetails; 040import ca.uhn.fhir.rest.param.ParameterUtil; 041import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 042 043import javax.annotation.Nonnull; 044 045public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { 046 047 public UpdateMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { 048 super(theMethod, theContext, Update.class, theProvider); 049 } 050 051 @Override 052 protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) { 053 IIdType id = theRequest.getId(); 054 id = applyETagAsVersion(theRequest, id); 055 if (theRequest.getId() != null && theRequest.getId().hasVersionIdPart() == false) { 056 if (id != null && id.hasVersionIdPart()) { 057 theRequest.getId().setValue(id.getValue()); 058 } 059 } 060 super.addParametersForServerRequest(theRequest, theParams); 061 } 062 063 public static IIdType applyETagAsVersion(RequestDetails theRequest, IIdType id) { 064 String ifMatchValue = theRequest.getHeader(Constants.HEADER_IF_MATCH); 065 if (isNotBlank(ifMatchValue)) { 066 ifMatchValue = ParameterUtil.parseETagValue(ifMatchValue); 067 if (id != null && id.hasVersionIdPart() == false) { 068 id = id.withVersion(ifMatchValue); 069 } 070 } 071 return id; 072 } 073 074 @Override 075 protected String getMatchingOperation() { 076 return null; 077 } 078 079 @Nonnull 080 @Override 081 public RestOperationTypeEnum getRestOperationType() { 082 return RestOperationTypeEnum.UPDATE; 083 } 084 085 /* 086 * @Override public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { if 087 * (super.incomingServerRequestMatchesMethod(theRequest)) { if (myVersionIdParameterIndex != null) { if 088 * (theRequest.getVersionId() == null) { return false; } } else { if (theRequest.getVersionId() != null) { return 089 * false; } } return true; } else { return false; } } 090 */ 091 092 @Override 093 protected Set<RequestTypeEnum> provideAllowableRequestTypes() { 094 return Collections.singleton(RequestTypeEnum.PUT); 095 } 096 097 @Override 098 protected void validateResourceIdAndUrlIdForNonConditionalOperation(IBaseResource theResource, String theResourceId, String theUrlId, String theMatchUrl) { 099 if (isBlank(theMatchUrl)) { 100 if (isBlank(theUrlId)) { 101 String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "noIdInUrlForUpdate"); 102 throw new InvalidRequestException(Msg.code(418) + msg); 103 } 104 if (isBlank(theResourceId)) { 105 String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "noIdInBodyForUpdate"); 106 throw new InvalidRequestException(Msg.code(419) + msg); 107 } 108 if (!theResourceId.equals(theUrlId)) { 109 String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBindingWithResourceParam.class, "incorrectIdForUpdate", theResourceId, theUrlId); 110 throw new InvalidRequestException(Msg.code(420) + msg); 111 } 112 } else { 113 theResource.setId((IIdType) null); 114 } 115 116 } 117}