diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java index e8af1714e4d..22d13e211f8 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java @@ -25,7 +25,6 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.Operation; -import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.param.ParameterUtil; @@ -46,18 +45,17 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; public class OperationMethodBinding extends BaseResourceReturningMethodBinding { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(OperationMethodBinding.class); - private BundleTypeEnum myBundleType; - private String myDescription; private final boolean myIdempotent; private final Integer myIdParamIndex; private final String myName; - private final RestOperationTypeEnum myOtherOperatiopnType; - private List myReturnParams; + private final RestOperationTypeEnum myOtherOperationType; private final ReturnTypeEnum myReturnType; + private BundleTypeEnum myBundleType; + private String myDescription; protected OperationMethodBinding(Class theReturnResourceType, Class theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider, - boolean theIdempotent, String theOperationName, Class theOperationType, - OperationParam[] theReturnParams, BundleTypeEnum theBundleType) { + boolean theIdempotent, String theOperationName, Class theOperationType, + BundleTypeEnum theBundleType) { super(theReturnResourceType, theMethod, theContext, theProvider); myBundleType = theBundleType; @@ -77,7 +75,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { if (isBlank(theOperationName)) { throw new ConfigurationException("Method '" + theMethod.getName() + "' on type " + theMethod.getDeclaringClass().getName() + " is annotated with @" + Operation.class.getSimpleName() - + " but this annotation has no name defined"); + + " but this annotation has no name defined"); } if (theOperationName.startsWith("$") == false) { theOperationName = "$" + theOperationName; @@ -97,45 +95,28 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { myReturnType = ReturnTypeEnum.RESOURCE; if (getResourceName() == null) { - myOtherOperatiopnType = RestOperationTypeEnum.EXTENDED_OPERATION_SERVER; + myOtherOperationType = RestOperationTypeEnum.EXTENDED_OPERATION_SERVER; } else if (myIdParamIndex == null) { - myOtherOperatiopnType = RestOperationTypeEnum.EXTENDED_OPERATION_TYPE; + myOtherOperationType = RestOperationTypeEnum.EXTENDED_OPERATION_TYPE; } else { - myOtherOperatiopnType = RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE; - } - - myReturnParams = new ArrayList<>(); - if (theReturnParams != null) { - for (OperationParam next : theReturnParams) { - ReturnType type = new ReturnType(); - type.setName(next.name()); - type.setMin(next.min()); - type.setMax(next.max()); - if (type.getMax() == OperationParam.MAX_DEFAULT) { - type.setMax(1); - } - if (!next.type().equals(IBase.class)) { - if (next.type().isInterface() || Modifier.isAbstract(next.type().getModifiers())) { - throw new ConfigurationException("Invalid value for @OperationParam.type(): " + next.type().getName()); - } - type.setType(theContext.getElementDefinition(next.type()).getName()); - } - myReturnParams.add(type); - } + myOtherOperationType = RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE; } } public OperationMethodBinding(Class theReturnResourceType, Class theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider, - Operation theAnnotation) { - this(theReturnResourceType, theReturnTypeFromRp, theMethod, theContext, theProvider, theAnnotation.idempotent(), theAnnotation.name(), theAnnotation.type(), theAnnotation.returnParameters(), - theAnnotation.bundleType()); + Operation theAnnotation) { + this(theReturnResourceType, theReturnTypeFromRp, theMethod, theContext, theProvider, theAnnotation.idempotent(), theAnnotation.name(), theAnnotation.type(), theAnnotation.bundleType()); } public String getDescription() { return myDescription; } + public void setDescription(String theDescription) { + myDescription = theDescription; + } + /** * Returns the name of the operation, starting with "$" */ @@ -150,7 +131,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { @Override public RestOperationTypeEnum getRestOperationType() { - return myOtherOperatiopnType; + return myOtherOperationType; } @Override @@ -181,12 +162,8 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { return myIdempotent; } - public void setDescription(String theDescription) { - myDescription = theDescription; - } - public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theVersion, String theOperationName, IBaseParameters theInput, - boolean theUseHttpGet) { + boolean theUseHttpGet) { StringBuilder b = new StringBuilder(); if (theResourceName != null) { b.append(theResourceName); @@ -231,7 +208,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { } if (!(value instanceof IPrimitiveType)) { throw new IllegalArgumentException( - "Can not invoke operation as HTTP GET when it has parameters with a composite (non priitive) datatype as the value. Found value: " + value.getClass().getName()); + "Can not invoke operation as HTTP GET when it has parameters with a composite (non priitive) datatype as the value. Found value: " + value.getClass().getName()); } IPrimitiveType primitive = (IPrimitiveType) value; params.get(nextName).add(primitive.getValueAsString()); @@ -256,46 +233,4 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { } - public static class ReturnType { - private int myMax; - private int myMin; - private String myName; - /** - * http://hl7-fhir.github.io/valueset-operation-parameter-type.html - */ - private String myType; - - public int getMax() { - return myMax; - } - - public int getMin() { - return myMin; - } - - public String getName() { - return myName; - } - - public String getType() { - return myType; - } - - public void setMax(int theMax) { - myMax = theMax; - } - - public void setMin(int theMin) { - myMin = theMin; - } - - public void setName(String theName) { - myName = theName; - } - - public void setType(String theType) { - myType = theType; - } - } - } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java index 21a6a991392..151cfa087b4 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java @@ -40,7 +40,7 @@ public class ValidateMethodBindingDstu2Plus extends OperationMethodBinding { public ValidateMethodBindingDstu2Plus(Class theReturnResourceType, Class theReturnTypeFromRp, Method theMethod, FhirContext theContext, Object theProvider, Validate theAnnotation) { - super(null, theReturnTypeFromRp, theMethod, theContext, theProvider, true, Constants.EXTOP_VALIDATE, theAnnotation.type(), new OperationParam[0], BundleTypeEnum.COLLECTION); + super(null, theReturnTypeFromRp, theMethod, theContext, theProvider, true, Constants.EXTOP_VALIDATE, theAnnotation.type(), BundleTypeEnum.COLLECTION); List newParams = new ArrayList(); int idx = 0; diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamFinder.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamFinder.java new file mode 100644 index 00000000000..88fb281deff --- /dev/null +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamFinder.java @@ -0,0 +1,98 @@ +package ca.uhn.fhir.jpa.searchparam.extractor; + +import ca.uhn.fhir.context.*; +import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SearchParamFinder { + private static final Logger ourLog = LoggerFactory.getLogger(SearchParamFinder.class); + + public static void main(String[] args) { + + FhirContext ctx = FhirContext.forR5(); + RestSearchParameterTypeEnum wantType = RestSearchParameterTypeEnum.NUMBER; + + for (String nextResourceName : ctx.getResourceNames()) { + RuntimeResourceDefinition nextResDef = ctx.getResourceDefinition(nextResourceName); + for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { + + if (nextSp.getParamType() == wantType) { + + boolean logged = false; + for (String nextPath : nextSp.getPathsSplit()) { + + List pathsPart = new ArrayList<>(Arrays.asList(nextPath.split("\\."))); + + BaseRuntimeElementCompositeDefinition def = null; + + traverse(ctx, pathsPart, def); +// for (int i = 0; i < pathsPart.length; i++) { +// String nextPart = pathsPart[i]; +// +// if (i == 0) { +// def = ctx.getResourceDefinition(nextPart); +// } else { +// BaseRuntimeChildDefinition child = def.getChildByName(nextPart); +// if (child == null) { +// child = def.getChildByName(nextPart + "[x]"); +// } +// BaseRuntimeElementDefinition childDef = child.getChildByName(nextPart); +// if (childDef instanceof RuntimePrimitiveDatatypeDefinition) { +// ourLog.info("SearchParam {} : {} : {} has {}", nextResourceName, nextSp.getName(), nextSp.getPath(), childDef.getName()); +// logged = true; +// break; +// } +// def = (BaseRuntimeElementCompositeDefinition) childDef; +// } +// +// } + } + + if (!logged) { + ourLog.info("SearchParam {} : {} : {}", nextResourceName, nextSp.getName(), nextSp.getPath()); + } + + } + + + } + } + + } + + private static void traverse(FhirContext theContext, List thePathsPart, BaseRuntimeElementCompositeDefinition theDef) { + if (thePathsPart.size() == 0) { + ourLog.info("{} - {}", thePathsPart, theDef.getName()); + return; + } + + String nextName = thePathsPart.get(0); + if (theDef == null) { + RuntimeResourceDefinition def = theContext.getResourceDefinition(nextName); + traverse(theContext, thePathsPart.subList(1, thePathsPart.size()), def); + } else { + BaseRuntimeChildDefinition child = theDef.getChildByName(nextName); + if (child != null) { + BaseRuntimeElementCompositeDefinition def = (BaseRuntimeElementCompositeDefinition) child.getChildByName(nextName); + traverse(theContext, thePathsPart.subList(1, thePathsPart.size()), def); + } + + RuntimeChildChoiceDefinition choiceChild = (RuntimeChildChoiceDefinition) theDef.getChildByName(nextName + "[x]"); + if (choiceChild != null){ + for (String nextChildName : choiceChild.getValidChildNames()) { + if (nextChildName.startsWith(nextName)) { + BaseRuntimeElementCompositeDefinition def = (BaseRuntimeElementCompositeDefinition) choiceChild.getChildByName(nextChildName); + traverse(theContext, thePathsPart.subList(1, thePathsPart.size()), def); + } + } + } + } + } + + +} diff --git a/hapi-fhir-jpaserver-searchparam/src/test/resources/logback-test.xml b/hapi-fhir-jpaserver-searchparam/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..dc857b12814 --- /dev/null +++ b/hapi-fhir-jpaserver-searchparam/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] - %msg%n + + + + + + + + +