001package ca.uhn.fhir.rest.server.interceptor;
002
003/*-
004 * #%L
005 * HAPI FHIR - Server Framework
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.interceptor.api.Hook;
025import ca.uhn.fhir.interceptor.api.Interceptor;
026import ca.uhn.fhir.interceptor.api.Pointcut;
027import ca.uhn.fhir.rest.api.EncodingEnum;
028import ca.uhn.fhir.rest.api.server.RequestDetails;
029import ca.uhn.fhir.util.ClasspathUtil;
030import org.apache.commons.lang3.Validate;
031import org.hl7.fhir.instance.model.api.IBaseConformance;
032
033/**
034 * This interceptor replaces the auto-generated CapabilityStatement that is generated
035 * by the HAPI FHIR Server with a static hard-coded resource.
036 */
037@Interceptor
038public class StaticCapabilityStatementInterceptor {
039
040        private String myCapabilityStatementResource;
041        private volatile IBaseConformance myCapabilityStatement;
042
043        /**
044         * Sets the CapabilityStatement to use
045         *
046         * @see #setCapabilityStatementResource(String) #setCapabilityStatementResource(String) is an alternate way to supply the CapabilityStatement
047         */
048        public void setCapabilityStatement(IBaseConformance theCapabilityStatement) {
049                myCapabilityStatement = theCapabilityStatement;
050        }
051
052        /**
053         * Sets the classpath location of the CapabilityStatement to use. If this method is used to supply
054         * the CapabiltyStatement, then the given classpath resource will be read and parsed as a FHIR
055         * CapabilityStatement.
056         *
057         * @see #setCapabilityStatement(IBaseConformance) #setCapabilityStatement(IBaseConformance) is an alternate way to supply the CapabilityStatement
058         */
059        public void setCapabilityStatementResource(String theClasspath) {
060                myCapabilityStatementResource = theClasspath;
061                myCapabilityStatement = null;
062        }
063
064        @Hook(Pointcut.SERVER_CAPABILITY_STATEMENT_GENERATED)
065        public IBaseConformance hook(RequestDetails theRequestDetails) {
066                IBaseConformance retVal = myCapabilityStatement;
067
068                if (retVal == null) {
069                        Validate.notBlank(myCapabilityStatementResource, "No CapabilityStatement defined");
070                        String output = ClasspathUtil.loadResource(myCapabilityStatementResource);
071
072                        FhirContext ctx = theRequestDetails.getFhirContext();
073                        EncodingEnum encoding = EncodingEnum.detectEncodingNoDefault(output);
074                        Validate.notNull(encoding, "Could not determine FHIR encoding for resource: %s", myCapabilityStatementResource);
075
076                        retVal = (IBaseConformance) encoding
077                                .newParser(ctx)
078                                .parseResource(output);
079                        myCapabilityStatement = retVal;
080                }
081
082                return retVal;
083        }
084
085}