001package ca.uhn.fhir.rest.param; 002 003/* 004 * #%L 005 * HAPI FHIR - Core Library 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 */ 022import static org.apache.commons.lang3.StringUtils.isBlank; 023 024import java.util.List; 025 026import org.apache.commons.lang3.Validate; 027import org.apache.commons.lang3.builder.ToStringBuilder; 028import org.apache.commons.lang3.builder.ToStringStyle; 029 030import ca.uhn.fhir.context.ConfigurationException; 031import ca.uhn.fhir.context.FhirContext; 032import ca.uhn.fhir.model.api.IQueryParameterType; 033import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; 034 035public class CompositeParam<A extends IQueryParameterType, B extends IQueryParameterType> extends BaseParam implements IQueryParameterType { 036 037 private A myLeftType; 038 private B myRightType; 039 040 public CompositeParam(A theLeftInstance, B theRightInstance) { 041 myLeftType = theLeftInstance; 042 myRightType = theRightInstance; 043 } 044 045 public CompositeParam(Class<A> theLeftType, Class<B> theRightType) { 046 Validate.notNull(theLeftType); 047 Validate.notNull(theRightType); 048 try { 049 myLeftType = theLeftType.newInstance(); 050 } catch (InstantiationException e) { 051 throw new ConfigurationException("Failed to instantiate type: " + myLeftType, e); 052 } catch (IllegalAccessException e) { 053 throw new ConfigurationException("Failed to instantiate type: " + myLeftType, e); 054 } 055 try { 056 myRightType = theRightType.newInstance(); 057 } catch (InstantiationException e) { 058 throw new ConfigurationException("Failed to instantiate type: " + myRightType, e); 059 } catch (IllegalAccessException e) { 060 throw new ConfigurationException("Failed to instantiate type: " + myRightType, e); 061 } 062 } 063 064 @Override 065 String doGetQueryParameterQualifier() { 066 return null; 067 } 068 069 @Override 070 String doGetValueAsQueryToken(FhirContext theContext) { 071 StringBuilder b = new StringBuilder(); 072 if (myLeftType != null) { 073 b.append(myLeftType.getValueAsQueryToken(theContext)); 074 } 075 b.append('$'); 076 if (myRightType != null) { 077 b.append(myRightType.getValueAsQueryToken(theContext)); 078 } 079 return b.toString(); 080 } 081 082 @Override 083 void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) { 084 if (isBlank(theValue)) { 085 myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, ""); 086 myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, ""); 087 } else { 088 List<String> parts = ParameterUtil.splitParameterString(theValue, '$', false); 089 if (parts.size() > 2) { 090 throw new InvalidRequestException("Invalid value for composite parameter (only one '$' is valid for this parameter, others must be escaped). Value was: " + theValue); 091 } 092 myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(0)); 093 if (parts.size() > 1) { 094 myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(1)); 095 } 096 } 097 } 098 099 /** 100 * @return Returns the left value for this parameter (the first of two parameters in this composite) 101 */ 102 public A getLeftValue() { 103 return myLeftType; 104 } 105 106 /** 107 * @return Returns the right value for this parameter (the second of two parameters in this composite) 108 */ 109 public B getRightValue() { 110 return myRightType; 111 } 112 113 @Override 114 public String toString() { 115 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 116 b.append("myLeftType", getLeftValue()); 117 b.append("myRightType", getRightValue()); 118 return b.toString(); 119 } 120 121}