001package ca.uhn.fhir.context; 002 003import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; 004import org.apache.commons.lang3.builder.EqualsBuilder; 005import org.apache.commons.lang3.builder.HashCodeBuilder; 006import org.apache.commons.lang3.builder.ToStringBuilder; 007import org.apache.commons.lang3.builder.ToStringStyle; 008import org.hl7.fhir.instance.model.api.IBaseDatatype; 009import org.hl7.fhir.instance.model.api.IBaseExtension; 010import org.hl7.fhir.instance.model.api.IIdType; 011 012import javax.annotation.Nonnull; 013import java.util.ArrayList; 014import java.util.Collection; 015import java.util.Collections; 016import java.util.HashMap; 017import java.util.HashSet; 018import java.util.List; 019import java.util.Map; 020import java.util.Set; 021import java.util.StringTokenizer; 022 023import static org.apache.commons.lang3.StringUtils.isNotBlank; 024import static org.apache.commons.lang3.StringUtils.trim; 025 026/* 027 * #%L 028 * HAPI FHIR - Core Library 029 * %% 030 * Copyright (C) 2014 - 2020 University Health Network 031 * %% 032 * Licensed under the Apache License, Version 2.0 (the "License"); 033 * you may not use this file except in compliance with the License. 034 * You may obtain a copy of the License at 035 * 036 * http://www.apache.org/licenses/LICENSE-2.0 037 * 038 * Unless required by applicable law or agreed to in writing, software 039 * distributed under the License is distributed on an "AS IS" BASIS, 040 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 041 * See the License for the specific language governing permissions and 042 * limitations under the License. 043 * #L% 044 */ 045 046public class RuntimeSearchParam { 047 private final IIdType myId; 048 private final Set<String> myBase; 049 private final List<RuntimeSearchParam> myCompositeOf; 050 private final String myDescription; 051 private final String myName; 052 private final RestSearchParameterTypeEnum myParamType; 053 private final String myPath; 054 private final Set<String> myTargets; 055 private final Set<String> myProvidesMembershipInCompartments; 056 private final RuntimeSearchParamStatusEnum myStatus; 057 private final String myUri; 058 private final Map<String, List<IBaseExtension<?, ?>>> myExtensions = new HashMap<>(); 059 060 /** 061 * Constructor 062 */ 063 public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf, 064 Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus) { 065 this(theId, theUri, theName, theDescription, thePath, theParamType, theCompositeOf, theProvidesMembershipInCompartments, theTargets, theStatus, null); 066 } 067 068 /** 069 * Constructor 070 */ 071 public RuntimeSearchParam(IIdType theId, String theUri, String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf, 072 Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus, Collection<String> theBase) { 073 super(); 074 075 myId = theId; 076 myUri = theUri; 077 myName = theName; 078 myDescription = theDescription; 079 myPath = thePath; 080 myParamType = theParamType; 081 myCompositeOf = theCompositeOf; 082 myStatus = theStatus; 083 if (theProvidesMembershipInCompartments != null && !theProvidesMembershipInCompartments.isEmpty()) { 084 myProvidesMembershipInCompartments = Collections.unmodifiableSet(theProvidesMembershipInCompartments); 085 } else { 086 myProvidesMembershipInCompartments = null; 087 } 088 if (theTargets != null && theTargets.isEmpty() == false) { 089 myTargets = Collections.unmodifiableSet(theTargets); 090 } else { 091 myTargets = Collections.emptySet(); 092 } 093 094 if (theBase == null || theBase.isEmpty()) { 095 HashSet<String> base = new HashSet<>(); 096 if (isNotBlank(thePath)) { 097 int indexOf = thePath.indexOf('.'); 098 if (indexOf != -1) { 099 base.add(trim(thePath.substring(0, indexOf))); 100 } 101 } 102 myBase = Collections.unmodifiableSet(base); 103 } else { 104 myBase = Collections.unmodifiableSet(new HashSet<>(theBase)); 105 } 106 } 107 108 public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments, Set<String> theTargets, RuntimeSearchParamStatusEnum theStatus) { 109 this(null, null, theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments, theTargets, theStatus); 110 } 111 112 /** 113 * Retrieve user data - This can be used to store any application-specific data 114 * 115 * @return 116 */ 117 public List<IBaseExtension<?, ?>> getExtensions(String theKey) { 118 List<IBaseExtension<?, ?>> retVal = myExtensions.get(theKey); 119 if (retVal != null) { 120 retVal = Collections.unmodifiableList(retVal); 121 } 122 return retVal; 123 } 124 125 /** 126 * Sets user data - This can be used to store any application-specific data 127 */ 128 public RuntimeSearchParam addExtension(String theKey, IBaseExtension theValue) { 129 List<IBaseExtension<?, ?>> valuesList = myExtensions.computeIfAbsent(theKey, k -> new ArrayList<>()); 130 valuesList.add(theValue); 131 return this; 132 } 133 134 @Override 135 public String toString() { 136 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 137 .append("base", myBase) 138 .append("name", myName) 139 .append("path", myPath) 140 .append("id", myId) 141 .append("uri", myUri) 142 .toString(); 143 } 144 145 public IIdType getId() { 146 return myId; 147 } 148 149 public String getUri() { 150 return myUri; 151 } 152 153 @Override 154 public boolean equals(Object theO) { 155 if (this == theO) return true; 156 157 if (theO == null || getClass() != theO.getClass()) return false; 158 159 RuntimeSearchParam that = (RuntimeSearchParam) theO; 160 161 return new EqualsBuilder() 162 .append(getId(), that.getId()) 163 .append(getName(), that.getName()) 164 .append(getPath(), that.getPath()) 165 .append(getUri(), that.getUri()) 166 .isEquals(); 167 } 168 169 @Override 170 public int hashCode() { 171 return new HashCodeBuilder(17, 37) 172 .append(getId()) 173 .append(getName()) 174 .append(getPath()) 175 .append(getUri()) 176 .toHashCode(); 177 } 178 179 public Set<String> getBase() { 180 return myBase; 181 } 182 183 @Nonnull 184 public Set<String> getTargets() { 185 return myTargets; 186 } 187 188 public boolean hasTargets() { 189 return !myTargets.isEmpty(); 190 } 191 192 public RuntimeSearchParamStatusEnum getStatus() { 193 return myStatus; 194 } 195 196 public List<RuntimeSearchParam> getCompositeOf() { 197 return myCompositeOf; 198 } 199 200 public String getDescription() { 201 return myDescription; 202 } 203 204 public String getName() { 205 return myName; 206 } 207 208 public RestSearchParameterTypeEnum getParamType() { 209 return myParamType; 210 } 211 212 public String getPath() { 213 return myPath; 214 } 215 216 public List<String> getPathsSplit() { 217 String path = getPath(); 218 if (path.indexOf('|') == -1) { 219 return Collections.singletonList(path); 220 } 221 222 List<String> retVal = new ArrayList<>(); 223 StringTokenizer tok = new StringTokenizer(path, "|"); 224 while (tok.hasMoreElements()) { 225 String nextPath = tok.nextToken().trim(); 226 retVal.add(nextPath.trim()); 227 } 228 return retVal; 229 } 230 231 /** 232 * Can return null 233 */ 234 public Set<String> getProvidesMembershipInCompartments() { 235 return myProvidesMembershipInCompartments; 236 } 237 238 239 public enum RuntimeSearchParamStatusEnum { 240 ACTIVE, 241 DRAFT, 242 RETIRED, 243 UNKNOWN 244 } 245 246}