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 */ 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.List; 033 034import static org.apache.commons.lang3.StringUtils.isBlank; 035 036public class CompositeParam<A extends IQueryParameterType, B extends IQueryParameterType> extends BaseParam implements IQueryParameterType { 037 038 private A myLeftType; 039 private B myRightType; 040 041 public CompositeParam(A theLeftInstance, B theRightInstance) { 042 myLeftType = theLeftInstance; 043 myRightType = theRightInstance; 044 } 045 046 public CompositeParam(Class<A> theLeftType, Class<B> theRightType) { 047 Validate.notNull(theLeftType); 048 Validate.notNull(theRightType); 049 try { 050 myLeftType = theLeftType.newInstance(); 051 } catch (InstantiationException e) { 052 throw new ConfigurationException(Msg.code(1943) + "Failed to instantiate type: " + myLeftType, e); 053 } catch (IllegalAccessException e) { 054 throw new ConfigurationException(Msg.code(1944) + "Failed to instantiate type: " + myLeftType, e); 055 } 056 try { 057 myRightType = theRightType.newInstance(); 058 } catch (InstantiationException e) { 059 throw new ConfigurationException(Msg.code(1945) + "Failed to instantiate type: " + myRightType, e); 060 } catch (IllegalAccessException e) { 061 throw new ConfigurationException(Msg.code(1946) + "Failed to instantiate type: " + myRightType, e); 062 } 063 } 064 065 @Override 066 String doGetQueryParameterQualifier() { 067 return null; 068 } 069 070 @Override 071 String doGetValueAsQueryToken(FhirContext theContext) { 072 StringBuilder b = new StringBuilder(); 073 if (myLeftType != null) { 074 b.append(myLeftType.getValueAsQueryToken(theContext)); 075 } 076 b.append('$'); 077 if (myRightType != null) { 078 b.append(myRightType.getValueAsQueryToken(theContext)); 079 } 080 return b.toString(); 081 } 082 083 @Override 084 void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) { 085 if (isBlank(theValue)) { 086 myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, ""); 087 myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, ""); 088 } else { 089 List<String> parts = ParameterUtil.splitParameterString(theValue, '$', false); 090 if (parts.size() > 2) { 091 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); 092 } 093 myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(0)); 094 if (parts.size() > 1) { 095 myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(1)); 096 } 097 } 098 } 099 100 /** 101 * @return Returns the left value for this parameter (the first of two parameters in this composite) 102 */ 103 public A getLeftValue() { 104 return myLeftType; 105 } 106 107 /** 108 * @return Returns the right value for this parameter (the second of two parameters in this composite) 109 */ 110 public B getRightValue() { 111 return myRightType; 112 } 113 114 @Override 115 public String toString() { 116 ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); 117 b.append("myLeftType", getLeftValue()); 118 b.append("myRightType", getRightValue()); 119 return b.toString(); 120 } 121 122}