001package ca.uhn.fhir.rest.gclient; 002 003import ca.uhn.fhir.context.FhirContext; 004import org.apache.commons.lang3.Validate; 005import org.hl7.fhir.instance.model.api.IIdType; 006 007import java.util.Arrays; 008import java.util.Collection; 009 010import static org.apache.commons.lang3.StringUtils.isNotBlank; 011 012/* 013 * #%L 014 * HAPI FHIR - Core Library 015 * %% 016 * Copyright (C) 2014 - 2021 Smile CDR, Inc. 017 * %% 018 * Licensed under the Apache License, Version 2.0 (the "License"); 019 * you may not use this file except in compliance with the License. 020 * You may obtain a copy of the License at 021 * 022 * http://www.apache.org/licenses/LICENSE-2.0 023 * 024 * Unless required by applicable law or agreed to in writing, software 025 * distributed under the License is distributed on an "AS IS" BASIS, 026 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 027 * See the License for the specific language governing permissions and 028 * limitations under the License. 029 * #L% 030 */ 031 032 033public class ReferenceClientParam extends BaseClientParam implements IParam { 034 035 private String myName; 036 037 public ReferenceClientParam(String theName) { 038 myName = theName; 039 } 040 041 @Override 042 public String getParamName() { 043 return myName; 044 } 045 046 /** 047 * Include a chained search. For example: 048 * <pre> 049 * Bundle resp = ourClient 050 * .search() 051 * .forResource(QuestionnaireResponse.class) 052 * .where(QuestionnaireResponse.SUBJECT.hasChainedProperty(Patient.FAMILY.matches().value("SMITH"))) 053 * .returnBundle(Bundle.class) 054 * .execute(); 055 * </pre> 056 */ 057 public ICriterion<ReferenceClientParam> hasChainedProperty(ICriterion<?> theCriterion) { 058 return new ReferenceChainCriterion(getParamName(), theCriterion); 059 } 060 061 /** 062 * Include a chained search with a resource type. For example: 063 * <pre> 064 * Bundle resp = ourClient 065 * .search() 066 * .forResource(QuestionnaireResponse.class) 067 * .where(QuestionnaireResponse.SUBJECT.hasChainedProperty("Patient", Patient.FAMILY.matches().value("SMITH"))) 068 * .returnBundle(Bundle.class) 069 * .execute(); 070 * </pre> 071 */ 072 public ICriterion<ReferenceClientParam> hasChainedProperty(String theResourceType, ICriterion<?> theCriterion) { 073 return new ReferenceChainCriterion(getParamName(), theResourceType, theCriterion); 074 } 075 076 /** 077 * Match the referenced resource if the resource has the given ID (this can be 078 * the logical ID or the absolute URL of the resource) 079 */ 080 public ICriterion<ReferenceClientParam> hasId(IIdType theId) { 081 return new StringCriterion<>(getParamName(), theId.getValue()); 082 } 083 084 /** 085 * Match the referenced resource if the resource has the given ID (this can be 086 * the logical ID or the absolute URL of the resource) 087 */ 088 public ICriterion<ReferenceClientParam> hasId(String theId) { 089 return new StringCriterion<>(getParamName(), theId); 090 } 091 092 /** 093 * Match the referenced resource if the resource has ANY of the given IDs 094 * (this is an OR search, not an AND search), (this can be the logical ID or 095 * the absolute URL of the resource). Note that to specify an AND search, 096 * simply add a subsequent {@link IQuery#where(ICriterion) where} criteria 097 * with the same parameter. 098 */ 099 public ICriterion<ReferenceClientParam> hasAnyOfIds(Collection<String> theIds) { 100 return new StringCriterion<>(getParamName(), theIds); 101 } 102 103 /** 104 * Match the referenced resource if the resource has ANY of the given IDs 105 * (this is an OR search, not an AND search), (this can be the logical ID or 106 * the absolute URL of the resource). Note that to specify an AND search, 107 * simply add a subsequent {@link IQuery#where(ICriterion) where} criteria 108 * with the same parameter. 109 */ 110 public ICriterion<ReferenceClientParam> hasAnyOfIds(String... theIds) { 111 Validate.notNull(theIds, "theIds must not be null"); 112 return hasAnyOfIds(Arrays.asList(theIds)); 113 } 114 115 private static class ReferenceChainCriterion implements ICriterion<ReferenceClientParam>, ICriterionInternal { 116 117 private final String myResourceTypeQualifier; 118 private String myParamName; 119 private ICriterionInternal myWrappedCriterion; 120 121 ReferenceChainCriterion(String theParamName, ICriterion<?> theWrappedCriterion) { 122 this(theParamName, null, theWrappedCriterion); 123 } 124 125 ReferenceChainCriterion(String theParamName, String theResourceType, ICriterion<?> theWrappedCriterion) { 126 myParamName = theParamName; 127 myResourceTypeQualifier = isNotBlank(theResourceType) ? ":" + theResourceType : ""; 128 myWrappedCriterion = (ICriterionInternal) theWrappedCriterion; 129 } 130 131 @Override 132 public String getParameterName() { 133 return myParamName + myResourceTypeQualifier + "." + myWrappedCriterion.getParameterName(); 134 } 135 136 @Override 137 public String getParameterValue(FhirContext theContext) { 138 return myWrappedCriterion.getParameterValue(theContext); 139 } 140 141 } 142 143}