001/*- 002 * #%L 003 * HAPI FHIR JPA - Search Parameters 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.searchparam.matcher; 021 022import java.util.List; 023 024public class InMemoryMatchResult { 025 public static final String PARSE_FAIL = "Failed to translate parse query string"; 026 public static final String STANDARD_PARAMETER = "Standard parameters not supported"; 027 public static final String CHAIN = "Chained parameters are not supported"; 028 public static final String PARAM = "Parameter not supported"; 029 public static final String QUALIFIER = "Qualified parameter not supported"; 030 public static final String LOCATION_NEAR = "Location.position near not supported"; 031 032 private final boolean myMatch; 033 /** 034 * True if it is expected that a search will be performed in-memory 035 */ 036 private final boolean mySupported; 037 /** 038 * if mySupported is false, then the parameter responsible for in-memory search not being supported 039 */ 040 private final String myUnsupportedParameter; 041 /** 042 * if mySupported is false, then the reason in-memory search is not supported 043 */ 044 private final String myUnsupportedReason; 045 /** 046 * Only used by CompositeInMemoryDaoSubscriptionMatcher to track whether we had to go 047 * out to the database to resolve the match. 048 */ 049 private boolean myInMemory = false; 050 051 private InMemoryMatchResult(boolean theMatch) { 052 this.myMatch = theMatch; 053 this.mySupported = true; 054 this.myUnsupportedParameter = null; 055 this.myUnsupportedReason = null; 056 } 057 058 private InMemoryMatchResult(String theUnsupportedParameter, String theUnsupportedReason) { 059 myMatch = false; 060 mySupported = false; 061 myUnsupportedParameter = theUnsupportedParameter; 062 myUnsupportedReason = theUnsupportedReason; 063 } 064 065 public static InMemoryMatchResult successfulMatch() { 066 return new InMemoryMatchResult(true); 067 } 068 069 public static InMemoryMatchResult fromBoolean(boolean theMatched) { 070 return new InMemoryMatchResult(theMatched); 071 } 072 073 public static InMemoryMatchResult unsupportedFromReason(String theUnsupportedReason) { 074 return new InMemoryMatchResult(null, theUnsupportedReason); 075 } 076 077 public static InMemoryMatchResult unsupportedFromParameterAndReason( 078 String theUnsupportedParameter, String theUnsupportedReason) { 079 return new InMemoryMatchResult(theUnsupportedParameter, theUnsupportedReason); 080 } 081 082 public static InMemoryMatchResult noMatch() { 083 return new InMemoryMatchResult(false); 084 } 085 086 public boolean supported() { 087 return mySupported; 088 } 089 090 public boolean matched() { 091 return myMatch; 092 } 093 094 public String getUnsupportedReason() { 095 if (myUnsupportedParameter != null) { 096 return "Parameter: <" + myUnsupportedParameter + "> Reason: " + myUnsupportedReason; 097 } 098 return myUnsupportedReason; 099 } 100 101 public boolean isInMemory() { 102 return myInMemory; 103 } 104 105 public void setInMemory(boolean theInMemory) { 106 myInMemory = theInMemory; 107 } 108 109 public static InMemoryMatchResult and(InMemoryMatchResult theLeft, InMemoryMatchResult theRight) { 110 if (theLeft == null) { 111 return theRight; 112 } 113 if (theRight == null) { 114 return theLeft; 115 } 116 if (theLeft.supported() && theRight.supported()) { 117 return InMemoryMatchResult.fromBoolean(theLeft.matched() && theRight.matched()); 118 } 119 if (!theLeft.supported() && !theRight.supported()) { 120 return InMemoryMatchResult.unsupportedFromReason( 121 List.of(theLeft.getUnsupportedReason(), theRight.getUnsupportedReason()) 122 .toString()); 123 } 124 if (!theLeft.supported()) { 125 return theLeft; 126 } 127 return theRight; 128 } 129 130 public static InMemoryMatchResult or(InMemoryMatchResult theLeft, InMemoryMatchResult theRight) { 131 if (theLeft == null) { 132 return theRight; 133 } 134 if (theRight == null) { 135 return theLeft; 136 } 137 if (theLeft.matched() || theRight.matched()) { 138 return InMemoryMatchResult.successfulMatch(); 139 } 140 if (!theLeft.supported() && !theRight.supported()) { 141 return InMemoryMatchResult.unsupportedFromReason( 142 List.of(theLeft.getUnsupportedReason(), theRight.getUnsupportedReason()) 143 .toString()); 144 } 145 if (!theLeft.supported()) { 146 return theLeft; 147 } 148 return theRight; 149 } 150}