Conformance generation

This commit is contained in:
jamesagnew 2014-03-19 08:56:37 -04:00
parent 7b7a663748
commit eb1df7b36a
6 changed files with 106 additions and 17 deletions

View File

@ -10,6 +10,8 @@
and maybe a way to configure this in the FhirContext so that the parser
can take advantage?
* Return link-self in returned bundles from server
* Add SimpleSetters for all primitive datatypes
* Implement and add Simple Getters in a similar way to simple setters

View File

@ -1,18 +1,24 @@
package ca.uhn.fhir.rest.server.provider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.UndeclaredExtension;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Conformance.Rest;
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResourceSearchParam;
import ca.uhn.fhir.model.dstu.valueset.RestfulConformanceModeEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.ReadMethodBinding;
@ -21,6 +27,8 @@ import ca.uhn.fhir.rest.param.IParameter;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.ResourceBinding;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.util.DatatypeUtil;
import ca.uhn.fhir.util.ExtensionConstants;
import ca.uhn.fhir.util.VersionUtil;
public class ServerConformanceProvider implements IResourceProvider {
@ -37,26 +45,27 @@ public class ServerConformanceProvider implements IResourceProvider {
if (myConformance != null) {
return myConformance;
}
Conformance retVal = new Conformance();
retVal.getSoftware().setName("HAPI FHIR Server");
retVal.getSoftware().setVersion(VersionUtil.getVersion());
Rest rest = retVal.addRest();
rest.setMode(RestfulConformanceModeEnum.SERVER);
Set<RestfulOperationSystemEnum> systemOps = new HashSet<RestfulOperationSystemEnum>();
for (ResourceBinding next : myRestfulServer.getResourceBindings()) {
Set<RestfulOperationTypeEnum> resourceOps = new HashSet<RestfulOperationTypeEnum>();
Set<RestfulOperationTypeEnum> resourceOps = new HashSet<RestfulOperationTypeEnum>();
RestResource resource = rest.addResource();
Class<? extends IResource> resourceType = next.getResourceProvider().getResourceType();
RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceType);
resource.getType().setValue(def.getName());
resource.getProfile().setId(new IdDt(def.getResourceProfile()));
Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String, Conformance.RestResourceSearchParam>();
for (BaseMethodBinding nextMethodBinding : next.getMethodBindings()) {
RestfulOperationTypeEnum resOp = nextMethodBinding.getResourceOperationType();
if (resOp != null) {
@ -73,26 +82,47 @@ public class ServerConformanceProvider implements IResourceProvider {
rest.addOperation().setCode(sysOp);
}
}
if (nextMethodBinding instanceof SearchMethodBinding) {
List<IParameter> params = ((SearchMethodBinding) nextMethodBinding).getParameters();
// TODO: this would probably work best if we sorted these by required first, then optional
RestResourceSearchParam searchParam = null;
StringDt searchParamChain = null;
for (IParameter nextParameter : params) {
if (nextParameter.getName().startsWith("_")) {
continue;
}
resource.addSearchParam().setName(nextParameter.getName());
if (searchParam == null) {
if (!nameToSearchParam.containsKey(nextParameter.getName())) {
RestResourceSearchParam param = resource.addSearchParam();
param.setName(nextParameter.getName());
searchParam = param;
} else {
searchParam = nameToSearchParam.get(nextParameter.getName());
}
} else if (searchParamChain == null) {
searchParam.addChain(nextParameter.getName());
searchParamChain = searchParam.getChain().get(searchParam.getChain().size()-1);
} else {
UndeclaredExtension ext = new UndeclaredExtension();
ext.setUrl(ExtensionConstants.CONF_ALSO_CHAIN);
ext.setValue(new StringDt(nextParameter.getName()));
searchParamChain.getUndeclaredExtensions().add(ext);
}
}
}
}
}
myConformance = retVal;
return retVal;
}
@Override
public Class<? extends IResource> getResourceType() {
return Conformance.class;

View File

@ -0,0 +1,26 @@
package ca.uhn.fhir.util;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import ca.uhn.fhir.model.primitive.StringDt;
public class DatatypeUtil {
/**
* Convert a list of FHIR String objects to a set of native java Strings
*/
public static Set<String> toStringSet(List<StringDt> theStringList) {
HashSet<String> retVal = new HashSet<String>();
if (theStringList != null) {
for (StringDt string : theStringList) {
if (string != null && string.getValue()!=null) {
retVal.add(string.getValue());
}
}
}
return retVal;
}
}

View File

@ -0,0 +1,7 @@
package ca.uhn.fhir.util;
public class ExtensionConstants {
public static final String CONF_ALSO_CHAIN = "http://hl7api.sourceforge.net/hapi-fhir/extensions.xml#alsoChain";
}

View File

@ -107,6 +107,22 @@ public class DummyPatientResourceProvider implements IResourceProvider {
return retVal;
}
/**
* @param theName3
*/
@Search()
public List<Patient> getPatientWithOptionalName(@Required(name = "aaa") StringDt theName1, @Optional(name = "bbb") StringDt theName2, @Optional(name = "ccc") StringDt theName3) {
List<Patient> retVal = new ArrayList<Patient>();
Patient next = getIdToPatient().get("1");
next.getName().get(0).getFamily().set(0, theName1);
if (theName2 != null) {
next.getName().get(0).getGiven().set(0, theName2);
}
retVal.add(next);
return retVal;
}
@Search()
public List<Patient> getPatientMultipleIdentifiers(@Required(name = "ids") CodingListParam theIdentifiers) {
List<Patient> retVal = new ArrayList<Patient>();

View File

@ -26,6 +26,7 @@ import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
import ca.uhn.fhir.testutil.RandomServerPortProvider;
import ca.uhn.fhir.util.ExtensionConstants;
/**
* Created by dsotnikov on 2/25/2014.
@ -102,7 +103,6 @@ public class ResfulServerTest {
}
@Test
public void testGetMetadata() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata");
@ -115,8 +115,16 @@ public class ResfulServerTest {
IParser parser = ourCtx.newXmlParser().setPrettyPrint(true);
Conformance bundle = parser.parseResource(Conformance.class, responseContent);
ourLog.info("Response:\n{}", parser.encodeResourceToString(bundle));
IParser p = ourCtx.newJsonParser().setPrettyPrint(true);
String enc = p.encodeResourceToString(bundle);
ourLog.info("Response:\n{}", enc);
assertTrue(enc.contains(ExtensionConstants.CONF_ALSO_CHAIN));
p = ourCtx.newXmlParser().setPrettyPrint(true);
enc = p.encodeResourceToString(bundle);
ourLog.info("Response:\n{}", enc);
assertTrue(enc.contains(ExtensionConstants.CONF_ALSO_CHAIN));
}
@Test