001package ca.uhn.fhir.rest.api;
002
003/*
004 * #%L
005 * HAPI FHIR - Core Library
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.context.FhirContext;
024import ca.uhn.fhir.rest.annotation.Patch;
025import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
026import ca.uhn.fhir.util.UrlUtil;
027
028import javax.annotation.Nonnull;
029import java.util.HashMap;
030import java.util.Map;
031
032import static org.apache.commons.lang3.StringUtils.defaultString;
033import static org.apache.commons.lang3.StringUtils.isBlank;
034
035/**
036 * Parameter type for methods annotated with {@link Patch}
037 */
038public enum PatchTypeEnum {
039
040        JSON_PATCH(Constants.CT_JSON_PATCH),
041        XML_PATCH(Constants.CT_XML_PATCH),
042        FHIR_PATCH_JSON(Constants.CT_FHIR_JSON_NEW),
043        FHIR_PATCH_XML(Constants.CT_FHIR_XML_NEW);
044
045        private static volatile Map<String, PatchTypeEnum> ourContentTypeToPatchType;
046        private final String myContentType;
047
048        PatchTypeEnum(String theContentType) {
049                myContentType = theContentType;
050        }
051
052        public String getContentType() {
053                return myContentType;
054        }
055
056        @Nonnull
057        public static PatchTypeEnum forContentTypeOrThrowInvalidRequestException(FhirContext theContext, String theContentType) {
058                String contentType = defaultString(theContentType);
059                int semiColonIdx = contentType.indexOf(';');
060                if (semiColonIdx != -1) {
061                        contentType = theContentType.substring(0, semiColonIdx);
062                }
063                contentType = contentType.trim();
064
065
066                Map<String, PatchTypeEnum> map = ourContentTypeToPatchType;
067                if (map == null) {
068                        map = new HashMap<>();
069                        for (PatchTypeEnum next : values()) {
070                                map.put(next.getContentType(), next);
071                        }
072                        ourContentTypeToPatchType = map;
073                }
074
075                PatchTypeEnum retVal = map.get(contentType);
076                if (retVal == null) {
077                        if (isBlank(contentType)) {
078                                String msg = theContext.getLocalizer().getMessage(PatchTypeEnum.class, "missingPatchContentType");
079                                throw new InvalidRequestException(msg);
080                        }
081
082                        String msg = theContext.getLocalizer().getMessageSanitized(PatchTypeEnum.class, "invalidPatchContentType", contentType);
083                        throw new InvalidRequestException(msg);
084                }
085
086                return retVal;
087        }
088}