@Test public void testExtendedClass() { FhirContext ctx = new FhirContext(); ctx.getResourceDefinition(MyPatient.class); RuntimeResourceDefinition patient = ctx.getResourceDefinition("Patient"); assertEquals(Patient.class, patient.getImplementingClass()); RuntimeResourceDefinition def = ctx.getResourceDefinition(MyPatient.class); RuntimeResourceDefinition baseDef = def.getBaseDefinition(); assertEquals(Patient.class, baseDef.getImplementingClass()); }
public static BaseHttpClientInvocation createValidateInvocation( FhirContext theContext, IBaseResource theResource) { IBaseParameters parameters = (IBaseParameters) theContext.getResourceDefinition("Parameters").newInstance(); ParametersUtil.addParameterToParameters(theContext, parameters, theResource, "resource"); String resourceName = theContext.getResourceDefinition(theResource).getName(); String resourceId = theResource.getIdElement().getIdPart(); BaseHttpClientInvocation retVal = createOperationInvocation( theContext, resourceName, resourceId, Constants.EXTOP_VALIDATE, parameters, false); return retVal; }
@Test public void testQueryBoundCodeableConcept() { RuntimeResourceDefinition patientType = ourCtx.getResourceDefinition(Patient.class); String childName = "maritalStatus"; BaseRuntimeChildDatatypeDefinition genderChild = (BaseRuntimeChildDatatypeDefinition) patientType.getChildByName(childName); ourLog.trace(genderChild.getClass().getName()); assertEquals(MaritalStatusCodesEnum.class, genderChild.getBoundEnumType()); }
@Test public void testQueryBoundCode() { RuntimeResourceDefinition patientType = ourCtx.getResourceDefinition(Patient.class); String childName = "gender"; BaseRuntimeChildDatatypeDefinition genderChild = (BaseRuntimeChildDatatypeDefinition) patientType.getChildByName(childName); ourLog.trace(genderChild.getClass().getName()); assertEquals(AdministrativeGenderEnum.class, genderChild.getBoundEnumType()); }
@Override public MethodOutcome delete(final Class<? extends IResource> theType, IdDt theId) { HttpDeleteClientInvocation invocation = DeleteMethodBinding.createDeleteInvocation(theId.withResourceType(toResourceName(theType))); if (isKeepResponses()) { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding()); } final String resourceName = myContext.getResourceDefinition(theType).getName(); OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; }
@Override public MethodOutcome validate(IResource theResource) { BaseHttpClientInvocation invocation = ValidateMethodBinding.createValidateInvocation(theResource, null, myContext); if (isKeepResponses()) { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding()); } RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); final String resourceName = def.getName(); OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; }
/** * Create an OperationOutcome resource which contains all of the messages found as a result of * this validation */ public IBaseOperationOutcome toOperationOutcome() { IBaseOperationOutcome oo = (IBaseOperationOutcome) myCtx.getResourceDefinition("OperationOutcome").newInstance(); for (SingleValidationMessage next : myMessages) { String location; if (isNotBlank(next.getLocationString())) { location = next.getLocationString(); } else if (next.getLocationLine() != null || next.getLocationCol() != null) { location = "Line[" + next.getLocationLine() + "] Col[" + next.getLocationCol() + "]"; } else { location = null; } String severity = next.getSeverity() != null ? next.getSeverity().getCode() : null; OperationOutcomeUtil.addIssue( myCtx, oo, severity, next.getMessage(), location, ExceptionHandlingInterceptor.PROCESSING); } return oo; }
@Test(expected = DataFormatException.class) public void testScanInvalid() { FhirContext ctx = FhirContext.forDstu2(); ctx.getResourceDefinition("InvalidResource"); }
private void encodeResourceToXmlStreamWriter( IBaseResource theResource, XMLStreamWriter theEventWriter, boolean theContainedResource, String theResourceId) throws XMLStreamException { if (!theContainedResource) { super.containResourcesForEncoding(theResource); } RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource); if (resDef == null) { throw new ConfigurationException("Unknown resource type: " + theResource.getClass()); } theEventWriter.writeStartElement(resDef.getName()); theEventWriter.writeDefaultNamespace(FHIR_NS); if (theResource instanceof IAnyResource) { // HL7.org Structures encodeCompositeElementToStreamWriter( theResource, theResource, theEventWriter, resDef, theContainedResource); } else { if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) { // DSTU2+ IResource resource = (IResource) theResource; writeOptionalTagWithValue(theEventWriter, "id", theResourceId); InstantDt updated = (InstantDt) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED); IdDt resourceId = resource.getId(); String versionIdPart = resourceId.getVersionIdPart(); if (isBlank(versionIdPart)) { versionIdPart = ResourceMetadataKeyEnum.VERSION.get(resource); } List<BaseCodingDt> securityLabels = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.SECURITY_LABELS); List<IdDt> profiles = extractMetadataListNotNull(resource, ResourceMetadataKeyEnum.PROFILES); TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(resource); if (ElementUtil.isEmpty(versionIdPart, updated, securityLabels, profiles) == false) { theEventWriter.writeStartElement("meta"); writeOptionalTagWithValue(theEventWriter, "versionId", versionIdPart); if (updated != null) { writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString()); } for (IdDt profile : profiles) { theEventWriter.writeStartElement("profile"); theEventWriter.writeAttribute("value", profile.getValue()); theEventWriter.writeEndElement(); } for (BaseCodingDt securityLabel : securityLabels) { theEventWriter.writeStartElement("security"); BaseRuntimeElementCompositeDefinition<?> def = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass()); encodeCompositeElementChildrenToStreamWriter( resource, securityLabel, theEventWriter, def.getChildren(), theContainedResource); theEventWriter.writeEndElement(); } if (tags != null) { for (Tag tag : tags) { theEventWriter.writeStartElement("tag"); writeOptionalTagWithValue(theEventWriter, "system", tag.getScheme()); writeOptionalTagWithValue(theEventWriter, "code", tag.getTerm()); writeOptionalTagWithValue(theEventWriter, "display", tag.getLabel()); theEventWriter.writeEndElement(); } } theEventWriter.writeEndElement(); } if (theResource instanceof IBaseBinary) { IBaseBinary bin = (IBaseBinary) theResource; writeOptionalTagWithValue(theEventWriter, "contentType", bin.getContentType()); writeOptionalTagWithValue(theEventWriter, "content", bin.getContentAsBase64()); } else { encodeResourceToStreamWriterInDstu2Format( resDef, theResource, theResource, theEventWriter, resDef, theContainedResource); } } else { // DSTU1 if (theResourceId != null && theContainedResource) { theEventWriter.writeAttribute("id", theResourceId); } if (theResource instanceof IBaseBinary) { IBaseBinary bin = (IBaseBinary) theResource; if (bin.getContentType() != null) { theEventWriter.writeAttribute("contentType", bin.getContentType()); } theEventWriter.writeCharacters(bin.getContentAsBase64()); } else { encodeCompositeElementToStreamWriter( theResource, theResource, theEventWriter, resDef, theContainedResource); } } } theEventWriter.writeEndElement(); }
private void encodeCompositeElementChildrenToStreamWriter( IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException, DataFormatException { for (BaseRuntimeChildDefinition nextChild : children) { if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) { continue; } if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) { INarrativeGenerator gen = myContext.getNarrativeGenerator(); if (theResource instanceof IResource) { BaseNarrativeDt<?> narr = ((IResource) theResource).getText(); if (gen != null && narr.isEmpty()) { String resourceProfile = myContext.getResourceDefinition(theResource).getResourceProfile(); gen.generateNarrative(resourceProfile, theResource, narr); } if (narr.isEmpty() == false) { RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; String childName = nextChild.getChildNameByDatatype(child.getDatatype()); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); encodeChildElementToStreamWriter( theResource, theEventWriter, narr, childName, type, null, theIncludedResource); continue; } } else { INarrative narr1 = ((IDomainResource) theResource).getText(); BaseNarrativeDt<?> narr2 = null; if (gen != null && narr1.isEmpty()) { // TODO: need to implement this String resourceProfile = myContext.getResourceDefinition(theResource).getResourceProfile(); gen.generateNarrative(resourceProfile, theResource, null); } if (narr2 != null) { RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; String childName = nextChild.getChildNameByDatatype(child.getDatatype()); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); encodeChildElementToStreamWriter( theResource, theEventWriter, narr2, childName, type, null, theIncludedResource); continue; } } } List<? extends IBase> values = nextChild.getAccessor().getValues(theElement); if (values == null || values.isEmpty()) { continue; } for (IBase nextValue : values) { if ((nextValue == null || nextValue.isEmpty()) && !(nextValue instanceof BaseContainedDt)) { continue; } Class<? extends IBase> type = nextValue.getClass(); String childName = nextChild.getChildNameByDatatype(type); String extensionUrl = nextChild.getExtensionUrl(); BaseRuntimeElementDefinition<?> childDef = nextChild.getChildElementDefinitionByDatatype(type); if (childDef == null) { super.throwExceptionForUnknownChildType(nextChild, type); } if (nextValue instanceof IBaseExtension && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) { // This is called for the Query resource in DSTU1 only extensionUrl = ((IBaseExtension<?>) nextValue).getUrl(); encodeChildElementToStreamWriter( theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource); } else if (extensionUrl != null && childName.equals("extension") == false) { RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild; if (extDef.isModifier()) { theEventWriter.writeStartElement("modifierExtension"); } else { theEventWriter.writeStartElement("extension"); } theEventWriter.writeAttribute("url", extensionUrl); encodeChildElementToStreamWriter( theResource, theEventWriter, nextValue, childName, childDef, null, theIncludedResource); theEventWriter.writeEndElement(); } else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIncludedResource) { // suppress narratives from contained resources } else { encodeChildElementToStreamWriter( theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource); } } } }
@SuppressWarnings("unchecked") public BaseResourceReturningMethodBinding( Class<?> theReturnResourceType, Method theMethod, FhirContext theContext, Object theProvider) { super(theMethod, theContext, theProvider); Class<?> methodReturnType = theMethod.getReturnType(); if (Collection.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.LIST_OF_RESOURCES; Class<?> collectionType = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod); if (collectionType != null) { if (!Object.class.equals(collectionType) && !IResource.class.isAssignableFrom(collectionType)) { throw new ConfigurationException( "Method " + theMethod.getDeclaringClass().getSimpleName() + "#" + theMethod.getName() + " returns an invalid collection generic type: " + collectionType); } } myResourceListCollectionType = collectionType; } else if (IBaseResource.class.isAssignableFrom(methodReturnType)) { if (Modifier.isAbstract(methodReturnType.getModifiers()) == false && theContext .getResourceDefinition((Class<? extends IBaseResource>) methodReturnType) .isBundle()) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE_RESOURCE; } else { myMethodReturnType = MethodReturnTypeEnum.RESOURCE; } } else if (Bundle.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE; } else if (IBundleProvider.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE_PROVIDER; } else { throw new ConfigurationException( "Invalid return type '" + methodReturnType.getCanonicalName() + "' on method '" + theMethod.getName() + "' on type: " + theMethod.getDeclaringClass().getCanonicalName()); } if (theReturnResourceType != null) { if (IResource.class.isAssignableFrom(theReturnResourceType)) { ResourceDef resourceDefAnnotation = theReturnResourceType.getAnnotation(ResourceDef.class); if (resourceDefAnnotation == null) { if (Modifier.isAbstract(theReturnResourceType.getModifiers())) { // If we're returning an abstract type, that's ok } else { throw new ConfigurationException( theReturnResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName() + " annotation"); } } else { myResourceType = (Class<? extends IResource>) theReturnResourceType; myResourceName = resourceDefAnnotation.name(); } } } }
private String toResourceName(Class<? extends IResource> theType) { return myContext.getResourceDefinition(theType).getName(); }
@SuppressWarnings("unchecked") void validateServerBase(String theServerBase, HttpClient theHttpClient, BaseClient theClient) { GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this); for (IClientInterceptor interceptor : theClient.getInterceptors()) { client.registerInterceptor(interceptor); } client.setDontValidateConformance(true); IBaseResource conformance; try { @SuppressWarnings("rawtypes") Class implementingClass = myContext.getResourceDefinition("Conformance").getImplementingClass(); conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute(); } catch (FhirClientConnectionException e) { throw new FhirClientConnectionException( myContext .getLocalizer() .getMessage( RestfulClientFactory.class, "failedToRetrieveConformance", theServerBase + Constants.URL_TOKEN_METADATA), e); } FhirTerser t = myContext.newTerser(); String serverFhirVersionString = null; Object value = t.getSingleValueOrNull(conformance, "fhirVersion"); if (value instanceof IPrimitiveType) { serverFhirVersionString = ((IPrimitiveType<?>) value).getValueAsString(); } FhirVersionEnum serverFhirVersionEnum = null; if (StringUtils.isBlank(serverFhirVersionString)) { // we'll be lenient and accept this } else { if (serverFhirVersionString.startsWith("0.80") || serverFhirVersionString.startsWith("0.0.8")) { serverFhirVersionEnum = FhirVersionEnum.DSTU1; } else if (serverFhirVersionString.startsWith("0.4")) { serverFhirVersionEnum = FhirVersionEnum.DSTU2; } else if (serverFhirVersionString.startsWith("0.5")) { serverFhirVersionEnum = FhirVersionEnum.DSTU2; } else { // we'll be lenient and accept this ourLog.debug( "Server conformance statement indicates unknown FHIR version: {}", serverFhirVersionString); } } if (serverFhirVersionEnum != null) { FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion(); if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) { throw new FhirClientInappropriateForServerException( myContext .getLocalizer() .getMessage( RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion)); } } myValidatedServerBaseUrls.add(normalizeBaseUrlForMap(theServerBase)); }