001/* 002 * #%L 003 * HAPI FHIR - Core Library 004 * %% 005 * Copyright (C) 2014 - 2023 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.rest.gclient; 021 022import ca.uhn.fhir.context.FhirContext; 023import org.apache.commons.lang3.Validate; 024import org.hl7.fhir.instance.model.api.IIdType; 025 026import java.util.Arrays; 027import java.util.Collection; 028 029import static org.apache.commons.lang3.StringUtils.isNotBlank; 030 031 032public class ReferenceClientParam extends BaseClientParam implements IParam { 033 034 private String myName; 035 036 public ReferenceClientParam(String theName) { 037 myName = theName; 038 } 039 040 @Override 041 public String getParamName() { 042 return myName; 043 } 044 045 /** 046 * Include a chained search. For example: 047 * <pre> 048 * Bundle resp = ourClient 049 * .search() 050 * .forResource(QuestionnaireResponse.class) 051 * .where(QuestionnaireResponse.SUBJECT.hasChainedProperty(Patient.FAMILY.matches().value("SMITH"))) 052 * .returnBundle(Bundle.class) 053 * .execute(); 054 * </pre> 055 */ 056 public ICriterion<ReferenceClientParam> hasChainedProperty(ICriterion<?> theCriterion) { 057 return new ReferenceChainCriterion(getParamName(), theCriterion); 058 } 059 060 /** 061 * Include a chained search with a resource type. For example: 062 * <pre> 063 * Bundle resp = ourClient 064 * .search() 065 * .forResource(QuestionnaireResponse.class) 066 * .where(QuestionnaireResponse.SUBJECT.hasChainedProperty("Patient", Patient.FAMILY.matches().value("SMITH"))) 067 * .returnBundle(Bundle.class) 068 * .execute(); 069 * </pre> 070 */ 071 public ICriterion<ReferenceClientParam> hasChainedProperty(String theResourceType, ICriterion<?> theCriterion) { 072 return new ReferenceChainCriterion(getParamName(), theResourceType, theCriterion); 073 } 074 075 /** 076 * Match the referenced resource if the resource has the given ID (this can be 077 * the logical ID or the absolute URL of the resource) 078 */ 079 public ICriterion<ReferenceClientParam> hasId(IIdType theId) { 080 return new StringCriterion<>(getParamName(), theId.getValue()); 081 } 082 083 /** 084 * Match the referenced resource if the resource has the given ID (this can be 085 * the logical ID or the absolute URL of the resource) 086 */ 087 public ICriterion<ReferenceClientParam> hasId(String theId) { 088 return new StringCriterion<>(getParamName(), theId); 089 } 090 091 /** 092 * Match the referenced resource if the resource has ANY of the given IDs 093 * (this is an OR search, not an AND search), (this can be the logical ID or 094 * the absolute URL of the resource). Note that to specify an AND search, 095 * simply add a subsequent {@link IQuery#where(ICriterion) where} criteria 096 * with the same parameter. 097 */ 098 public ICriterion<ReferenceClientParam> hasAnyOfIds(Collection<String> theIds) { 099 return new StringCriterion<>(getParamName(), theIds); 100 } 101 102 /** 103 * Match the referenced resource if the resource has ANY of the given IDs 104 * (this is an OR search, not an AND search), (this can be the logical ID or 105 * the absolute URL of the resource). Note that to specify an AND search, 106 * simply add a subsequent {@link IQuery#where(ICriterion) where} criteria 107 * with the same parameter. 108 */ 109 public ICriterion<ReferenceClientParam> hasAnyOfIds(String... theIds) { 110 Validate.notNull(theIds, "theIds must not be null"); 111 return hasAnyOfIds(Arrays.asList(theIds)); 112 } 113 114 private static class ReferenceChainCriterion implements ICriterion<ReferenceClientParam>, ICriterionInternal { 115 116 private final String myResourceTypeQualifier; 117 private String myParamName; 118 private ICriterionInternal myWrappedCriterion; 119 120 ReferenceChainCriterion(String theParamName, ICriterion<?> theWrappedCriterion) { 121 this(theParamName, null, theWrappedCriterion); 122 } 123 124 ReferenceChainCriterion(String theParamName, String theResourceType, ICriterion<?> theWrappedCriterion) { 125 myParamName = theParamName; 126 myResourceTypeQualifier = isNotBlank(theResourceType) ? ":" + theResourceType : ""; 127 myWrappedCriterion = (ICriterionInternal) theWrappedCriterion; 128 } 129 130 @Override 131 public String getParameterName() { 132 return myParamName + myResourceTypeQualifier + "." + myWrappedCriterion.getParameterName(); 133 } 134 135 @Override 136 public String getParameterValue(FhirContext theContext) { 137 return myWrappedCriterion.getParameterValue(theContext); 138 } 139 140 } 141 142}