Skip to content

Commit

Permalink
Issue #1323 - Add support for ':of-type' modifier
Browse files Browse the repository at this point in the history
Signed-off-by: Troy Biesterfeld <tbieste@us.ibm.com>
  • Loading branch information
tbieste committed Mar 19, 2021
1 parent d86e9d2 commit fdfd561
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public class JDBCConstants {
supportedModifiersMap.put(Type.STRING, Arrays.asList(Modifier.EXACT, Modifier.CONTAINS, Modifier.MISSING));
supportedModifiersMap.put(Type.REFERENCE, Arrays.asList(Modifier.TYPE, Modifier.MISSING, Modifier.IDENTIFIER));
supportedModifiersMap.put(Type.URI, Arrays.asList(Modifier.BELOW, Modifier.ABOVE, Modifier.MISSING));
supportedModifiersMap.put(Type.TOKEN, Arrays.asList(Modifier.MISSING, Modifier.NOT));
supportedModifiersMap.put(Type.TOKEN, Arrays.asList(Modifier.MISSING, Modifier.NOT, Modifier.OF_TYPE));
supportedModifiersMap.put(Type.NUMBER, Arrays.asList(Modifier.MISSING));
supportedModifiersMap.put(Type.DATE, Arrays.asList(Modifier.MISSING));
supportedModifiersMap.put(Type.QUANTITY, Arrays.asList(Modifier.MISSING));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ private SearchConstants() {

public static final String PARAMETER_DELIMITER = "|";

public static final String COMPOSITE_DELIMITER = "$";

public static final char COLON_DELIMITER = ':';

public static final String COLON_DELIMITER_STR = ":";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
public class QueryParameterValue {

private boolean hidden = false;
private boolean ofTypeModifier = false;

private Prefix prefix = null;

Expand Down Expand Up @@ -150,6 +151,22 @@ public void setHidden(boolean hidden) {
this.hidden = hidden;
}

/**
* Sets whether the value of an :of-type modifier.
* @return true or false
*/
public boolean isOfTypeModifier() {
return ofTypeModifier;
}

/**
* Gets whether the value of an :of-type modifier.
* @param ofTypeModifier true if value of an :of-type modifier
*/
public void setOfTypeModifier(boolean ofTypeModifier) {
this.ofTypeModifier = ofTypeModifier;
}

/**
* Serialize the ParameterValue to a query parameter string
*/
Expand Down Expand Up @@ -178,6 +195,7 @@ public String toString() {
delim = outputBuilder(returnString, delim, valueString);
delim = outputBuilder(returnString, delim, valueDate);

// token search with :of-type modifier is handled as a composite search
if (component != null && !component.isEmpty()) {
String componentDelim = "";
for (QueryParameter componentParam : component) {
Expand All @@ -190,7 +208,7 @@ public String toString() {
throw new IllegalStateException("Components of a composite search parameter may only have a single value");
}
returnString.append(componentDelim).append(componentValues.get(0));
componentDelim = "$";
componentDelim = ofTypeModifier ? SearchConstants.PARAMETER_DELIMITER : SearchConstants.COMPOSITE_DELIMITER;
}
}
return returnString.toString();
Expand Down
44 changes: 38 additions & 6 deletions fhir-search/src/main/java/com/ibm/fhir/search/util/SearchUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -882,9 +882,15 @@ public static FHIRSearchContext parseQueryParameters(Class<?> resourceType,
// Build list of processed query parameters
List<QueryParameter> curParameterList = new ArrayList<>();
for (String paramValueString : params) {
QueryParameter parameter = new QueryParameter(type, parameterCode, modifier, modifierResourceTypeName);
List<QueryParameterValue> queryParameterValues =
processQueryParameterValueString(resourceType, searchParameter, modifier, parameter.getModifierResourceTypeName(), paramValueString);
processQueryParameterValueString(resourceType, searchParameter, modifier, modifierResourceTypeName, paramValueString);
QueryParameter parameter;
// Internally treat search with :of-type modifier as composite search
if (Modifier.OF_TYPE.equals(modifier)) {
parameter = new QueryParameter(Type.COMPOSITE, parameterCode + SearchConstants.OF_TYPE_MODIFIER_SUFFIX, null, null);
} else {
parameter = new QueryParameter(type, parameterCode, modifier, modifierResourceTypeName);
}
parameter.getValues().addAll(queryParameterValues);
curParameterList.add(parameter);
parameters.add(parameter);
Expand Down Expand Up @@ -1238,12 +1244,10 @@ private static List<QueryParameterValue> parseQueryParameterValuesString(SearchP
if (parts.length == 2) {
parameterValue.setValueSystem(unescapeSearchParm(parts[0]));
parameterValue.setValueCode(unescapeSearchParm(parts[1]));
}
else {
} else {
parameterValue.setValueCode(unescapeSearchParm(v));
}
}
else {
} else {
String valueString = unescapeSearchParm(v);
valueString = extractReferenceValue(valueString);
parameterValue.setValueString(valueString);
Expand Down Expand Up @@ -1281,13 +1285,41 @@ private static List<QueryParameterValue> parseQueryParameterValuesString(SearchP
case TOKEN: {
// token
// [parameter]=[system]|[code]
// [parameter]:of-type=[system|code|value]
/*
* TODO: start enforcing this:
* "For token parameters on elements of type ContactPoint, uri, or boolean,
* the presence of the pipe symbol SHALL NOT be used - only the
* [parameter]=[code] form is allowed
*/
String[] parts = v.split(SearchConstants.BACKSLASH_NEGATIVE_LOOKBEHIND + "\\|");
if (Modifier.OF_TYPE.equals(modifier)) {
// Convert :of-type into a composite search parameter
final String ofTypeParmName = searchParameter.getCode().getValue() + SearchConstants.OF_TYPE_MODIFIER_SUFFIX;
parameterValue.setOfTypeModifier(true);
if (parts.length > 1 && parts.length < 4) {
QueryParameterValue typeParameterValue = new QueryParameterValue();
if (parts.length == 3) {
typeParameterValue.setValueSystem(unescapeSearchParm(parts[0]));
}
typeParameterValue.setValueCode(unescapeSearchParm(parts[parts.length - 2]));
QueryParameter typeParameter = new QueryParameter(Type.TOKEN, SearchUtil.makeCompositeSubCode(ofTypeParmName, SearchConstants.OF_TYPE_MODIFIER_COMPONENT_TYPE),
null, null, Collections.singletonList(typeParameterValue));
parameterValue.addComponent(typeParameter);

QueryParameterValue valueParameterValue = new QueryParameterValue();
valueParameterValue.setValueCode(unescapeSearchParm(parts[parts.length - 1]));
QueryParameter valueParameter = new QueryParameter(Type.TOKEN, SearchUtil.makeCompositeSubCode(ofTypeParmName, SearchConstants.OF_TYPE_MODIFIER_COMPONENT_VALUE),
null, null, Collections.singletonList(valueParameterValue));
parameterValue.addComponent(valueParameter);
} else {
QueryParameterValue valueParameterValue = new QueryParameterValue();
valueParameterValue.setValueCode(unescapeSearchParm(v));
QueryParameter valueParameter = new QueryParameter(Type.TOKEN, SearchUtil.makeCompositeSubCode(ofTypeParmName, SearchConstants.OF_TYPE_MODIFIER_COMPONENT_VALUE),
null, null, Collections.singletonList(valueParameterValue));
parameterValue.addComponent(valueParameter);
}
} else
if (parts.length == 2) {
parameterValue.setValueSystem(unescapeSearchParm(parts[0]));
parameterValue.setValueCode(unescapeSearchParm(parts[1]));
Expand Down

0 comments on commit fdfd561

Please sign in to comment.