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