
001package ca.uhn.fhir.jpa.subscription.match.matcher.subscriber; 002 003/*- 004 * #%L 005 * HAPI FHIR Subscription Server 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.jpa.searchparam.extractor.StringTrimmingTrimmerMatcher; 024import ca.uhn.fhir.rest.api.Constants; 025import com.google.common.collect.Sets; 026import org.apache.commons.lang3.builder.ToStringBuilder; 027import org.apache.commons.lang3.builder.ToStringStyle; 028import org.apache.commons.text.StringTokenizer; 029 030import javax.annotation.Nullable; 031import java.util.Collections; 032import java.util.List; 033import java.util.Set; 034 035import static org.apache.commons.lang3.StringUtils.isBlank; 036import static org.apache.commons.lang3.StringUtils.isNotBlank; 037import static org.apache.commons.lang3.StringUtils.trim; 038 039public enum SubscriptionCriteriaParser { 040 ; 041 042 public enum TypeEnum { 043 044 /** 045 * Normal search URL expression 046 */ 047 SEARCH_EXPRESSION, 048 049 /** 050 * Collection of resource types 051 */ 052 MULTITYPE_EXPRESSION, 053 054 /** 055 * All types 056 */ 057 STARTYPE_EXPRESSION 058 059 } 060 061 public static class SubscriptionCriteria { 062 063 private final TypeEnum myType; 064 private final String myCriteria; 065 private final Set<String> myApplicableResourceTypes; 066 067 private SubscriptionCriteria(TypeEnum theType, String theCriteria, Set<String> theApplicableResourceTypes) { 068 myType = theType; 069 myCriteria = theCriteria; 070 myApplicableResourceTypes = theApplicableResourceTypes; 071 } 072 073 @Override 074 public String toString() { 075 ToStringBuilder retVal = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 076 retVal.append("type", myType); 077 if (isNotBlank(myCriteria)) { 078 retVal.append("criteria", myCriteria); 079 } 080 if (myApplicableResourceTypes != null) { 081 retVal.append("applicableResourceTypes", myApplicableResourceTypes); 082 } 083 return retVal.toString(); 084 } 085 086 public TypeEnum getType() { 087 return myType; 088 } 089 090 public String getCriteria() { 091 return myCriteria; 092 } 093 094 public Set<String> getApplicableResourceTypes() { 095 return myApplicableResourceTypes; 096 } 097 } 098 099 @Nullable 100 public static SubscriptionCriteria parse(String theCriteria) { 101 String criteria = trim(theCriteria); 102 if (isBlank(criteria)) { 103 return null; 104 } 105 106 if (criteria.startsWith(Constants.SUBSCRIPTION_MULTITYPE_PREFIX)) { 107 if (criteria.endsWith(Constants.SUBSCRIPTION_MULTITYPE_SUFFIX)) { 108 String multitypeExpression = criteria.substring(1, criteria.length() - 1); 109 StringTokenizer tok = new StringTokenizer(multitypeExpression, ","); 110 tok.setTrimmerMatcher(new StringTrimmingTrimmerMatcher()); 111 List<String> types = tok.getTokenList(); 112 if (types.isEmpty()) { 113 return null; 114 } 115 if (types.contains(Constants.SUBSCRIPTION_MULTITYPE_STAR)) { 116 return new SubscriptionCriteria(TypeEnum.STARTYPE_EXPRESSION, null, null); 117 } 118 Set<String> typesSet = Sets.newHashSet(types); 119 return new SubscriptionCriteria(TypeEnum.MULTITYPE_EXPRESSION, null, typesSet); 120 } 121 } 122 123 if (Character.isLetter(criteria.charAt(0))) { 124 String criteriaType = criteria; 125 int questionMarkIdx = criteriaType.indexOf('?'); 126 if (questionMarkIdx > 0) { 127 criteriaType = criteriaType.substring(0, questionMarkIdx); 128 } 129 Set<String> types = Collections.singleton(criteriaType); 130 return new SubscriptionCriteria(TypeEnum.SEARCH_EXPRESSION, criteria, types); 131 } 132 133 return null; 134 } 135 136 137}