001package ca.uhn.fhir.rest.server.interceptor.validation;
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.interceptor.api.Hook;
024import ca.uhn.fhir.interceptor.api.Interceptor;
025import ca.uhn.fhir.interceptor.api.Pointcut;
026import ca.uhn.fhir.validation.SingleValidationMessage;
027import ca.uhn.fhir.validation.ValidationResult;
028
029import java.util.ArrayList;
030import java.util.Arrays;
031import java.util.List;
032import java.util.regex.Pattern;
033
034import static org.apache.commons.lang3.StringUtils.isNotBlank;
035
036@Interceptor
037public class ValidationMessageSuppressingInterceptor {
038
039        private List<Pattern> mySuppressPatterns = new ArrayList<>();
040
041        /**
042         * Constructor
043         */
044        public ValidationMessageSuppressingInterceptor() {
045                super();
046        }
047
048        /**
049         * Supplies one or more patterns to suppress. Any validation messages (of any severity) will be suppressed
050         * if they match this pattern. Patterns are in Java Regular Expression format (as defined by the {@link Pattern} class)
051         * and are treated as partial maches. They are also case insensitive.
052         * <p>
053         *    For example, a pattern of <code>loinc.*1234</code> would suppress the following message:<br/>
054         *    <code>The LOINC code 1234 is not valid</code>
055         * </p>
056         */
057        public ValidationMessageSuppressingInterceptor addMessageSuppressionPatterns(String... thePatterns) {
058                return addMessageSuppressionPatterns(Arrays.asList(thePatterns));
059        }
060
061        /**
062         * Supplies one or more patterns to suppress. Any validation messages (of any severity) will be suppressed
063         * if they match this pattern. Patterns are in Java Regular Expression format (as defined by the {@link Pattern} class)
064         * and are treated as partial maches. They are also case insensitive.
065         * <p>
066         *    For example, a pattern of <code>loinc.*1234</code> would suppress the following message:<br/>
067         *    <code>The LOINC code 1234 is not valid</code>
068         * </p>
069         */
070        public ValidationMessageSuppressingInterceptor addMessageSuppressionPatterns(List<String> thePatterns) {
071                for (String next : thePatterns) {
072                        if (isNotBlank(next)) {
073                                Pattern pattern = Pattern.compile(next, Pattern.CASE_INSENSITIVE);
074                                mySuppressPatterns.add(pattern);
075                        }
076                }
077                return this;
078        }
079
080
081        @Hook(Pointcut.VALIDATION_COMPLETED)
082        public ValidationResult handle(ValidationResult theResult) {
083
084                List<SingleValidationMessage> newMessages = new ArrayList<>(theResult.getMessages().size());
085                for (SingleValidationMessage next : theResult.getMessages()) {
086
087                        String nextMessage = next.getMessage();
088                        boolean suppress = false;
089                        for (Pattern nextSuppressPattern : mySuppressPatterns) {
090                                if (nextSuppressPattern.matcher(nextMessage).find()) {
091                                        suppress = true;
092                                        break;
093                                }
094                        }
095
096                        if (!suppress) {
097                                newMessages.add(next);
098                        }
099                }
100
101                if (newMessages.size() == theResult.getMessages().size()) {
102                        return null;
103                }
104
105                return new ValidationResult(theResult.getContext(), newMessages);
106        }
107
108}