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