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