001/*- 002 * #%L 003 * HAPI FHIR Subscription Server 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.jpa.subscription.submit.interceptor.validator; 021 022import ca.uhn.fhir.i18n.Msg; 023import ca.uhn.fhir.jpa.api.dao.DaoRegistry; 024import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionMatchingStrategy; 025import ca.uhn.fhir.jpa.subscription.match.matcher.matching.SubscriptionStrategyEvaluator; 026import ca.uhn.fhir.jpa.subscription.match.matcher.subscriber.SubscriptionCriteriaParser; 027import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; 028 029import static org.apache.commons.lang3.StringUtils.isBlank; 030 031public class SubscriptionQueryValidator { 032 private final DaoRegistry myDaoRegistry; 033 private final SubscriptionStrategyEvaluator mySubscriptionStrategyEvaluator; 034 035 public SubscriptionQueryValidator( 036 DaoRegistry theDaoRegistry, SubscriptionStrategyEvaluator theSubscriptionStrategyEvaluator) { 037 myDaoRegistry = theDaoRegistry; 038 mySubscriptionStrategyEvaluator = theSubscriptionStrategyEvaluator; 039 } 040 041 public void validateCriteria(String theCriteria, String theFieldName) { 042 if (isBlank(theCriteria)) { 043 throw new UnprocessableEntityException(Msg.code(11) + theFieldName + " must be populated"); 044 } 045 046 SubscriptionCriteriaParser.SubscriptionCriteria parsedCriteria = SubscriptionCriteriaParser.parse(theCriteria); 047 if (parsedCriteria == null) { 048 throw new UnprocessableEntityException(Msg.code(12) + theFieldName + " can not be parsed"); 049 } 050 051 if (parsedCriteria.getType() == SubscriptionCriteriaParser.TypeEnum.STARTYPE_EXPRESSION) { 052 return; 053 } 054 055 for (String next : parsedCriteria.getApplicableResourceTypes()) { 056 if (!myDaoRegistry.isResourceTypeSupported(next)) { 057 throw new UnprocessableEntityException( 058 Msg.code(13) + theFieldName + " contains invalid/unsupported resource type: " + next); 059 } 060 } 061 062 if (parsedCriteria.getType() != SubscriptionCriteriaParser.TypeEnum.SEARCH_EXPRESSION) { 063 return; 064 } 065 066 int sep = theCriteria.indexOf('?'); 067 if (sep <= 1) { 068 throw new UnprocessableEntityException( 069 Msg.code(14) + theFieldName + " must be in the form \"{Resource Type}?[params]\""); 070 } 071 072 String resType = theCriteria.substring(0, sep); 073 if (resType.contains("/")) { 074 throw new UnprocessableEntityException( 075 Msg.code(15) + theFieldName + " must be in the form \"{Resource Type}?[params]\""); 076 } 077 } 078 079 public SubscriptionMatchingStrategy determineStrategy(String theCriteriaString) { 080 return mySubscriptionStrategyEvaluator.determineStrategy(theCriteriaString); 081 } 082}