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.rest.api.server.RequestDetails;
023import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
024import ca.uhn.fhir.rest.server.method.MethodMatchEnum;
025
026import java.util.LinkedList;
027import java.util.List;
028
029/**
030 * Holds all method bindings for an individual resource type
031 */
032public class ResourceBinding {
033
034        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceBinding.class);
035
036        private String myResourceName;
037        private final LinkedList<BaseMethodBinding> myMethodBindings = new LinkedList<>();
038
039        /**
040         * Constructor
041         */
042        public ResourceBinding() {
043                super();
044        }
045
046        public BaseMethodBinding getMethod(RequestDetails theRequest) {
047                if (myMethodBindings.isEmpty()) {
048                        ourLog.warn("No methods exist for resource: {}", myResourceName);
049                        return null;
050                }
051
052                ourLog.debug("Looking for a handler for {}", theRequest);
053
054                /*
055                 * Look for the method with the highest match strength
056                 */
057
058                BaseMethodBinding matchedMethod = null;
059                MethodMatchEnum matchedMethodStrength = null;
060
061                for (BaseMethodBinding rm : myMethodBindings) {
062                        MethodMatchEnum nextMethodMatch = rm.incomingServerRequestMatchesMethod(theRequest);
063                        if (nextMethodMatch != MethodMatchEnum.NONE) {
064                                if (matchedMethodStrength == null || matchedMethodStrength.ordinal() < nextMethodMatch.ordinal()) {
065                                        matchedMethod = rm;
066                                        matchedMethodStrength = nextMethodMatch;
067                                }
068                                if (matchedMethodStrength == MethodMatchEnum.EXACT) {
069                                        break;
070                                }
071                        }
072                }
073
074                return matchedMethod;
075        }
076
077        public String getResourceName() {
078                return myResourceName;
079        }
080
081        public void setResourceName(String resourceName) {
082                this.myResourceName = resourceName;
083        }
084
085        public List<BaseMethodBinding> getMethodBindings() {
086                return myMethodBindings;
087        }
088
089        public void addMethod(BaseMethodBinding method) {
090                if (myMethodBindings.stream()
091                                .anyMatch(
092                                                t -> t.getMethod().toString().equals(method.getMethod().toString()))) {
093                        ourLog.warn(
094                                        "The following method has been registered twice against this RestfulServer: {}",
095                                        method.getMethod());
096                }
097                this.myMethodBindings.push(method);
098        }
099
100        @Override
101        public boolean equals(Object o) {
102                if (!(o instanceof ResourceBinding)) return false;
103                return myResourceName.equals(((ResourceBinding) o).getResourceName());
104        }
105
106        @Override
107        public int hashCode() {
108                return 0;
109        }
110}