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