Merge branch 'master' of https://github.com/jaferkhan/hapi-fhir into cleanup-docs-v2
# Conflicts: # hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/validation/profile_validator.md
This commit is contained in:
commit
b8b8248133
|
@ -0,0 +1,17 @@
|
|||
# Two years until issues go stale
|
||||
daysUntilStale: 730
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
variables:
|
||||
MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository
|
||||
MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'
|
||||
#MAVEN_CACHE_FOLDER: $(Agent.TempDirectory)/.m2/repository
|
||||
#MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'
|
||||
MAVEN_OPTS: ''
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
@ -15,17 +17,21 @@ jobs:
|
|||
timeoutInMinutes: 360
|
||||
container: maven:3-jdk-11
|
||||
steps:
|
||||
- task: CacheBeta@0
|
||||
- task: Cache@2
|
||||
inputs:
|
||||
key: maven
|
||||
key: 'maven | "$(Agent.OS)" | ./pom.xml'
|
||||
path: $(MAVEN_CACHE_FOLDER)
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: mkdir -p $(MAVEN_CACHE_FOLDER); pwd; ls -al $(MAVEN_CACHE_FOLDER)
|
||||
- task: Maven@3
|
||||
env:
|
||||
JAVA_HOME_11_X64: /usr/local/openjdk-11
|
||||
inputs:
|
||||
goals: 'clean install'
|
||||
# These are Maven CLI options (and show up in the build logs) - "-nsu"=Don't update snapshots. We can remove this when Maven OSS is more healthy
|
||||
options: '-P ALLMODULES,JACOCO,CI,ERRORPRONE -nsu'
|
||||
options: '-P ALLMODULES,JACOCO,CI,ERRORPRONE -nsu -e -B -Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'
|
||||
# These are JVM options (and don't show up in the build logs)
|
||||
mavenOptions: '-Xmx2048m $(MAVEN_OPTS) -Dorg.slf4j.simpleLogger.showDateTime=true -Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Duser.timezone=America/Toronto'
|
||||
jdkVersionOption: 1.11
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
/target/
|
||||
|
||||
# Created by https://www.gitignore.io
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
### Vim ###
|
||||
[._]*.s[a-w][a-z]
|
||||
[._]s[a-w][a-z]
|
||||
*.un~
|
||||
Session.vim
|
||||
.netrwhist
|
||||
*~
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
133
examples/pom.xml
133
examples/pom.xml
|
@ -1,133 +0,0 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>hapi-fhir-base-examples</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HAPI FHIR - Examples (for site)</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-bom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2.1</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-converter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-client-okhttp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- jax rs server -->
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jaxrsserver-base</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<version>2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ejb</groupId>
|
||||
<artifactId>ejb-api</artifactId>
|
||||
<version>3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-jpaserver-base</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j_version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -1,216 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.HookParams;
|
||||
import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.auth.*;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AuthorizationInterceptors {
|
||||
|
||||
public class PatientResourceProvider implements IResourceProvider
|
||||
{
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
public MethodOutcome create(@ResourceParam Patient thePatient, RequestDetails theRequestDetails) {
|
||||
|
||||
return new MethodOutcome(); // populate this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//START SNIPPET: patientAndAdmin
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class PatientAndAdminAuthorizationInterceptor extends AuthorizationInterceptor {
|
||||
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
|
||||
// Process authorization header - The following is a fake
|
||||
// implementation. Obviously we'd want something more real
|
||||
// for a production scenario.
|
||||
//
|
||||
// In this basic example we have two hardcoded bearer tokens,
|
||||
// one which is for a user that has access to one patient, and
|
||||
// another that has full access.
|
||||
IdDt userIdPatientId = null;
|
||||
boolean userIsAdmin = false;
|
||||
String authHeader = theRequestDetails.getHeader("Authorization");
|
||||
if ("Bearer dfw98h38r".equals(authHeader)) {
|
||||
// This user has access only to Patient/1 resources
|
||||
userIdPatientId = new IdDt("Patient", 1L);
|
||||
} else if ("Bearer 39ff939jgg".equals(authHeader)) {
|
||||
// This user has access to everything
|
||||
userIsAdmin = true;
|
||||
} else {
|
||||
// Throw an HTTP 401
|
||||
throw new AuthenticationException("Missing or invalid Authorization header value");
|
||||
}
|
||||
|
||||
// If the user is a specific patient, we create the following rule chain:
|
||||
// Allow the user to read anything in their own patient compartment
|
||||
// Allow the user to write anything in their own patient compartment
|
||||
// If a client request doesn't pass either of the above, deny it
|
||||
if (userIdPatientId != null) {
|
||||
return new RuleBuilder()
|
||||
.allow().read().allResources().inCompartment("Patient", userIdPatientId).andThen()
|
||||
.allow().write().allResources().inCompartment("Patient", userIdPatientId).andThen()
|
||||
.denyAll()
|
||||
.build();
|
||||
}
|
||||
|
||||
// If the user is an admin, allow everything
|
||||
if (userIsAdmin) {
|
||||
return new RuleBuilder()
|
||||
.allowAll()
|
||||
.build();
|
||||
}
|
||||
|
||||
// By default, deny everything. This should never get hit, but it's
|
||||
// good to be defensive
|
||||
return new RuleBuilder()
|
||||
.denyAll()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
//END SNIPPET: patientAndAdmin
|
||||
|
||||
|
||||
//START SNIPPET: conditionalUpdate
|
||||
@Update()
|
||||
public MethodOutcome update(
|
||||
@IdParam IdDt theId,
|
||||
@ResourceParam Patient theResource,
|
||||
@ConditionalUrlParam String theConditionalUrl,
|
||||
ServletRequestDetails theRequestDetails,
|
||||
IInterceptorBroadcaster theInterceptorBroadcaster) {
|
||||
|
||||
// If we're processing a conditional URL...
|
||||
if (isNotBlank(theConditionalUrl)) {
|
||||
|
||||
// Pretend we've done the conditional processing. Now let's
|
||||
// notify the interceptors that an update has been performed
|
||||
// and supply the actual ID that's being updated
|
||||
IdDt actual = new IdDt("Patient", "1123");
|
||||
|
||||
}
|
||||
|
||||
// In a real server, perhaps we would process the conditional
|
||||
// request differently and follow a separate path. Either way,
|
||||
// let's pretend there is some storage code here.
|
||||
theResource.setId(theId.withVersion("2"));
|
||||
|
||||
// Notify the interceptor framework when we're about to perform an update. This is
|
||||
// useful as the authorization interceptor will pick this event up and use it
|
||||
// to factor into a decision about whether the operation should be allowed to proceed.
|
||||
IBaseResource previousContents = theResource;
|
||||
IBaseResource newContents = theResource;
|
||||
HookParams params = new HookParams()
|
||||
.add(IBaseResource.class, previousContents)
|
||||
.add(IBaseResource.class, newContents)
|
||||
.add(RequestDetails.class, theRequestDetails)
|
||||
.add(ServletRequestDetails.class, theRequestDetails);
|
||||
theInterceptorBroadcaster.callHooks(Pointcut.STORAGE_PRESTORAGE_RESOURCE_UPDATED, params);
|
||||
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
retVal.setCreated(true);
|
||||
retVal.setResource(theResource);
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: conditionalUpdate
|
||||
|
||||
public void authorizeTenantAction() {
|
||||
//START SNIPPET: authorizeTenantAction
|
||||
new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
.allow().read().resourcesOfType(Patient.class).withAnyId().forTenantIds("TENANTA").andThen()
|
||||
.build();
|
||||
}
|
||||
};
|
||||
//END SNIPPET: authorizeTenantAction
|
||||
|
||||
|
||||
//START SNIPPET: patchAll
|
||||
new AuthorizationInterceptor(PolicyEnum.DENY) {
|
||||
@Override
|
||||
public List<IAuthRule> buildRuleList(RequestDetails theRequestDetails) {
|
||||
return new RuleBuilder()
|
||||
// Authorize patch requests
|
||||
.allow().patch().allRequests().andThen()
|
||||
// Authorize actual writes that patch may perform
|
||||
.allow().write().allResources().inCompartment("Patient", new IdType("Patient/123")).andThen()
|
||||
.build();
|
||||
}
|
||||
};
|
||||
//END SNIPPET: patchAll
|
||||
|
||||
}
|
||||
|
||||
|
||||
//START SNIPPET: narrowing
|
||||
public class MyPatientSearchNarrowingInterceptor extends SearchNarrowingInterceptor {
|
||||
|
||||
/**
|
||||
* This method must be overridden to provide the list of compartments
|
||||
* and/or resources that the current user should have access to
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizedList buildAuthorizedList(RequestDetails theRequestDetails) {
|
||||
// Process authorization header - The following is a fake
|
||||
// implementation. Obviously we'd want something more real
|
||||
// for a production scenario.
|
||||
//
|
||||
// In this basic example we have two hardcoded bearer tokens,
|
||||
// one which is for a user that has access to one patient, and
|
||||
// another that has full access.
|
||||
String authHeader = theRequestDetails.getHeader("Authorization");
|
||||
if ("Bearer dfw98h38r".equals(authHeader)) {
|
||||
|
||||
// This user will have access to two compartments
|
||||
return new AuthorizedList()
|
||||
.addCompartment("Patient/123")
|
||||
.addCompartment("Patient/456");
|
||||
|
||||
} else if ("Bearer 39ff939jgg".equals(authHeader)) {
|
||||
|
||||
// This user has access to everything
|
||||
return new AuthorizedList();
|
||||
|
||||
} else {
|
||||
|
||||
throw new AuthenticationException("Unknown bearer token");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: narrowing
|
||||
|
||||
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package example;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor;
|
||||
import ca.uhn.fhir.rest.server.util.ITestingUiClientFactory;
|
||||
|
||||
public class AuthorizingTesterUiClientFactory implements ITestingUiClientFactory {
|
||||
|
||||
@Override
|
||||
public IGenericClient newClient(FhirContext theFhirContext, HttpServletRequest theRequest, String theServerBaseUrl) {
|
||||
// Create a client
|
||||
IGenericClient client = theFhirContext.newRestfulGenericClient(theServerBaseUrl);
|
||||
|
||||
// Register an interceptor which adds credentials
|
||||
client.registerInterceptor(new BasicAuthInterceptor("someusername", "somepassword"));
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.RelatedPerson;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
/**
|
||||
* @author Bill de Beaubien on 1/13/2016.
|
||||
*/
|
||||
public class BundleFetcher {
|
||||
public static void fetchRestOfBundle(IGenericClient theClient, Bundle theBundle) {
|
||||
// we need to keep track of which resources are already in the bundle so that if other resources (e.g. Practitioner) are _included,
|
||||
// we don't end up with multiple copies
|
||||
Set<String> resourcesAlreadyAdded = new HashSet<String>();
|
||||
addInitialUrlsToSet(theBundle, resourcesAlreadyAdded);
|
||||
Bundle partialBundle = theBundle;
|
||||
for (;;) {
|
||||
if (partialBundle.getLink(IBaseBundle.LINK_NEXT) != null) {
|
||||
partialBundle = theClient.loadPage().next(partialBundle).execute();
|
||||
addAnyResourcesNotAlreadyPresentToBundle(theBundle, partialBundle, resourcesAlreadyAdded);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// the self and next links for the aggregated bundle aren't really valid anymore, so remove them
|
||||
theBundle.getLink().clear();
|
||||
}
|
||||
|
||||
private static void addInitialUrlsToSet(Bundle theBundle, Set<String> theResourcesAlreadyAdded) {
|
||||
for (Bundle.Entry entry : theBundle.getEntry()) {
|
||||
theResourcesAlreadyAdded.add(entry.getFullUrl());
|
||||
}
|
||||
}
|
||||
|
||||
private static void addAnyResourcesNotAlreadyPresentToBundle(Bundle theAggregatedBundle, Bundle thePartialBundle, Set<String> theResourcesAlreadyAdded) {
|
||||
for (Bundle.Entry entry : thePartialBundle.getEntry()) {
|
||||
if (!theResourcesAlreadyAdded.contains(entry.getFullUrl())) {
|
||||
theResourcesAlreadyAdded.add(entry.getFullUrl());
|
||||
theAggregatedBundle.getEntry().add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
// use RelatedPerson because there aren't that many on the server
|
||||
Bundle bundle = client.search().forResource(RelatedPerson.class).returnBundle(Bundle.class).execute();
|
||||
BundleFetcher.fetchRestOfBundle(client, bundle);
|
||||
if (bundle.getTotal() != bundle.getEntry().size()) {
|
||||
System.out.println("Counts didn't match! Expected " + bundle.getTotal() + " but bundle only had " + bundle.getEntry().size() + " entries!");
|
||||
}
|
||||
|
||||
// IParser parser = ctx.newXmlParser().setPrettyPrint(true);
|
||||
// System.out.println(parser.encodeResourceToString(bundle));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.okhttp.client.OkHttpRestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.client.apache.GZipContentInterceptor;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ca.uhn.fhir.rest.client.interceptor.*;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
public class ClientExamples {
|
||||
|
||||
public interface IPatientClient extends IBasicClient {
|
||||
// nothing yet
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createProxy() {
|
||||
// START SNIPPET: proxy
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Set connections to access the network via the HTTP proxy at
|
||||
// example.com : 8888
|
||||
ctx.getRestfulClientFactory().setProxy("example.com", 8888);
|
||||
|
||||
// If the proxy requires authentication, use the following as well
|
||||
ctx.getRestfulClientFactory().setProxyCredentials("theUsername", "thePassword");
|
||||
|
||||
// Create the client
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
// END SNIPPET: proxy
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void processMessage() {
|
||||
// START SNIPPET: processMessage
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create the client
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
// ..populate the bundle..
|
||||
|
||||
Bundle response = client
|
||||
.operation()
|
||||
.processMessage() // New operation for sending messages
|
||||
.setMessageBundle(bundle)
|
||||
.asynchronous(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: processMessage
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void cacheControl() {
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create the client
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
// ..populate the bundle..
|
||||
|
||||
// START SNIPPET: cacheControl
|
||||
Bundle response = client
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.returnBundle(Bundle.class)
|
||||
.cacheControl(new CacheControlDirective().setNoCache(true)) // <-- add a directive
|
||||
.execute();
|
||||
// END SNIPPET: cacheControl
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createOkHttp() {
|
||||
// START SNIPPET: okhttp
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Use OkHttp
|
||||
ctx.setRestfulClientFactory(new OkHttpRestfulClientFactory(ctx));
|
||||
|
||||
// Create the client
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
// END SNIPPET: okhttp
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createTimeouts() {
|
||||
// START SNIPPET: timeouts
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Set how long to try and establish the initial TCP connection (in ms)
|
||||
ctx.getRestfulClientFactory().setConnectTimeout(20 * 1000);
|
||||
|
||||
// Set how long to block for individual read/write operations (in ms)
|
||||
ctx.getRestfulClientFactory().setSocketTimeout(20 * 1000);
|
||||
|
||||
// Create the client
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
// END SNIPPET: timeouts
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createSecurity() {
|
||||
// START SNIPPET: security
|
||||
// Create a context and get the client factory so it can be configured
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IRestfulClientFactory clientFactory = ctx.getRestfulClientFactory();
|
||||
|
||||
// Create an HTTP basic auth interceptor
|
||||
String username = "foobar";
|
||||
String password = "boobear";
|
||||
IClientInterceptor authInterceptor = new BasicAuthInterceptor(username, password);
|
||||
|
||||
// If you're usinf an annotation client, use this style to
|
||||
// register it
|
||||
IPatientClient annotationClient = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(authInterceptor);
|
||||
|
||||
// If you're using a generic client, use this instead
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
genericClient.registerInterceptor(authInterceptor);
|
||||
// END SNIPPET: security
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createCookie() {
|
||||
// START SNIPPET: cookie
|
||||
// Create a context and get the client factory so it can be configured
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IRestfulClientFactory clientFactory = ctx.getRestfulClientFactory();
|
||||
|
||||
// Create a cookie interceptor. This cookie will have the name "mycookie" and
|
||||
// the value "Chips Ahoy"
|
||||
CookieInterceptor interceptor = new CookieInterceptor("mycookie=Chips Ahoy");
|
||||
|
||||
// Register the interceptor with your client (either style)
|
||||
IPatientClient annotationClient = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(interceptor);
|
||||
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(interceptor);
|
||||
// END SNIPPET: cookie
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void gzip() {
|
||||
// START SNIPPET: gzip
|
||||
// Create a context and get the client factory so it can be configured
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IRestfulClientFactory clientFactory = ctx.getRestfulClientFactory();
|
||||
|
||||
// Register the interceptor with your client (either style)
|
||||
IPatientClient annotationClient = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(new GZipContentInterceptor());
|
||||
// END SNIPPET: gzip
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createSecurityBearer() {
|
||||
// START SNIPPET: securityBearer
|
||||
// Create a context and get the client factory so it can be configured
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IRestfulClientFactory clientFactory = ctx.getRestfulClientFactory();
|
||||
|
||||
// In reality the token would have come from an authorization server
|
||||
String token = "3w03fj.r3r3t";
|
||||
|
||||
BearerTokenAuthInterceptor authInterceptor = new BearerTokenAuthInterceptor(token);
|
||||
|
||||
// Register the interceptor with your client (either style)
|
||||
IPatientClient annotationClient = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(authInterceptor);
|
||||
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(authInterceptor);
|
||||
// END SNIPPET: securityBearer
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void createLogging() {
|
||||
{
|
||||
// START SNIPPET: logging
|
||||
// Create a context and get the client factory so it can be configured
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IRestfulClientFactory clientFactory = ctx.getRestfulClientFactory();
|
||||
|
||||
// Create a logging interceptor
|
||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
||||
|
||||
// Optionally you may configure the interceptor (by default only
|
||||
// summary info is logged)
|
||||
loggingInterceptor.setLogRequestSummary(true);
|
||||
loggingInterceptor.setLogRequestBody(true);
|
||||
|
||||
// Register the interceptor with your client (either style)
|
||||
IPatientClient annotationClient = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/fhir");
|
||||
annotationClient.registerInterceptor(loggingInterceptor);
|
||||
|
||||
IGenericClient genericClient = ctx.newRestfulGenericClient("http://localhost:9999/fhir");
|
||||
genericClient.registerInterceptor(loggingInterceptor);
|
||||
// END SNIPPET: logging
|
||||
}
|
||||
|
||||
/******************************/
|
||||
{
|
||||
// START SNIPPET: clientConfig
|
||||
// Create a client
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IPatientClient client = ctx.newRestfulClient(IPatientClient.class, "http://localhost:9999/");
|
||||
|
||||
// Request JSON encoding from the server (_format=json)
|
||||
client.setEncoding(EncodingEnum.JSON);
|
||||
|
||||
// Request pretty printing from the server (_pretty=true)
|
||||
client.setPrettyPrint(true);
|
||||
// END SNIPPET: clientConfig
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.*;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.*;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
public class ClientTransactionExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
conditionalCreate();
|
||||
}
|
||||
|
||||
private static void conditionalCreate() {
|
||||
|
||||
//START SNIPPET: conditional
|
||||
// Create a patient object
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier()
|
||||
.setSystem("http://acme.org/mrns")
|
||||
.setValue("12345");
|
||||
patient.addName()
|
||||
.addFamily("Jameson")
|
||||
.addGiven("J")
|
||||
.addGiven("Jonah");
|
||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||
|
||||
// Give the patient a temporary UUID so that other resources in
|
||||
// the transaction can refer to it
|
||||
patient.setId(IdDt.newRandomUuid());
|
||||
|
||||
// Create an observation object
|
||||
Observation observation = new Observation();
|
||||
observation.setStatus(ObservationStatusEnum.FINAL);
|
||||
observation
|
||||
.getCode()
|
||||
.addCoding()
|
||||
.setSystem("http://loinc.org")
|
||||
.setCode("789-8")
|
||||
.setDisplay("Erythrocytes [#/volume] in Blood by Automated count");
|
||||
observation.setValue(
|
||||
new QuantityDt()
|
||||
.setValue(4.12)
|
||||
.setUnit("10 trillion/L")
|
||||
.setSystem("http://unitsofmeasure.org")
|
||||
.setCode("10*12/L"));
|
||||
|
||||
// The observation refers to the patient using the ID, which is already
|
||||
// set to a temporary UUID
|
||||
observation.setSubject(new ResourceReferenceDt(patient.getId().getValue()));
|
||||
|
||||
// Create a bundle that will be used as a transaction
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.setType(BundleTypeEnum.TRANSACTION);
|
||||
|
||||
// Add the patient as an entry. This entry is a POST with an
|
||||
// If-None-Exist header (conditional create) meaning that it
|
||||
// will only be created if there isn't already a Patient with
|
||||
// the identifier 12345
|
||||
bundle.addEntry()
|
||||
.setFullUrl(patient.getId().getValue())
|
||||
.setResource(patient)
|
||||
.getRequest()
|
||||
.setUrl("Patient")
|
||||
.setIfNoneExist("identifier=http://acme.org/mrns|12345")
|
||||
.setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
// Add the observation. This entry is a POST with no header
|
||||
// (normal create) meaning that it will be created even if
|
||||
// a similar resource already exists.
|
||||
bundle.addEntry()
|
||||
.setResource(observation)
|
||||
.getRequest()
|
||||
.setUrl("Observation")
|
||||
.setMethod(HTTPVerbEnum.POST);
|
||||
|
||||
// Log the request
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
System.out.println(ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(bundle));
|
||||
|
||||
// Create a client and post the transaction to the server
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
Bundle resp = client.transaction().withBundle(bundle).execute();
|
||||
|
||||
// Log the response
|
||||
System.out.println(ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(resp));
|
||||
//END SNIPPET: conditional
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package example;
|
||||
|
||||
//START SNIPPET: client
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
|
||||
public class CompleteExampleClient {
|
||||
|
||||
/**
|
||||
* This is a simple client interface. It can have many methods for various
|
||||
* searches but in this case it has only 1.
|
||||
*/
|
||||
public static interface ClientInterface extends IRestfulClient {
|
||||
|
||||
/**
|
||||
* This is translated into a URL similar to the following:
|
||||
* http://fhir.healthintersections.com.au/open/Patient?identifier=urn:oid:1.2.36.146.595.217.0.1%7C12345
|
||||
*/
|
||||
@Search
|
||||
List<Patient> findPatientsForMrn(@RequiredParam(name = Patient.SP_IDENTIFIER) IdentifierDt theIdentifier);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method here will directly call an open FHIR server and retrieve a
|
||||
* list of resources matching a given criteria, then load a linked resource.
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
// Create a client factory
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Create the client
|
||||
String serverBase = "http://fhir.healthintersections.com.au/open";
|
||||
ClientInterface client = ctx.newRestfulClient(ClientInterface.class, serverBase);
|
||||
|
||||
// Invoke the client to search for patient
|
||||
List<Patient> patients = client.findPatientsForMrn(new IdentifierDt("urn:oid:1.2.36.146.595.217.0.1", "12345"));
|
||||
|
||||
System.out.println("Found " + patients.size() + " patients");
|
||||
|
||||
// Print a value from the loaded resource
|
||||
Patient patient = patients.get(0);
|
||||
System.out.println("Patient Last Name: " + patient.getName().get(0).getFamily().get(0).getValue());
|
||||
|
||||
// Load a referenced resource
|
||||
ResourceReferenceDt managingRef = patient.getManagingOrganization();
|
||||
Organization org = (Organization) managingRef.loadResource(client);
|
||||
|
||||
// Print organization name
|
||||
System.out.println(org.getName());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: client
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.consent.ConsentOutcome;
|
||||
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
|
||||
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentService;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ConsentInterceptors {
|
||||
|
||||
|
||||
//START SNIPPET: service
|
||||
public class MyConsentService implements IConsentService {
|
||||
|
||||
/**
|
||||
* Invoked once at the start of every request
|
||||
*/
|
||||
@Override
|
||||
public ConsentOutcome startOperation(RequestDetails theRequestDetails, IConsentContextServices theContextServices) {
|
||||
// This means that all requests should flow through the consent service
|
||||
// This has performance implications - If you know that some requests
|
||||
// don't need consent checking it is a good idea to return
|
||||
// ConsentOutcome.AUTHORIZED instead for those requests.
|
||||
return ConsentOutcome.PROCEED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a given resource be returned to the user?
|
||||
*/
|
||||
@Override
|
||||
public ConsentOutcome canSeeResource(RequestDetails theRequestDetails, IBaseResource theResource, IConsentContextServices theContextServices) {
|
||||
// In this basic example, we will filter out lab results so that they
|
||||
// are never disclosed to the user. A real interceptor might do something
|
||||
// more nuanced.
|
||||
if (theResource instanceof Observation) {
|
||||
Observation obs = (Observation)theResource;
|
||||
if (obs.getCategoryFirstRep().hasCoding("http://hl7.org/fhir/codesystem-observation-category.html", "laboratory")) {
|
||||
return ConsentOutcome.REJECT;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, allow the
|
||||
return ConsentOutcome.PROCEED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify resources that are being shown to the user
|
||||
*/
|
||||
@Override
|
||||
public ConsentOutcome willSeeResource(RequestDetails theRequestDetails, IBaseResource theResource, IConsentContextServices theContextServices) {
|
||||
// Don't return the subject for Observation resources
|
||||
if (theResource instanceof Observation) {
|
||||
Observation obs = (Observation)theResource;
|
||||
obs.setSubject(null);
|
||||
}
|
||||
return ConsentOutcome.AUTHORIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeOperationSuccess(RequestDetails theRequestDetails, IConsentContextServices theContextServices) {
|
||||
// We could write an audit trail entry in here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeOperationFailure(RequestDetails theRequestDetails, BaseServerResponseException theException, IConsentContextServices theContextServices) {
|
||||
// We could write an audit trail entry in here
|
||||
}
|
||||
}
|
||||
//END SNIPPET: service
|
||||
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package example;
|
||||
|
||||
import org.hl7.fhir.converter.NullVersionConverterAdvisor30;
|
||||
import org.hl7.fhir.convertors.*;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
|
||||
public class ConverterExamples {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void c1020() throws FHIRException {
|
||||
//START SNIPPET: 1020
|
||||
// Create a converter
|
||||
NullVersionConverterAdvisor30 advisor = new NullVersionConverterAdvisor30();
|
||||
VersionConvertor_10_30 converter = new VersionConvertor_10_30(advisor);
|
||||
|
||||
// Create an input resource to convert
|
||||
org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation();
|
||||
input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123"));
|
||||
|
||||
// Convert the resource
|
||||
org.hl7.fhir.dstu3.model.Observation output = converter.convertObservation(input);
|
||||
String context = output.getContext().getReference();
|
||||
//END SNIPPET: 1020
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void c1420() throws FHIRException {
|
||||
//START SNIPPET: 1420
|
||||
// Create a resource to convert
|
||||
org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire();
|
||||
input.setTitle("My title");
|
||||
|
||||
// Convert the resource
|
||||
org.hl7.fhir.dstu3.model.Questionnaire output = VersionConvertor_14_30.convertQuestionnaire(input);
|
||||
String context = output.getTitle();
|
||||
//END SNIPPET: 1420
|
||||
}
|
||||
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.util.ResourceReferenceInfo;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Copier {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(Copier.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
IGenericClient source = ctx.newRestfulGenericClient("http://localhost:8080/baseDstu3");
|
||||
IGenericClient target = ctx.newRestfulGenericClient("https://try.smilecdr.com:8000");
|
||||
|
||||
List<String> resType = Arrays.asList(
|
||||
"Patient", "Organization", "Encounter", "Procedure",
|
||||
"Observation", "ResearchSubject", "Specimen",
|
||||
"ResearchStudy", "Location", "Practitioner"
|
||||
);
|
||||
|
||||
List<IBaseResource> queued = new ArrayList<>();
|
||||
Set<String> sent = new HashSet<>();
|
||||
for (String next : resType) {
|
||||
copy(ctx, source, target, next, queued, sent);
|
||||
}
|
||||
|
||||
while (queued.size() > 0) {
|
||||
ourLog.info("Have {} queued resources to deliver", queued.size());
|
||||
|
||||
for (IBaseResource nextQueued : new ArrayList<>(queued)) {
|
||||
|
||||
String missingRef = null;
|
||||
for (ResourceReferenceInfo nextRefInfo : ctx.newTerser().getAllResourceReferences(nextQueued)) {
|
||||
String nextRef = nextRefInfo.getResourceReference().getReferenceElement().getValue();
|
||||
if (isNotBlank(nextRef) && !sent.contains(nextRef)) {
|
||||
missingRef = nextRef;
|
||||
}
|
||||
}
|
||||
if (missingRef != null) {
|
||||
ourLog.info("Can't send {} because of missing ref {}", nextQueued.getIdElement().getIdPart(), missingRef);
|
||||
continue;
|
||||
}
|
||||
|
||||
IIdType newId = target
|
||||
.update()
|
||||
.resource(nextQueued)
|
||||
.execute()
|
||||
.getId();
|
||||
|
||||
ourLog.info("Copied resource {} and got ID {}", nextQueued.getIdElement().getValue(), newId);
|
||||
sent.add(nextQueued.getIdElement().toUnqualifiedVersionless().getValue());
|
||||
queued.remove(nextQueued);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void copy(FhirContext theCtx, IGenericClient theSource, IGenericClient theTarget, String theResType, List<IBaseResource> theQueued, Set<String> theSent) {
|
||||
Bundle received = theSource
|
||||
.search()
|
||||
.forResource(theResType)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
copy(theCtx, theTarget, theResType, theQueued, theSent, received);
|
||||
|
||||
while (received.getLink("next") != null) {
|
||||
ourLog.info("Fetching next page...");
|
||||
received = theSource.loadPage().next(received).execute();
|
||||
copy(theCtx, theTarget, theResType, theQueued, theSent, received);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void copy(FhirContext theCtx, IGenericClient theTarget, String theResType, List<IBaseResource> theQueued, Set<String> theSent, Bundle theReceived) {
|
||||
for (Bundle.BundleEntryComponent nextEntry : theReceived.getEntry()) {
|
||||
Resource nextResource = nextEntry.getResource();
|
||||
nextResource.setId(theResType + "/" + "CR-" + nextResource.getIdElement().getIdPart());
|
||||
|
||||
boolean haveUnsentReference = false;
|
||||
for (ResourceReferenceInfo nextRefInfo : theCtx.newTerser().getAllResourceReferences(nextResource)) {
|
||||
IIdType nextRef = nextRefInfo.getResourceReference().getReferenceElement();
|
||||
if (nextRef.hasIdPart()) {
|
||||
String newRef = nextRef.getResourceType() + "/" + "CR-" + nextRef.getIdPart();
|
||||
ourLog.info("Changing reference {} to {}", nextRef.getValue(), newRef);
|
||||
nextRefInfo.getResourceReference().setReference(newRef);
|
||||
if (!theSent.contains(newRef)) {
|
||||
haveUnsentReference = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (haveUnsentReference) {
|
||||
ourLog.info("Queueing {} for delivery after", nextResource.getId());
|
||||
theQueued.add(nextResource);
|
||||
continue;
|
||||
}
|
||||
|
||||
IIdType newId = theTarget
|
||||
.update()
|
||||
.resource(nextResource)
|
||||
.execute()
|
||||
.getId();
|
||||
|
||||
ourLog.info("Copied resource {} and got ID {}", nextResource.getId(), newId);
|
||||
theSent.add(nextResource.getIdElement().toUnqualifiedVersionless().getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package example;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
|
||||
public class CustomObservation extends Observation {
|
||||
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class Dstu2Examples {
|
||||
private Collection<IResourceProvider> resourceProviderList;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Dstu2Examples().getResourceTags();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void getResourceTags() {
|
||||
// START SNIPPET: context
|
||||
// Create a DSTU2 context, which will use DSTU2 semantics
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// This parser supports DSTU2
|
||||
IParser parser = ctx.newJsonParser();
|
||||
|
||||
// This client supports DSTU2
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
// END SNIPPET: context
|
||||
}
|
||||
|
||||
|
||||
// START SNIPPET: server
|
||||
public class MyServer extends RestfulServer
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// In your initialize method, assign a DSTU2 FhirContext. This
|
||||
// is all that is required in order to put the server
|
||||
// into DSTU2 mode
|
||||
setFhirContext(FhirContext.forDstu2());
|
||||
|
||||
// Then set resource providers as normal, and do any other
|
||||
// configuration you need to do.
|
||||
setResourceProviders(resourceProviderList);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: server
|
||||
|
||||
|
||||
public void upgrade() {
|
||||
// START SNIPPET: client
|
||||
FhirContext ctxDstu2 = FhirContext.forDstu2();
|
||||
IGenericClient clientDstu2 = ctxDstu2.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
// END SNIPPET: client
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
@SuppressWarnings(value= {"serial"})
|
||||
public class ExampleProviders {
|
||||
|
||||
|
||||
//START SNIPPET: plainProvider
|
||||
public class PlainProvider {
|
||||
|
||||
/**
|
||||
* This method is a Patient search, but HAPI can not automatically
|
||||
* determine the resource type so it must be explicitly stated.
|
||||
*/
|
||||
@Search(type=Patient.class)
|
||||
public Bundle searchForPatients(@RequiredParam(name=Patient.SP_NAME) StringDt theName) {
|
||||
Bundle retVal = new Bundle();
|
||||
// perform search
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: plainProvider
|
||||
|
||||
|
||||
//START SNIPPET: plainProviderServer
|
||||
public class ExampleServlet extends ca.uhn.fhir.rest.server.RestfulServer {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ExampleServlet() {
|
||||
/*
|
||||
* Plain providers are passed to the server in the same way
|
||||
* as resource providers. You may pass both resource providers
|
||||
* and and plain providers to the same server if you like.
|
||||
*/
|
||||
List<Object> plainProviders=new ArrayList<Object>();
|
||||
plainProviders.add(new PlainProvider());
|
||||
registerProviders(plainProviders);
|
||||
|
||||
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
|
||||
// ...add some resource providers...
|
||||
registerProviders(resourceProviders);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: plainProviderServer
|
||||
|
||||
//START SNIPPET: addressStrategy
|
||||
public class MyServlet extends ca.uhn.fhir.rest.server.RestfulServer {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public MyServlet() {
|
||||
|
||||
String serverBaseUrl = "http://foo.com/fhir";
|
||||
setServerAddressStrategy(new HardcodedServerAddressStrategy(serverBaseUrl));
|
||||
|
||||
// ...add some resource providers, etc...
|
||||
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
|
||||
setResourceProviders(resourceProviders);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: addressStrategy
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class ExampleRestfulClient {
|
||||
|
||||
//START SNIPPET: client
|
||||
public static void main(String[] args) {
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String serverBase = "http://foo.com/fhirServerBase";
|
||||
|
||||
// Create the client
|
||||
IRestfulClient client = ctx.newRestfulClient(IRestfulClient.class, serverBase);
|
||||
|
||||
// Try the client out! This method will invoke the server
|
||||
List<Patient> patients = client.getPatient(new StringDt("SMITH"));
|
||||
|
||||
}
|
||||
//END SNIPPET: client
|
||||
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
|
||||
//START SNIPPET: servlet
|
||||
/**
|
||||
* In this example, we are using Servlet 3.0 annotations to define
|
||||
* the URL pattern for this servlet, but we could also
|
||||
* define this in a web.xml file.
|
||||
*/
|
||||
@WebServlet(urlPatterns= {"/fhir/*"}, displayName="FHIR Server")
|
||||
public class ExampleRestfulServlet extends RestfulServer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* The initialize method is automatically called when the servlet is starting up, so it can
|
||||
* be used to configure the servlet to define resource providers, or set up
|
||||
* configuration, interceptors, etc.
|
||||
*/
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
/*
|
||||
* The servlet defines any number of resource providers, and
|
||||
* configures itself to use them by calling
|
||||
* setResourceProviders()
|
||||
*/
|
||||
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
|
||||
resourceProviders.add(new RestfulPatientResourceProvider());
|
||||
resourceProviders.add(new RestfulObservationResourceProvider());
|
||||
setResourceProviders(resourceProviders);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: servlet
|
||||
|
||||
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire.GroupQuestion;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
public class ExtensionsDstu2 {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
|
||||
{
|
||||
Questionnaire q= new Questionnaire();
|
||||
GroupQuestion item = q.getGroup().addQuestion();
|
||||
item.setText("Hello");
|
||||
|
||||
ExtensionDt extension = new ExtensionDt(false, "http://hl7.org/fhir/StructureDefinition/translation");
|
||||
item.getTextElement().addUndeclaredExtension(extension);
|
||||
|
||||
extension.addUndeclaredExtension(new ExtensionDt(false, "lang", new CodeDt("es")));
|
||||
extension.addUndeclaredExtension(new ExtensionDt(false, "cont", new StringDt("hola")));
|
||||
|
||||
System.out.println(FhirContext.forDstu2().newJsonParser().setPrettyPrint(true).encodeResourceToString(q));
|
||||
}
|
||||
|
||||
|
||||
// START SNIPPET: resourceExtension
|
||||
// Create an example patient
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
|
||||
|
||||
// Create an extension
|
||||
ExtensionDt ext = new ExtensionDt();
|
||||
ext.setModifier(false);
|
||||
ext.setUrl("http://example.com/extensions#someext");
|
||||
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
|
||||
|
||||
// Add the extension to the resource
|
||||
patient.addUndeclaredExtension(ext);
|
||||
//END SNIPPET: resourceExtension
|
||||
|
||||
|
||||
//START SNIPPET: resourceStringExtension
|
||||
// Continuing the example from above, we will add a name to the patient, and then
|
||||
// add an extension to part of that name
|
||||
HumanNameDt name = patient.addName();
|
||||
name.addFamily().setValue("Shmoe");
|
||||
|
||||
// Add a new "given name", which is of type StringDt
|
||||
StringDt given = name.addGiven();
|
||||
given.setValue("Joe");
|
||||
|
||||
// Create an extension and add it to the StringDt
|
||||
ExtensionDt givenExt = new ExtensionDt(false, "http://examples.com#moreext", new StringDt("Hello"));
|
||||
given.addUndeclaredExtension(givenExt);
|
||||
//END SNIPPET: resourceStringExtension
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(output);
|
||||
|
||||
|
||||
//START SNIPPET: parseExtension
|
||||
// Get all extensions (modifier or not) for a given URL
|
||||
List<ExtensionDt> resourceExts = patient.getUndeclaredExtensionsByUrl("http://fooextensions.com#exts");
|
||||
|
||||
// Get all non-modifier extensions regardless of URL
|
||||
List<ExtensionDt> nonModExts = patient.getUndeclaredExtensions();
|
||||
|
||||
//Get all non-modifier extensions regardless of URL
|
||||
List<ExtensionDt> modExts = patient.getUndeclaredModifierExtensions();
|
||||
//END SNIPPET: parseExtension
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void foo() {
|
||||
//START SNIPPET: subExtension
|
||||
Patient patient = new Patient();
|
||||
|
||||
// Add an extension (initially with no contents) to the resource
|
||||
ExtensionDt parent = new ExtensionDt(false, "http://example.com#parent");
|
||||
patient.addUndeclaredExtension(parent);
|
||||
|
||||
// Add two extensions as children to the parent extension
|
||||
ExtensionDt child1 = new ExtensionDt(false, "http://example.com#childOne", new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child1);
|
||||
|
||||
ExtensionDt child2 = new ExtensionDt(false, "http://example.com#childTwo", new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child2);
|
||||
//END SNIPPET: subExtension
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.Identifier.IdentifierUse;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
public class ExtensionsDstu3 {
|
||||
|
||||
public void customType() {
|
||||
|
||||
IGenericClient client = FhirContext.forDstu3().newRestfulGenericClient("http://foo");
|
||||
|
||||
//START SNIPPET: customTypeClientSimple
|
||||
// Create an example patient
|
||||
MyPatient custPatient = new MyPatient();
|
||||
custPatient.addName().setFamily("Smith").addGiven("John");
|
||||
custPatient.setPetName(new StringType("Rover")); // populate the extension
|
||||
|
||||
// Create the resource like normal
|
||||
client.create().resource(custPatient).execute();
|
||||
|
||||
// You can also read the resource back like normal
|
||||
custPatient = client.read().resource(MyPatient.class).withId("123").execute();
|
||||
//END SNIPPET: customTypeClientSimple
|
||||
|
||||
//START SNIPPET: customTypeClientSearch
|
||||
// Perform the search using the custom type
|
||||
Bundle bundle = client
|
||||
.search()
|
||||
.forResource(MyPatient.class)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
// Entries in the return bundle will use the given type
|
||||
MyPatient pat0 = (MyPatient) bundle.getEntry().get(0).getResource();
|
||||
//END SNIPPET: customTypeClientSearch
|
||||
|
||||
//START SNIPPET: customTypeClientSearch2
|
||||
//Perform the search using the custom type
|
||||
bundle = client
|
||||
.history()
|
||||
.onInstance(new IdType("Patient/123"))
|
||||
.andReturnBundle(Bundle.class)
|
||||
.preferResponseType(MyPatient.class)
|
||||
.execute();
|
||||
|
||||
//Entries in the return bundle will use the given type
|
||||
MyPatient historyPatient0 = (MyPatient) bundle.getEntry().get(0).getResource();
|
||||
//END SNIPPET: customTypeClientSearch2
|
||||
|
||||
}
|
||||
|
||||
public void customTypeDeclared() {
|
||||
|
||||
|
||||
//START SNIPPET: customTypeClientDeclared
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Instruct the context that if it receives a resource which
|
||||
// claims to conform to the given profile (by URL), it should
|
||||
// use the MyPatient type to parse this resource
|
||||
ctx.setDefaultTypeForProfile("http://example.com/StructureDefinition/mypatient", MyPatient.class);
|
||||
|
||||
// You can declare as many default types as you like
|
||||
ctx.setDefaultTypeForProfile("http://foo.com/anotherProfile", CustomObservation.class);
|
||||
|
||||
// Create a client
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu3");
|
||||
|
||||
// You can also read the resource back like normal
|
||||
Patient patient = client.read().resource(Patient.class).withId("123").execute();
|
||||
if (patient instanceof MyPatient) {
|
||||
// If the server supplied a resource which declared to conform
|
||||
// to the given profile, MyPatient will have been returned so
|
||||
// process it differently..
|
||||
}
|
||||
|
||||
//END SNIPPET: customTypeClientDeclared
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
|
||||
|
||||
// START SNIPPET: resourceExtension
|
||||
// Create an example patient
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
|
||||
|
||||
// Create an extension
|
||||
Extension ext = new Extension();
|
||||
ext.setUrl("http://example.com/extensions#someext");
|
||||
ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
|
||||
|
||||
// Add the extension to the resource
|
||||
patient.addExtension(ext);
|
||||
//END SNIPPET: resourceExtension
|
||||
|
||||
|
||||
//START SNIPPET: resourceStringExtension
|
||||
// Continuing the example from above, we will add a name to the patient, and then
|
||||
// add an extension to part of that name
|
||||
HumanName name = patient.addName();
|
||||
name.setFamily("Shmoe");
|
||||
|
||||
// Add a new "given name", which is of type String
|
||||
StringType given = name.addGivenElement();
|
||||
given.setValue("Joe");
|
||||
|
||||
// Create an extension and add it to the String
|
||||
Extension givenExt = new Extension("http://examples.com#moreext", new StringType("Hello"));
|
||||
given.addExtension(givenExt);
|
||||
//END SNIPPET: resourceStringExtension
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(output);
|
||||
|
||||
|
||||
//START SNIPPET: parseExtension
|
||||
// Get all extensions (modifier or not) for a given URL
|
||||
List<Extension> resourceExts = patient.getExtensionsByUrl("http://fooextensions.com#exts");
|
||||
|
||||
// Get all non-modifier extensions regardless of URL
|
||||
List<Extension> nonModExts = patient.getExtension();
|
||||
|
||||
//Get all non-modifier extensions regardless of URL
|
||||
List<Extension> modExts = patient.getModifierExtension();
|
||||
//END SNIPPET: parseExtension
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void foo() {
|
||||
//START SNIPPET: subExtension
|
||||
Patient patient = new Patient();
|
||||
|
||||
// Add an extension (initially with no contents) to the resource
|
||||
Extension parent = new Extension("http://example.com#parent");
|
||||
patient.addExtension(parent);
|
||||
|
||||
// Add two extensions as children to the parent extension
|
||||
Extension child1 = new Extension("http://example.com#childOne", new StringType("value1"));
|
||||
parent.addExtension(child1);
|
||||
|
||||
Extension child2 = new Extension("http://example.com#chilwo", new StringType("value1"));
|
||||
parent.addExtension(child2);
|
||||
//END SNIPPET: subExtension
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.NameUseEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
||||
public class FhirContextIntro {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void creatingContext() {
|
||||
// START SNIPPET: creatingContext
|
||||
// Create a context for DSTU2
|
||||
FhirContext ctxDstu2 = FhirContext.forDstu2();
|
||||
|
||||
// Alternately, create a context for R4
|
||||
FhirContext ctxR4 = FhirContext.forR4();
|
||||
// END SNIPPET: creatingContext
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void creatingContextHl7org() {
|
||||
// START SNIPPET: creatingContextHl7org
|
||||
// Create a context for DSTU3
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Working with RI structures is similar to how it works with the HAPI structures
|
||||
org.hl7.fhir.dstu3.model.Patient patient = new org.hl7.fhir.dstu3.model.Patient();
|
||||
patient.addName().addGiven("John").setFamily("Smith");
|
||||
patient.getBirthDateElement().setValueAsString("1998-02-22");
|
||||
|
||||
// Parsing and encoding works the same way too
|
||||
String encoded = ctx.newJsonParser().encodeResourceToString(patient);
|
||||
|
||||
// END SNIPPET: creatingContextHl7org
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws DataFormatException {
|
||||
|
||||
new FhirContextIntro().encodeMsg();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void encodeMsg() throws DataFormatException {
|
||||
FhirContext ctx = new FhirContext(Patient.class, Observation.class);
|
||||
//START SNIPPET: encodeMsg
|
||||
|
||||
/**
|
||||
* FHIR model types in HAPI are simple POJOs. To create a new
|
||||
* one, invoke the default constructor and then
|
||||
* start populating values.
|
||||
*/
|
||||
Patient patient = new Patient();
|
||||
|
||||
// Add an MRN (a patient identifier)
|
||||
IdentifierDt id = patient.addIdentifier();
|
||||
id.setSystem("http://example.com/fictitious-mrns");
|
||||
id.setValue("MRN001");
|
||||
|
||||
// Add a name
|
||||
HumanNameDt name = patient.addName();
|
||||
name.setUse(NameUseEnum.OFFICIAL);
|
||||
name.addFamily("Tester");
|
||||
name.addGiven("John");
|
||||
name.addGiven("Q");
|
||||
|
||||
// We can now use a parser to encode this resource into a string.
|
||||
String encoded = ctx.newXmlParser().encodeResourceToString(patient);
|
||||
System.out.println(encoded);
|
||||
//END SNIPPET: encodeMsg
|
||||
|
||||
//START SNIPPET: encodeMsgJson
|
||||
IParser jsonParser = ctx.newJsonParser();
|
||||
jsonParser.setPrettyPrint(true);
|
||||
encoded = jsonParser.encodeResourceToString(patient);
|
||||
System.out.println(encoded);
|
||||
//END SNIPPET: encodeMsgJson
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void fluent() throws DataFormatException {
|
||||
FhirContext ctx = new FhirContext(Patient.class, Observation.class);
|
||||
String encoded;
|
||||
//START SNIPPET: encodeMsgFluent
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("http://example.com/fictitious-mrns").setValue("MRN001");
|
||||
patient.addName().setUse(NameUseEnum.OFFICIAL).addFamily("Tester").addGiven("John").addGiven("Q");
|
||||
|
||||
encoded = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(encoded);
|
||||
//END SNIPPET: encodeMsgFluent
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void parseMsg() {
|
||||
FhirContext ctx = FhirContext.forR4();
|
||||
|
||||
//START SNIPPET: parseMsg
|
||||
// The following is an example Patient resource
|
||||
String msgString = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal</div></text>"
|
||||
+ "<identifier><system value=\"http://orionhealth.com/mrn\" /><value value=\"PRP1660\" /></identifier>"
|
||||
+ "<name><use value=\"official\" /><family value=\"Cardinal\" /><given value=\"John\" /></name>"
|
||||
+ "<gender><coding><system value=\"http://hl7.org/fhir/v3/AdministrativeGender\" /><code value=\"M\" /></coding></gender>"
|
||||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>";
|
||||
|
||||
// The hapi context object is used to create a new XML parser
|
||||
// instance. The parser can then be used to parse (or unmarshall) the
|
||||
// string message into a Patient object
|
||||
IParser parser = ctx.newXmlParser();
|
||||
Patient patient = parser.parseResource(Patient.class, msgString);
|
||||
|
||||
// The patient object has accessor methods to retrieve all of the
|
||||
// data which has been parsed into the instance.
|
||||
String patientId = patient.getIdentifier().get(0).getValue();
|
||||
String familyName = patient.getName().get(0).getFamily().get(0).getValue();
|
||||
String gender = patient.getGender();
|
||||
|
||||
System.out.println(patientId); // PRP1660
|
||||
System.out.println(familyName); // Cardinal
|
||||
System.out.println(gender); // M
|
||||
//END SNIPPET: parseMsg
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.*;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.*;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
public class FhirDataModel {
|
||||
|
||||
public static void datatypes() {
|
||||
// START SNIPPET: datatypes
|
||||
Observation obs = new Observation();
|
||||
|
||||
// These are all equivalent
|
||||
obs.setIssued(new InstantDt(new Date()));
|
||||
obs.setIssued(new Date(), TemporalPrecisionEnum.MILLI);
|
||||
obs.setIssuedWithMillisPrecision(new Date());
|
||||
|
||||
// The InstantDt also lets you work with the instant as a Java Date
|
||||
// object or as a FHIR String.
|
||||
Date date = obs.getIssuedElement().getValue(); // A date object
|
||||
String dateString = obs.getIssuedElement().getValueAsString(); // "2014-03-08T12:59:58.068-05:00"
|
||||
// END SNIPPET: datatypes
|
||||
|
||||
System.out.println(date);
|
||||
System.out.println(dateString);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void nonNull() {
|
||||
// START SNIPPET: nonNull
|
||||
Observation observation = new Observation();
|
||||
|
||||
// None of these calls will not return null, but instead create their
|
||||
// respective
|
||||
// child elements.
|
||||
List<IdentifierDt> identifierList = observation.getIdentifier();
|
||||
CodeableConceptDt code = observation.getCode();
|
||||
StringDt textElement = observation.getCode().getTextElement();
|
||||
|
||||
// DateTimeDt is a FHIR primitive however, so the following will return
|
||||
// null
|
||||
// unless a value has been placed there.
|
||||
Date active = observation.addIdentifier().getPeriod().getStartElement().getValue();
|
||||
// END SNIPPET: nonNull
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void codes() {
|
||||
// START SNIPPET: codes
|
||||
Patient patient = new Patient();
|
||||
|
||||
// You can set this code using a String if you want. Note that
|
||||
// for "closed" valuesets (such as the one used for Patient.gender)
|
||||
// you must use one of the strings defined by the FHIR specification.
|
||||
// You must not define your own.
|
||||
patient.getGenderElement().setValue("male");
|
||||
|
||||
// HAPI also provides Java enumerated types which make it easier to
|
||||
// deal with coded values. This code achieves the exact same result
|
||||
// as the code above.
|
||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||
|
||||
// You can also retrieve coded values the same way
|
||||
String genderString = patient.getGenderElement().getValueAsString();
|
||||
AdministrativeGenderEnum genderEnum = patient.getGenderElement().getValueAsEnum();
|
||||
|
||||
// The following is a shortcut to create
|
||||
patient.setMaritalStatus(MaritalStatusCodesEnum.M);
|
||||
// END SNIPPET: codes
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void codeableConcepts() {
|
||||
// START SNIPPET: codeableConcepts
|
||||
Patient patient = new Patient();
|
||||
|
||||
// Coded types can naturally be set using plain strings
|
||||
CodingDt statusCoding = patient.getMaritalStatus().addCoding();
|
||||
statusCoding.setSystem("http://hl7.org/fhir/v3/MaritalStatus");
|
||||
statusCoding.setCode("M");
|
||||
statusCoding.setDisplay("Married");
|
||||
|
||||
// You could add a second coding to the field if needed too. This
|
||||
// can be useful if you want to convey the concept using different
|
||||
// codesystems.
|
||||
CodingDt secondStatus = patient.getMaritalStatus().addCoding();
|
||||
secondStatus.setCode("H");
|
||||
secondStatus.setSystem("http://example.com#maritalStatus");
|
||||
secondStatus.setDisplay("Happily Married");
|
||||
|
||||
// CodeableConcept also has a text field meant to convey
|
||||
// a user readable version of the concepts it conveys.
|
||||
patient.getMaritalStatus().setText("Happily Married");
|
||||
|
||||
// There are also accessors for retrieving values
|
||||
String firstCode = patient.getMaritalStatus().getCoding().get(0).getCode();
|
||||
String secondCode = patient.getMaritalStatus().getCoding().get(1).getCode();
|
||||
// END SNIPPET: codeableConcepts
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void codeableConceptEnums() {
|
||||
// START SNIPPET: codeableConceptEnums
|
||||
Patient patient = new Patient();
|
||||
|
||||
// Set the CodeableConcept's first coding to use the code
|
||||
// and codesystem associated with the M value.
|
||||
patient.setMaritalStatus(MaritalStatusCodesEnum.M);
|
||||
|
||||
// If you need to set other fields (such as the display name) after
|
||||
// using the Enum type, you may still do so.
|
||||
patient.getMaritalStatus().getCodingFirstRep().setDisplay("Married");
|
||||
patient.getMaritalStatus().getCodingFirstRep().setVersion("1.0");
|
||||
patient.getMaritalStatus().getCodingFirstRep().setUserSelected(true);
|
||||
|
||||
// You can use accessors to retrieve values from CodeableConcept fields
|
||||
|
||||
// Returns "M"
|
||||
String code = patient.getMaritalStatus().getCodingFirstRep().getCode();
|
||||
|
||||
// Returns "http://hl7.org/fhir/v3/MaritalStatus". This value was also
|
||||
// populated via the enum above.
|
||||
String codeSystem = patient.getMaritalStatus().getCodingFirstRep().getCode();
|
||||
|
||||
// In many cases, Enum types can be used to retrieve values as well. Note that
|
||||
// the setter takes a single type, but the getter returns a Set, because the
|
||||
// field can technicaly contain more than one code and codesystem. BE CAREFUL
|
||||
// when using this method however, as no Enum will be returned in the case
|
||||
// that the field contains only a code other than the ones defined by the Enum.
|
||||
Set<MaritalStatusCodesEnum> status = patient.getMaritalStatus().getValueAsEnum();
|
||||
// END SNIPPET: codeableConceptEnums
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
tmp();
|
||||
|
||||
|
||||
datatypes();
|
||||
|
||||
// START SNIPPET: observation
|
||||
// Create an Observation instance
|
||||
Observation observation = new Observation();
|
||||
|
||||
// Give the observation a status
|
||||
observation.setStatus(ObservationStatusEnum.FINAL);
|
||||
|
||||
// Give the observation a code (what kind of observation is this)
|
||||
CodingDt coding = observation.getCode().addCoding();
|
||||
coding.setCode("29463-7").setSystem("http://loinc.org").setDisplay("Body Weight");
|
||||
|
||||
// Create a quantity datatype
|
||||
QuantityDt value = new QuantityDt();
|
||||
value.setValue(83.9).setSystem("http://unitsofmeasure.org").setCode("kg");
|
||||
observation.setValue(value);
|
||||
|
||||
// Set the reference range
|
||||
SimpleQuantityDt low = new SimpleQuantityDt();
|
||||
low.setValue(45).setSystem("http://unitsofmeasure.org").setCode("kg");
|
||||
observation.getReferenceRangeFirstRep().setLow(low);
|
||||
SimpleQuantityDt high = new SimpleQuantityDt();
|
||||
low.setValue(90).setSystem("http://unitsofmeasure.org").setCode("kg");
|
||||
observation.getReferenceRangeFirstRep().setHigh(high);
|
||||
|
||||
// END SNIPPET: observation
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void tmp() {
|
||||
// Create a FHIR Context
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Create a client
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
// Read a patient with the given ID
|
||||
Patient patient = client
|
||||
.read()
|
||||
.resource(Patient.class)
|
||||
.withId("952975")
|
||||
.execute();
|
||||
|
||||
// Print the patient's name
|
||||
String string = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(string);
|
||||
|
||||
}
|
||||
|
||||
public void namesHard() {
|
||||
// START SNIPPET: namesHard
|
||||
Patient patient = new Patient();
|
||||
HumanNameDt name = patient.addName();
|
||||
StringDt family = name.addFamily();
|
||||
family.setValue("Smith");
|
||||
StringDt firstName = name.addGiven();
|
||||
firstName.setValue("Rob");
|
||||
StringDt secondName = name.addGiven();
|
||||
secondName.setValue("Bruce");
|
||||
// END SNIPPET: namesHard
|
||||
}
|
||||
|
||||
public void namesEasy() {
|
||||
// START SNIPPET: namesEasy
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("Smith").addGiven("Rob").addGiven("Bruce");
|
||||
// END SNIPPET: namesEasy
|
||||
}
|
||||
|
||||
}
|
|
@ -1,536 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.PerformanceOptionsEnum;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.*;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.primitive.*;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||
|
||||
public class GenericClientExample {
|
||||
public static void deferModelScanning() {
|
||||
// START SNIPPET: deferModelScanning
|
||||
// Create a context and configure it for deferred child scanning
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
ctx.setPerformanceOptions(PerformanceOptionsEnum.DEFERRED_MODEL_SCANNING);
|
||||
|
||||
// Now create a client and use it
|
||||
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
// END SNIPPET: deferModelScanning
|
||||
}
|
||||
|
||||
public static void performance() {
|
||||
// START SNIPPET: dontValidate
|
||||
// Create a context
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Disable server validation (don't pull the server's metadata first)
|
||||
ctx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.NEVER);
|
||||
|
||||
// Now create a client and use it
|
||||
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
// END SNIPPET: dontValidate
|
||||
}
|
||||
|
||||
public static void simpleExample() {
|
||||
// START SNIPPET: simple
|
||||
// We're connecting to a DSTU1 compliant server in this example
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String serverBase = "http://fhirtest.uhn.ca/baseDstu2";
|
||||
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
|
||||
// Perform a search
|
||||
Bundle results = client
|
||||
.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.FAMILY.matches().value("duck"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
|
||||
System.out.println("Found " + results.getEntry().size() + " patients named 'duck'");
|
||||
// END SNIPPET: simple
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void fluentSearch() {
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
{
|
||||
// START SNIPPET: create
|
||||
Patient patient = new Patient();
|
||||
// ..populate the patient object..
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("12345");
|
||||
patient.addName().addFamily("Smith").addGiven("John");
|
||||
|
||||
// Invoke the server create method (and send pretty-printed JSON
|
||||
// encoding to the server
|
||||
// instead of the default which is non-pretty printed XML)
|
||||
MethodOutcome outcome = client.create()
|
||||
.resource(patient)
|
||||
.prettyPrint()
|
||||
.encodedJson()
|
||||
.execute();
|
||||
|
||||
// The MethodOutcome object will contain information about the
|
||||
// response from the server, including the ID of the created
|
||||
// resource, the OperationOutcome response, etc. (assuming that
|
||||
// any of these things were provided by the server! They may not
|
||||
// always be)
|
||||
IdDt id = (IdDt) outcome.getId();
|
||||
System.out.println("Got ID: " + id.getValue());
|
||||
// END SNIPPET: create
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: createConditional
|
||||
// One form
|
||||
MethodOutcome outcome = client.create()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
// Another form
|
||||
MethodOutcome outcome2 = client.create()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
|
||||
// This will return Boolean.TRUE if the server responded with an HTTP 201 created,
|
||||
// otherwise it will return null.
|
||||
Boolean created = outcome.getCreated();
|
||||
|
||||
// The ID of the created, or the pre-existing resource
|
||||
IdDt id = (IdDt) outcome.getId();
|
||||
// END SNIPPET: createConditional
|
||||
}
|
||||
{
|
||||
// START SNIPPET: validate
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("http://hospital.com").setValue("123445");
|
||||
patient.addName().addFamily("Smith").addGiven("John");
|
||||
|
||||
// Validate the resource
|
||||
MethodOutcome outcome = client.validate()
|
||||
.resource(patient)
|
||||
.execute();
|
||||
|
||||
// The returned object will contain an operation outcome resource
|
||||
OperationOutcome oo = (OperationOutcome) outcome.getOperationOutcome();
|
||||
|
||||
// If the OperationOutcome has any issues with a severity of ERROR or SEVERE,
|
||||
// the validation failed.
|
||||
for (Issue nextIssue : oo.getIssue()) {
|
||||
if (nextIssue.getSeverityElement().getValueAsEnum().ordinal() >= IssueSeverityEnum.ERROR.ordinal()) {
|
||||
System.out.println("We failed validation!");
|
||||
}
|
||||
}
|
||||
// END SNIPPET: validate
|
||||
}
|
||||
{
|
||||
// START SNIPPET: update
|
||||
Patient patient = new Patient();
|
||||
// ..populate the patient object..
|
||||
patient.addIdentifier().setSystem("urn:system").setValue("12345");
|
||||
patient.addName().addFamily("Smith").addGiven("John");
|
||||
|
||||
// To update a resource, it should have an ID set (if the resource
|
||||
// object
|
||||
// comes from the results of a previous read or search, it will already
|
||||
// have one though)
|
||||
patient.setId("Patient/123");
|
||||
|
||||
// Invoke the server update method
|
||||
MethodOutcome outcome = client.update()
|
||||
.resource(patient)
|
||||
.execute();
|
||||
|
||||
// The MethodOutcome object will contain information about the
|
||||
// response from the server, including the ID of the created
|
||||
// resource, the OperationOutcome response, etc. (assuming that
|
||||
// any of these things were provided by the server! They may not
|
||||
// always be)
|
||||
IdDt id = (IdDt) outcome.getId();
|
||||
System.out.println("Got ID: " + id.getValue());
|
||||
// END SNIPPET: update
|
||||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
// START SNIPPET: updateConditional
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.update()
|
||||
.resource(patient)
|
||||
.conditional()
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: updateConditional
|
||||
}
|
||||
{
|
||||
// START SNIPPET: etagupdate
|
||||
// First, let's retrive the latest version of a resource
|
||||
// from the server
|
||||
Patient patient = client.read().resource(Patient.class).withId("123").execute();
|
||||
|
||||
// If the server is a version aware server, we should now know the latest version
|
||||
// of the resource
|
||||
System.out.println("Version ID: " + patient.getId().getVersionIdPart());
|
||||
|
||||
// Now let's make a change to the resource
|
||||
patient.setGender(AdministrativeGenderEnum.FEMALE);
|
||||
|
||||
// Invoke the server update method - Because the resource has
|
||||
// a version, it will be included in the request sent to
|
||||
// the server
|
||||
try {
|
||||
MethodOutcome outcome = client
|
||||
.update()
|
||||
.resource(patient)
|
||||
.execute();
|
||||
} catch (PreconditionFailedException e) {
|
||||
// If we get here, the latest version has changed
|
||||
// on the server so our update failed.
|
||||
}
|
||||
// END SNIPPET: etagupdate
|
||||
}
|
||||
{
|
||||
// START SNIPPET: conformance
|
||||
// Retrieve the server's conformance statement and print its
|
||||
// description
|
||||
Conformance conf = client.fetchConformance().ofType(Conformance.class).execute();
|
||||
System.out.println(conf.getDescriptionElement().getValue());
|
||||
// END SNIPPET: conformance
|
||||
}
|
||||
{
|
||||
// START SNIPPET: delete
|
||||
IBaseOperationOutcome resp = client.delete().resourceById(new IdDt("Patient", "1234")).execute();
|
||||
|
||||
// outcome may be null if the server didn't return one
|
||||
if (resp != null) {
|
||||
OperationOutcome outcome = (OperationOutcome) resp;
|
||||
System.out.println(outcome.getIssueFirstRep().getDetailsElement().getValue());
|
||||
}
|
||||
// END SNIPPET: delete
|
||||
}
|
||||
{
|
||||
// START SNIPPET: deleteConditional
|
||||
client.delete()
|
||||
.resourceConditionalByUrl("Patient?identifier=system%7C00001")
|
||||
.execute();
|
||||
|
||||
client.delete()
|
||||
.resourceConditionalByType("Patient")
|
||||
.where(Patient.IDENTIFIER.exactly().systemAndIdentifier("system", "00001"))
|
||||
.execute();
|
||||
// END SNIPPET: deleteConditional
|
||||
}
|
||||
{
|
||||
// START SNIPPET: search
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.BIRTHDATE.beforeOrEquals().day("2011-01-01"))
|
||||
.and(Patient.CAREPROVIDER.hasChainedProperty(Organization.NAME.matches().value("Health")))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: search
|
||||
|
||||
// START SNIPPET: searchOr
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.FAMILY.matches().values("Smith", "Smyth"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchOr
|
||||
|
||||
// START SNIPPET: searchAnd
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.ADDRESS.matches().values("Toronto"))
|
||||
.and(Patient.ADDRESS.matches().values("Ontario"))
|
||||
.and(Patient.ADDRESS.matches().values("Canada"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchAnd
|
||||
|
||||
// START SNIPPET: searchCompartment
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.withIdAndCompartment("123", "condition")
|
||||
.where(Patient.ADDRESS.matches().values("Toronto"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchCompartment
|
||||
|
||||
// START SNIPPET: searchUrl
|
||||
String searchUrl = "http://example.com/base/Patient?identifier=foo";
|
||||
|
||||
// Search URL can also be a relative URL in which case the client's base
|
||||
// URL will be added to it
|
||||
searchUrl = "Patient?identifier=foo";
|
||||
|
||||
response = client.search()
|
||||
.byUrl(searchUrl)
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchUrl
|
||||
|
||||
// START SNIPPET: searchSubsetSummary
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.ADDRESS.matches().values("Toronto"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.summaryMode(SummaryEnum.TRUE)
|
||||
.execute();
|
||||
// END SNIPPET: searchSubsetSummary
|
||||
|
||||
// START SNIPPET: searchSubsetElements
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.ADDRESS.matches().values("Toronto"))
|
||||
.returnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.elementsSubset("identifier", "name") // only include the identifier and name
|
||||
.execute();
|
||||
// END SNIPPET: searchSubsetElements
|
||||
|
||||
// START SNIPPET: searchAdv
|
||||
response = client.search()
|
||||
.forResource(Patient.class)
|
||||
.encodedJson()
|
||||
.where(Patient.BIRTHDATE.beforeOrEquals().day("2012-01-22"))
|
||||
.and(Patient.BIRTHDATE.after().day("2011-01-01"))
|
||||
.withTag("http://acme.org/codes", "needs-review")
|
||||
.include(Patient.INCLUDE_ORGANIZATION.asRecursive())
|
||||
.include(Patient.INCLUDE_CAREPROVIDER.asNonRecursive())
|
||||
.revInclude(Provenance.INCLUDE_TARGET)
|
||||
.lastUpdated(new DateRangeParam("2011-01-01", null))
|
||||
.sort().ascending(Patient.BIRTHDATE)
|
||||
.sort().descending(Patient.NAME).limitTo(123)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchAdv
|
||||
|
||||
// START SNIPPET: searchPost
|
||||
response = client.search()
|
||||
.forResource("Patient")
|
||||
.where(Patient.NAME.matches().value("Tester"))
|
||||
.usingStyle(SearchStyleEnum.POST)
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchPost
|
||||
|
||||
// START SNIPPET: searchComposite
|
||||
response = client.search()
|
||||
.forResource("Observation")
|
||||
.where(Observation.CODE_VALUE_DATE
|
||||
.withLeft(Observation.CODE.exactly().code("FOO$BAR"))
|
||||
.withRight(Observation.VALUE_DATE.exactly().day("2001-01-01")))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: searchComposite
|
||||
}
|
||||
{
|
||||
// START SNIPPET: transaction
|
||||
List<IResource> resources = new ArrayList<IResource>();
|
||||
// .. populate this list - note that you can also pass in a populated
|
||||
// Bundle if you want to create one manually ..
|
||||
|
||||
List<IBaseResource> response = client.transaction().withResources(resources).execute();
|
||||
// END SNIPPET: transaction
|
||||
}
|
||||
|
||||
{
|
||||
// START SNIPPET: read
|
||||
// search for patient 123
|
||||
Patient patient = client.read()
|
||||
.resource(Patient.class)
|
||||
.withId("123")
|
||||
.execute();
|
||||
// END SNIPPET: read
|
||||
}
|
||||
{
|
||||
// START SNIPPET: vread
|
||||
// search for patient 123 (specific version 888)
|
||||
Patient patient = client.read()
|
||||
.resource(Patient.class)
|
||||
.withIdAndVersion("123", "888")
|
||||
.execute();
|
||||
// END SNIPPET: vread
|
||||
}
|
||||
{
|
||||
// START SNIPPET: readabsolute
|
||||
// search for patient 123 on example.com
|
||||
String url = "http://example.com/fhir/Patient/123";
|
||||
Patient patient = client.read()
|
||||
.resource(Patient.class)
|
||||
.withUrl(url)
|
||||
.execute();
|
||||
// END SNIPPET: readabsolute
|
||||
}
|
||||
|
||||
{
|
||||
// START SNIPPET: etagread
|
||||
// search for patient 123
|
||||
Patient patient = client.read()
|
||||
.resource(Patient.class)
|
||||
.withId("123")
|
||||
.ifVersionMatches("001").returnNull()
|
||||
.execute();
|
||||
if (patient == null) {
|
||||
// resource has not changed
|
||||
}
|
||||
// END SNIPPET: etagread
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void history() {
|
||||
IGenericClient client = FhirContext.forDstu2().newRestfulGenericClient("");
|
||||
{
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response;
|
||||
// START SNIPPET: historyDstu2
|
||||
response = client
|
||||
.history()
|
||||
.onServer()
|
||||
.andReturnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.execute();
|
||||
// END SNIPPET: historyDstu2
|
||||
}
|
||||
{
|
||||
ca.uhn.fhir.model.dstu2.resource.Bundle response;
|
||||
// START SNIPPET: historyFeatures
|
||||
response = client
|
||||
.history()
|
||||
.onServer()
|
||||
.andReturnBundle(ca.uhn.fhir.model.dstu2.resource.Bundle.class)
|
||||
.since(new InstantDt("2012-01-01T12:22:32.038Z"))
|
||||
.count(100)
|
||||
.execute();
|
||||
// END SNIPPET: historyFeatures
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
paging();
|
||||
}
|
||||
private static void paging() {
|
||||
{
|
||||
// START SNIPPET: searchPaging
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
// Perform a search
|
||||
Bundle resultBundle = client.search()
|
||||
.forResource(Patient.class)
|
||||
.where(Patient.NAME.matches().value("Smith"))
|
||||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
if (resultBundle.getLink(Bundle.LINK_NEXT) != null) {
|
||||
|
||||
// load next page
|
||||
Bundle nextPage = client.loadPage().next(resultBundle).execute();
|
||||
}
|
||||
// END SNIPPET: searchPaging
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void operationHttpGet() {
|
||||
// START SNIPPET: operationHttpGet
|
||||
// Create a client to talk to the HeathIntersections server
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client
|
||||
.operation()
|
||||
.onInstance(new IdDt("Patient", "1"))
|
||||
.named("$everything")
|
||||
.withParameters(inParams)
|
||||
.useHttpGet() // Use HTTP GET instead of POST
|
||||
.execute();
|
||||
// END SNIPPET: operationHttpGet
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void operation() {
|
||||
// START SNIPPET: operation
|
||||
// Create a client to talk to the HeathIntersections server
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Create the input parameters to pass to the server
|
||||
Parameters inParams = new Parameters();
|
||||
inParams.addParameter().setName("start").setValue(new DateDt("2001-01-01"));
|
||||
inParams.addParameter().setName("end").setValue(new DateDt("2015-03-01"));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client
|
||||
.operation()
|
||||
.onInstance(new IdDt("Patient", "1"))
|
||||
.named("$everything")
|
||||
.withParameters(inParams)
|
||||
.execute();
|
||||
|
||||
/*
|
||||
* Note that the $everything operation returns a Bundle instead
|
||||
* of a Parameters resource. The client operation methods return a
|
||||
* Parameters instance however, so HAPI creates a Parameters object
|
||||
* with a single parameter containing the value.
|
||||
*/
|
||||
Bundle responseBundle = (Bundle) outParams.getParameter().get(0).getResource();
|
||||
|
||||
// Print the response bundle
|
||||
System.out.println(ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(responseBundle));
|
||||
// END SNIPPET: operation
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void operationNoIn() {
|
||||
// START SNIPPET: operationNoIn
|
||||
// Create a client to talk to the HeathIntersections server
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhir-dev.healthintersections.com.au/open");
|
||||
client.registerInterceptor(new LoggingInterceptor(true));
|
||||
|
||||
// Invoke $everything on "Patient/1"
|
||||
Parameters outParams = client
|
||||
.operation()
|
||||
.onInstance(new IdDt("Patient", "1"))
|
||||
.named("$everything")
|
||||
.withNoParameters(Parameters.class) // No input parameters
|
||||
.execute();
|
||||
// END SNIPPET: operationNoIn
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
||||
import org.hl7.fhir.r4.model.Enumerations;
|
||||
import org.hl7.fhir.r4.model.SearchParameter;
|
||||
|
||||
public class GenomicsUploader {
|
||||
|
||||
public static void main(String[] theArgs) {
|
||||
FhirContext ctx = FhirContext.forR4();
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseR4");
|
||||
client.registerInterceptor(new LoggingInterceptor(false));
|
||||
|
||||
SearchParameter dnaSequenceVariantName = new SearchParameter();
|
||||
dnaSequenceVariantName.setId("SearchParameter/dnaSequenceVariantName");
|
||||
dnaSequenceVariantName.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
dnaSequenceVariantName.addBase("Observation");
|
||||
dnaSequenceVariantName.setCode("dnaSequenceVariantName");
|
||||
dnaSequenceVariantName.setType(Enumerations.SearchParamType.TOKEN);
|
||||
dnaSequenceVariantName.setTitle("DNASequenceVariantName");
|
||||
dnaSequenceVariantName.setExpression("Observation.extension('http://hl7.org/fhir/StructureDefinition/observation-geneticsDNASequenceVariantName')");
|
||||
dnaSequenceVariantName.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
client.update().resource(dnaSequenceVariantName).execute();
|
||||
|
||||
SearchParameter dNAVariantId = new SearchParameter();
|
||||
dNAVariantId.setId("SearchParameter/dNAVariantId");
|
||||
dNAVariantId.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
dNAVariantId.addBase("Observation");
|
||||
dNAVariantId.setCode("dnaVariantId");
|
||||
dNAVariantId.setType(Enumerations.SearchParamType.TOKEN);
|
||||
dNAVariantId.setTitle("DNAVariantId");
|
||||
dNAVariantId.setExpression("Observation.extension('http://hl7.org/fhir/StructureDefinition/observation-geneticsDNAVariantId')");
|
||||
dNAVariantId.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
client.update().resource(dNAVariantId).execute();
|
||||
|
||||
SearchParameter gene = new SearchParameter();
|
||||
gene.setId("SearchParameter/gene");
|
||||
gene.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
gene.addBase("Observation");
|
||||
gene.setCode("gene");
|
||||
gene.setType(Enumerations.SearchParamType.TOKEN);
|
||||
gene.setTitle("Gene");
|
||||
gene.setExpression("Observation.extension('http://hl7.org/fhir/StructureDefinition/observation-geneticsGene')");
|
||||
gene.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
client.update().resource(gene).execute();
|
||||
|
||||
SearchParameter alleleName = new SearchParameter();
|
||||
alleleName.setId("SearchParameter/alleleName");
|
||||
alleleName.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
alleleName.addBase("Observation");
|
||||
alleleName.setCode("alleleName");
|
||||
alleleName.setType(Enumerations.SearchParamType.TOKEN);
|
||||
alleleName.setTitle("AlleleName");
|
||||
alleleName.setExpression("Observation.extension('http://hl7.org/fhir/StructureDefinition/observation-geneticsAlleleName')");
|
||||
alleleName.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
|
||||
client.update().resource(alleleName).execute();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package example;
|
||||
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.impl.client.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
public class HttpProxy {
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* This is out ot date - Just keeping
|
||||
* it in case it's helpful...
|
||||
*/
|
||||
final String authUser = "username";
|
||||
final String authPassword = "password";
|
||||
CredentialsProvider credsProvider = new BasicCredentialsProvider();
|
||||
credsProvider.setCredentials(new AuthScope("10.10.10.10", 8080),
|
||||
new UsernamePasswordCredentials(authUser, authPassword));
|
||||
|
||||
HttpHost myProxy = new HttpHost("10.10.10.10", 8080);
|
||||
|
||||
|
||||
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
|
||||
clientBuilder
|
||||
.setProxy(myProxy)
|
||||
.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy())
|
||||
.setDefaultCredentialsProvider(credsProvider)
|
||||
.disableCookieManagement();
|
||||
CloseableHttpClient httpClient = clientBuilder.build();
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String serverBase = "http://spark.furore.com/fhir/";
|
||||
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
||||
IGenericClient client = ctx.newRestfulGenericClient(serverBase);
|
||||
|
||||
IdDt id = new IdDt("Patient", "123");
|
||||
client.read(Patient.class, id);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
* All RESTful clients must be an interface which extends IBasicClient
|
||||
*/
|
||||
public interface IRestfulClient extends IBasicClient {
|
||||
|
||||
/**
|
||||
* The "@Read" annotation indicates that this method supports the
|
||||
* read operation. Read operations should return a single resource
|
||||
* instance.
|
||||
*
|
||||
* @param theId
|
||||
* The read operation takes one parameter, which must be of type
|
||||
* IdDt and must be annotated with the "@Read.IdParam" annotation.
|
||||
* @return
|
||||
* Returns a resource matching this identifier, or null if none exists.
|
||||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@IdParam IdDt theId);
|
||||
|
||||
/**
|
||||
* The "@Search" annotation indicates that this method supports the
|
||||
* search operation. You may have many different methods annotated with
|
||||
* this annotation, to support many different search criteria. This
|
||||
* example searches by family name.
|
||||
*
|
||||
* @param theIdentifier
|
||||
* This operation takes one parameter which is the search criteria. It is
|
||||
* annotated with the "@Required" annotation. This annotation takes one argument,
|
||||
* a string containing the name of the search criteria. The datatype here
|
||||
* is StringDt, but there are other possible parameter types depending on the
|
||||
* specific search criteria.
|
||||
* @return
|
||||
* This method returns a list of Patients. This list may contain multiple
|
||||
* matching resources, or it may also be empty.
|
||||
*/
|
||||
@Search()
|
||||
public List<Patient> getPatient(@RequiredParam(name = Patient.SP_FAMILY) StringDt theFamilyName);
|
||||
|
||||
}
|
||||
//END SNIPPET: provider
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.provider.dstu2.Dstu2BundleFactory;
|
||||
|
||||
public class IncludesExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
testSearchForPatients();
|
||||
}
|
||||
|
||||
private static void testSearchForPatients() {
|
||||
List<IBaseResource> resources = new IncludesExamples().searchForPatients();
|
||||
|
||||
// Create a bundle with both
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
Dstu2BundleFactory bf = new Dstu2BundleFactory(ctx);
|
||||
bf.addRootPropertiesToBundle(null, null, null, null, null, resources.size(), BundleTypeEnum.SEARCHSET, null);
|
||||
bf.addResourcesToBundle(new ArrayList<>(resources), BundleTypeEnum.SEARCHSET, null, null, null);
|
||||
IBaseResource b = bf.getResourceBundle();
|
||||
|
||||
// Encode the bundle
|
||||
String encoded = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(b);
|
||||
System.out.println(encoded);
|
||||
}
|
||||
|
||||
// START SNIPPET: addIncludes
|
||||
@Search
|
||||
private List<IBaseResource> searchForPatients() {
|
||||
// Create an organization
|
||||
Organization org = new Organization();
|
||||
org.setId("Organization/65546");
|
||||
org.setName("Test Organization");
|
||||
|
||||
// Create a patient
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1333");
|
||||
patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
|
||||
patient.getManagingOrganization().setResource(org);
|
||||
|
||||
// Here we return only the patient object, which has links to other resources
|
||||
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
|
||||
retVal.add(patient);
|
||||
return retVal;
|
||||
}
|
||||
// END SNIPPET: addIncludes
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jaxrs.client.JaxRsRestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
@SuppressWarnings(value= {"serial"})
|
||||
public class JaxRsClient {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//START SNIPPET: createClient
|
||||
|
||||
// Create a client
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Create an instance of the JAX RS client factory and
|
||||
// set it on the context
|
||||
JaxRsRestfulClientFactory clientFactory = new JaxRsRestfulClientFactory(ctx);
|
||||
ctx.setRestfulClientFactory(clientFactory);
|
||||
|
||||
// This client uses JAX-RS!
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu2");
|
||||
|
||||
//END SNIPPET: createClient
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.ejb.EJB;
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsConformanceProvider;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
/**
|
||||
* Conformance Rest Service
|
||||
*
|
||||
* @author Peter Van Houte
|
||||
*/
|
||||
// START SNIPPET: jax-rs-conformance
|
||||
@Path("")
|
||||
@Stateless
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class JaxRsConformanceProvider extends AbstractJaxRsConformanceProvider {
|
||||
|
||||
@EJB
|
||||
private JaxRsPatientRestProvider provider;
|
||||
|
||||
public JaxRsConformanceProvider() {
|
||||
super("My Server Description", "My Server Name", "My Server Version");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> getProviders() {
|
||||
ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider> map = new ConcurrentHashMap<Class<? extends IResourceProvider>, IResourceProvider>();
|
||||
map.put(JaxRsConformanceProvider.class, this);
|
||||
map.put(JaxRsPatientRestProvider.class, provider);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
// END SNIPPET: jax-rs-conformance
|
|
@ -1,68 +0,0 @@
|
|||
package example;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.ejb.Stateless;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsResourceProvider;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
|
||||
/**
|
||||
* A demo JaxRs Patient Rest Provider
|
||||
*/
|
||||
@Local
|
||||
@Stateless
|
||||
// START SNIPPET: jax-rs-provider-construction
|
||||
@Path("/Patient")
|
||||
@Produces({ MediaType.APPLICATION_JSON, Constants.CT_FHIR_JSON, Constants.CT_FHIR_XML })
|
||||
public class JaxRsPatientRestProvider extends AbstractJaxRsResourceProvider<Patient> {
|
||||
|
||||
public JaxRsPatientRestProvider() {
|
||||
super(JaxRsPatientRestProvider.class);
|
||||
}
|
||||
// END SNIPPET: jax-rs-provider-construction
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
|
||||
@Create
|
||||
public MethodOutcome create(@ResourceParam final Patient patient, @ConditionalUrlParam String theConditional) {
|
||||
// create the patient ...
|
||||
return new MethodOutcome(new IdDt(1L)).setCreated(true);
|
||||
}
|
||||
|
||||
// START SNIPPET: jax-rs-provider-operation
|
||||
@GET
|
||||
@Path("/{id}/$someCustomOperation")
|
||||
public Response someCustomOperationUsingGet(@PathParam("id") String id, String resource) throws Exception {
|
||||
return customOperation(resource, RequestTypeEnum.GET, id, "$someCustomOperation",
|
||||
RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
@Operation(name = "someCustomOperation", idempotent = true, returnParameters = {
|
||||
@OperationParam(name = "return", type = StringDt.class) })
|
||||
public Parameters someCustomOperation(@IdParam IdDt myId, @OperationParam(name = "dummy") StringDt dummyInput) {
|
||||
Parameters parameters = new Parameters();
|
||||
parameters.addParameter().setName("return").setValue(new StringDt("My Dummy Result"));
|
||||
return parameters;
|
||||
}
|
||||
// END SNIPPET: jax-rs-provider-operation
|
||||
|
||||
@POST
|
||||
@Path("/{id}/$someCustomOperation")
|
||||
public Response someCustomOperationUsingPost(@PathParam("id") String id, String resource) throws Exception {
|
||||
return customOperation(resource, RequestTypeEnum.POST, id, "$someCustomOperation",
|
||||
RestOperationTypeEnum.EXTENDED_OPERATION_INSTANCE);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.tenant.UrlBaseTenantIdentificationStrategy;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
public class Multitenancy {
|
||||
|
||||
//START SNIPPET: enableUrlBaseTenantIdentificationStrategy
|
||||
public class MyServer extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
|
||||
setTenantIdentificationStrategy(new UrlBaseTenantIdentificationStrategy());
|
||||
|
||||
// ... do other initialization ...
|
||||
}
|
||||
}
|
||||
//END SNIPPET: enableUrlBaseTenantIdentificationStrategy
|
||||
|
||||
//START SNIPPET: resourceProvider
|
||||
public class MyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Read
|
||||
public Patient read(RequestDetails theRequestDetails, @IdParam IdType theId) {
|
||||
|
||||
String tenantId = theRequestDetails.getTenantId();
|
||||
String resourceId = theId.getIdPart();
|
||||
|
||||
// Use these two values to fetch the patient
|
||||
|
||||
return new Patient();
|
||||
}
|
||||
}
|
||||
|
||||
//END SNIPPET: resourceProvider
|
||||
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
package example;
|
||||
|
||||
//START SNIPPET: patientDef
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.DateTimeType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
* Definition class for adding extensions to the built-in
|
||||
* Patient resource type.
|
||||
*
|
||||
* Note the "profile" attribute below, which indicates the URL/ID of the
|
||||
* profile implemented by this resource. You are not required to supply this,
|
||||
* but if you do it will be automatically populated in the resource meta
|
||||
* tag if the resource is returned by a server.
|
||||
*/
|
||||
@ResourceDef(name="Patient", profile="http://example.com/StructureDefinition/mypatient")
|
||||
public class MyPatient extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Each extension is defined in a field. Any valid HAPI Data Type
|
||||
* can be used for the field type. Note that the [name=""] attribute
|
||||
* in the @Child annotation needs to match the name for the bean accessor
|
||||
* and mutator methods.
|
||||
*/
|
||||
@Child(name="petName")
|
||||
@Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The name of the patient's favourite pet")
|
||||
private StringType myPetName;
|
||||
|
||||
/**
|
||||
* The second example extension uses a List type to provide
|
||||
* repeatable values. Note that a [max=] value has been placed in
|
||||
* the @Child annotation.
|
||||
*
|
||||
* Note also that this extension is a modifier extension
|
||||
*/
|
||||
@Child(name="importantDates", max=Child.MAX_UNLIMITED)
|
||||
@Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
|
||||
@Description(shortDefinition="Some dates of note for this patient")
|
||||
private List<DateTimeType> myImportantDates;
|
||||
|
||||
/**
|
||||
* It is important to override the isEmpty() method, adding a check for any
|
||||
* newly added fields.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(myPetName, myImportantDates);
|
||||
}
|
||||
|
||||
/********
|
||||
* Accessors and mutators follow
|
||||
*
|
||||
* IMPORTANT:
|
||||
* Each extension is required to have an getter/accessor and a stter/mutator.
|
||||
* You are highly recommended to create getters which create instances if they
|
||||
* do not already exist, since this is how the rest of the HAPI FHIR API works.
|
||||
********/
|
||||
|
||||
/** Getter for important dates */
|
||||
public List<DateTimeType> getImportantDates() {
|
||||
if (myImportantDates==null) {
|
||||
myImportantDates = new ArrayList<DateTimeType>();
|
||||
}
|
||||
return myImportantDates;
|
||||
}
|
||||
|
||||
/** Getter for pet name */
|
||||
public StringType getPetName() {
|
||||
if (myPetName == null) {
|
||||
myPetName = new StringType();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
/** Setter for important dates */
|
||||
public void setImportantDates(List<DateTimeType> theImportantDates) {
|
||||
myImportantDates = theImportantDates;
|
||||
}
|
||||
|
||||
/** Setter for pet name */
|
||||
public void setPetName(StringType thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: patientDef
|
|
@ -1,86 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
||||
public class MyPatientUse {
|
||||
|
||||
@ResourceDef()
|
||||
public static class MyPatient extends Patient {
|
||||
|
||||
@Child(name="petName")
|
||||
@Extension(url="http://example.com/dontuse#petname", definedLocally=false, isModifier=false)
|
||||
@Description(shortDefinition="The name of the patient's favourite pet")
|
||||
private StringDt myPetName;
|
||||
|
||||
public StringDt getPetName() {
|
||||
if(myPetName==null) {
|
||||
myPetName = new StringDt();
|
||||
}
|
||||
return myPetName;
|
||||
}
|
||||
|
||||
public void setPetName(StringDt thePetName) {
|
||||
myPetName = thePetName;
|
||||
}
|
||||
|
||||
public List<DateTimeDt> getImportantDates() {
|
||||
if (myImportantDates==null) {
|
||||
myImportantDates=new ArrayList<DateTimeDt>();
|
||||
}
|
||||
return myImportantDates;
|
||||
}
|
||||
|
||||
public void setImportantDates(List<DateTimeDt> theImportantDates) {
|
||||
myImportantDates = theImportantDates;
|
||||
}
|
||||
|
||||
@Child(name="importantDates", max=Child.MAX_UNLIMITED)
|
||||
@Extension(url="http://example.com/dontuse#importantDates", definedLocally=false, isModifier=true)
|
||||
@Description(shortDefinition="Some dates of note for the patient")
|
||||
private List<DateTimeDt> myImportantDates;
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
//START SNIPPET: patientUse
|
||||
MyPatient patient = new MyPatient();
|
||||
patient.setPetName(new StringDt("Fido"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2010-01-02"));
|
||||
patient.getImportantDates().add(new DateTimeDt("2014-01-26T11:11:11"));
|
||||
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Quincy").addSuffix("Jr");
|
||||
|
||||
IParser p = FhirContext.forDstu2().newXmlParser().setPrettyPrint(true);
|
||||
String messageString = p.encodeResourceToString(patient);
|
||||
|
||||
System.out.println(messageString);
|
||||
//END SNIPPET: patientUse
|
||||
|
||||
//START SNIPPET: patientParse
|
||||
IParser parser = FhirContext.forDstu2().newXmlParser();
|
||||
MyPatient newPatient = parser.parseResource(MyPatient.class, messageString);
|
||||
//END SNIPPET: patientParse
|
||||
|
||||
{
|
||||
FhirContext ctx2 = FhirContext.forDstu2();
|
||||
RuntimeResourceDefinition def = ctx2.getResourceDefinition(patient);
|
||||
System.out.println(ctx2.newXmlParser().setPrettyPrint(true).encodeResourceToString(def.toProfile()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.NarrativeStatusEnum;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Narrative {
|
||||
|
||||
public static void main(String[] args) throws DataFormatException {
|
||||
|
||||
//START SNIPPET: example1
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setSystem("urn:foo").setValue("7000135");
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Edward");
|
||||
patient.addAddress().addLine("742 Evergreen Terrace").setCity("Springfield").setState("ZZ");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
|
||||
// Use the narrative generator
|
||||
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
|
||||
|
||||
// Encode the output, including the narrative
|
||||
String output = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(output);
|
||||
//END SNIPPET: example1
|
||||
|
||||
}
|
||||
|
||||
public void simple() {
|
||||
//START SNIPPET: simple
|
||||
Patient pat = new Patient();
|
||||
pat.getText().setStatus(NarrativeStatusEnum.GENERATED);
|
||||
pat.getText().setDiv("<div>This is the narrative text<br/>this is line 2</div>");
|
||||
//END SNIPPET: simple
|
||||
}
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.narrative.CustomThymeleafNarrativeGenerator;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class NarrativeGenerator {
|
||||
|
||||
public void testGenerator() {
|
||||
|
||||
//START SNIPPET: gen
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String propFile = "classpath:/com/foo/customnarrative.properties";
|
||||
CustomThymeleafNarrativeGenerator gen = new CustomThymeleafNarrativeGenerator(propFile);
|
||||
|
||||
ctx.setNarrativeGenerator(gen);
|
||||
//END SNIPPET: gen
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package example;
|
||||
|
||||
public class NewInterceptors {
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@SuppressWarnings("null")
|
||||
// START SNIPPET: provider
|
||||
public class PagingPatientProvider implements IResourceProvider {
|
||||
|
||||
/**
|
||||
* Search for Patient resources matching a given family name
|
||||
*/
|
||||
@Search
|
||||
public IBundleProvider search(@RequiredParam(name = Patient.SP_FAMILY) StringParam theFamily) {
|
||||
final InstantDt searchTime = InstantDt.withCurrentTime();
|
||||
|
||||
/**
|
||||
* First, we'll search the database for a set of database row IDs that
|
||||
* match the given search criteria. That way we can keep just the row IDs
|
||||
* around, and load the actual resources on demand later as the client
|
||||
* pages through them.
|
||||
*/
|
||||
final List<Long> matchingResourceIds = null; // <-- implement this
|
||||
|
||||
/**
|
||||
* Return a bundle provider which can page through the IDs and return the
|
||||
* resources that go with them.
|
||||
*/
|
||||
return new IBundleProvider() {
|
||||
|
||||
@Override
|
||||
public Integer size() {
|
||||
return matchingResourceIds.size();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<IBaseResource> getResources(int theFromIndex, int theToIndex) {
|
||||
int end = Math.max(theToIndex, matchingResourceIds.size() - 1);
|
||||
List<Long> idsToReturn = matchingResourceIds.subList(theFromIndex, end);
|
||||
return loadResourcesByIds(idsToReturn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstantDt getPublished() {
|
||||
return searchTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer preferredPageSize() {
|
||||
// Typically this method just returns null
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUuid() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of patient resources given their IDs
|
||||
*/
|
||||
private List<IBaseResource> loadResourcesByIds(List<Long> theIdsToReturn) {
|
||||
// .. implement this search against the database ..
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: provider
|
|
@ -1,33 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
|
||||
@SuppressWarnings({ "serial" })
|
||||
//START SNIPPET: provider
|
||||
public class PagingServer extends RestfulServer {
|
||||
|
||||
public PagingServer() {
|
||||
|
||||
/*
|
||||
* Set the resource providers as always. Here we are using the paging
|
||||
* provider from the example below, but it is not strictly neccesary
|
||||
* to use a paging resource provider as well. If a normal resource
|
||||
* provider is used (one which returns List<?> instead of IBundleProvider)
|
||||
* then the loaded resources will be stored by the IPagingProvider.
|
||||
*/
|
||||
setResourceProviders(new PagingPatientProvider());
|
||||
|
||||
/*
|
||||
* Set a paging provider. Here a simple in-memory implementation
|
||||
* is used, but you may create your own.
|
||||
*/
|
||||
FifoMemoryPagingProvider pp = new FifoMemoryPagingProvider(10);
|
||||
pp.setDefaultPageSize(10);
|
||||
pp.setMaximumPageSize(100);
|
||||
setPagingProvider(pp);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: provider
|
|
@ -1,42 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
||||
public class Parser {
|
||||
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
{
|
||||
//START SNIPPET: disableStripVersions
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IParser parser = ctx.newJsonParser();
|
||||
|
||||
// Disable the automatic stripping of versions from references on the parser
|
||||
parser.setStripVersionsFromReferences(false);
|
||||
//END SNIPPET: disableStripVersions
|
||||
|
||||
//START SNIPPET: disableStripVersionsCtx
|
||||
ctx.getParserOptions().setStripVersionsFromReferences(false);
|
||||
//END SNIPPET: disableStripVersionsCtx
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
//START SNIPPET: disableStripVersionsField
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
IParser parser = ctx.newJsonParser();
|
||||
|
||||
// Preserve versions only on these two fields (for the given parser)
|
||||
parser.setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference", "Patient.managingOrganization");
|
||||
|
||||
// You can also apply this setting to the context so that it will
|
||||
// flow to all parsers
|
||||
ctx.getParserOptions().setDontStripVersionsFromReferencesAtPaths("AuditEvent.entity.reference", "Patient.managingOrganization");
|
||||
//END SNIPPET: disableStripVersionsField
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package example;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.OperationOutcome;
|
||||
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.PatchTypeEnum;
|
||||
|
||||
|
||||
public class PatchExamples {
|
||||
|
||||
//START SNIPPET: patch
|
||||
@Patch
|
||||
public OperationOutcome patientPatch(@IdParam IdType theId, PatchTypeEnum thePatchType, @ResourceParam String theBody) {
|
||||
|
||||
if (thePatchType == PatchTypeEnum.JSON_PATCH) {
|
||||
// do something
|
||||
}
|
||||
if (thePatchType == PatchTypeEnum.XML_PATCH) {
|
||||
// do something
|
||||
}
|
||||
|
||||
OperationOutcome retVal = new OperationOutcome();
|
||||
retVal.getText().setDivAsString("<div>OK</div>");
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: patch
|
||||
|
||||
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
|
||||
public class QuickUsage {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:fake:mrns").setValue("7000135");
|
||||
patient.addIdentifier().setUse(IdentifierUseEnum.SECONDARY).setSystem("urn:fake:otherids").setValue("3287486");
|
||||
|
||||
patient.addName().addFamily("Smith").addGiven("John").addGiven("Q").addSuffix("Junior");
|
||||
|
||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu2();
|
||||
String xmlEncoded = ctx.newXmlParser().encodeResourceToString(patient);
|
||||
String jsonEncoded = ctx.newJsonParser().encodeResourceToString(patient);
|
||||
|
||||
MyClientInterface client = ctx.newRestfulClient(MyClientInterface.class, "http://foo/fhir");
|
||||
IdentifierDt searchParam = new IdentifierDt("urn:someidentifiers", "7000135");
|
||||
List<Patient> clients = client.findPatientsByIdentifier(searchParam);
|
||||
}
|
||||
|
||||
public interface MyClientInterface extends IRestfulClient
|
||||
{
|
||||
/** A FHIR search */
|
||||
@Search
|
||||
public List<Patient> findPatientsByIdentifier(@RequiredParam(name="identifier") IdentifierDt theIdentifier);
|
||||
|
||||
/** A FHIR create */
|
||||
@Create
|
||||
public MethodOutcome createPatient(@ResourceParam Patient thePatient);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package example;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
|
||||
|
||||
//START SNIPPET: interceptor
|
||||
public class RequestCounterInterceptor extends InterceptorAdapter
|
||||
{
|
||||
|
||||
private int myRequestCount;
|
||||
|
||||
public int getRequestCount() {
|
||||
return myRequestCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the incomingRequestPreProcessed method, which is called
|
||||
* for each incoming request before any processing is done
|
||||
*/
|
||||
@Override
|
||||
public boolean incomingRequestPreProcessed(HttpServletRequest theRequest, HttpServletResponse theResponse) {
|
||||
myRequestCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: interceptor
|
|
@ -1,36 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
|
||||
|
||||
//START SNIPPET: interceptor
|
||||
public class RequestExceptionInterceptor extends InterceptorAdapter
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theServletRequest,
|
||||
HttpServletResponse theServletResponse) throws ServletException, IOException {
|
||||
|
||||
// HAPI's server exceptions know what the appropriate HTTP status code is
|
||||
theServletResponse.setStatus(theException.getStatusCode());
|
||||
|
||||
// Provide a response ourself
|
||||
theServletResponse.setContentType("text/plain");
|
||||
theServletResponse.getWriter().append("Failed to process!");
|
||||
theServletResponse.getWriter().close();
|
||||
|
||||
// Since we handled this response in the interceptor, we must return false
|
||||
// to stop processing immediately
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//END SNIPPET: interceptor
|
|
@ -1,36 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
|
||||
public class ResourceRefs {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
public static void main(String[] args) {
|
||||
manualContained();
|
||||
}
|
||||
|
||||
public static void manualContained() {
|
||||
// START SNIPPET: manualContained
|
||||
// Create an organization, and give it a local ID
|
||||
Organization org = new Organization();
|
||||
org.setId("#localOrganization");
|
||||
org.getNameElement().setValue("Contained Test Organization");
|
||||
|
||||
// Create a patient
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1333");
|
||||
patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
|
||||
|
||||
// Set the reference, and manually add the contained resource
|
||||
patient.getManagingOrganization().setReference("#localOrganization");
|
||||
patient.getContained().getContainedResources().add(org);
|
||||
|
||||
String encoded = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(encoded);
|
||||
// END SNIPPET: manualContained
|
||||
}
|
||||
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
* All resource providers must implement IResourceProvider
|
||||
*/
|
||||
public class RestfulObservationResourceProvider implements IResourceProvider {
|
||||
|
||||
/**
|
||||
* The getResourceType method comes from IResourceProvider, and must
|
||||
* be overridden to indicate what type of resource this provider
|
||||
* supplies.
|
||||
*/
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "@Read" annotation indicates that this method supports the
|
||||
* read operation. It takes one argument, the Resource type being returned.
|
||||
*
|
||||
* @param theId
|
||||
* The read operation takes one parameter, which must be of type
|
||||
* IdDt and must be annotated with the "@Read.IdParam" annotation.
|
||||
* @return
|
||||
* Returns a resource matching this identifier, or null if none exists.
|
||||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@IdParam IdDt theId) {
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
patient.getIdentifier().get(0).setValue("00002");
|
||||
patient.addName().addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.setGender(AdministrativeGenderEnum.FEMALE);
|
||||
return patient;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "@Search" annotation indicates that this method supports the
|
||||
* search operation. You may have many different methods annotated with
|
||||
* this annotation, to support many different search criteria. This
|
||||
* example searches by family name.
|
||||
*
|
||||
* @param theIdentifier
|
||||
* This operation takes one parameter which is the search criteria. It is
|
||||
* annotated with the "@Required" annotation. This annotation takes one argument,
|
||||
* a string containing the name of the search criteria. The datatype here
|
||||
* is StringDt, but there are other possible parameter types depending on the
|
||||
* specific search criteria.
|
||||
* @return
|
||||
* This method returns a list of Patients. This list may contain multiple
|
||||
* matching resources, or it may also be empty.
|
||||
*/
|
||||
@Search()
|
||||
public List<Patient> getPatient(@RequiredParam(name = Patient.SP_FAMILY) StringDt theFamilyName) {
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
patient.getIdentifier().get(0).setValue("00001");
|
||||
patient.addName();
|
||||
patient.getName().get(0).addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||
return Collections.singletonList(patient);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: provider
|
|
@ -1,90 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.AdministrativeGenderEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
* All resource providers must implement IResourceProvider
|
||||
*/
|
||||
public class RestfulPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
/**
|
||||
* The getResourceType method comes from IResourceProvider, and must
|
||||
* be overridden to indicate what type of resource this provider
|
||||
* supplies.
|
||||
*/
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "@Read" annotation indicates that this method supports the
|
||||
* read operation. Read operations should return a single resource
|
||||
* instance.
|
||||
*
|
||||
* @param theId
|
||||
* The read operation takes one parameter, which must be of type
|
||||
* IdDt and must be annotated with the "@Read.IdParam" annotation.
|
||||
* @return
|
||||
* Returns a resource matching this identifier, or null if none exists.
|
||||
*/
|
||||
@Read()
|
||||
public Patient getResourceById(@IdParam IdDt theId) {
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
patient.getIdentifier().get(0).setValue("00002");
|
||||
patient.addName().addFamily("Test");
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.setGender(AdministrativeGenderEnum.FEMALE);
|
||||
return patient;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "@Search" annotation indicates that this method supports the
|
||||
* search operation. You may have many different methods annotated with
|
||||
* this annotation, to support many different search criteria. This
|
||||
* example searches by family name.
|
||||
*
|
||||
* @param theFamilyName
|
||||
* This operation takes one parameter which is the search criteria. It is
|
||||
* annotated with the "@Required" annotation. This annotation takes one argument,
|
||||
* a string containing the name of the search criteria. The datatype here
|
||||
* is StringParam, but there are other possible parameter types depending on the
|
||||
* specific search criteria.
|
||||
* @return
|
||||
* This method returns a list of Patients. This list may contain multiple
|
||||
* matching resources, or it may also be empty.
|
||||
*/
|
||||
@Search()
|
||||
public List<Patient> getPatient(@RequiredParam(name = Patient.SP_FAMILY) StringParam theFamilyName) {
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
patient.getIdentifier().get(0).setValue("00001");
|
||||
patient.addName();
|
||||
patient.getName().get(0).addFamily(theFamilyName.getValue());
|
||||
patient.getName().get(0).addGiven("PatientOne");
|
||||
patient.setGender(AdministrativeGenderEnum.MALE);
|
||||
return Collections.singletonList(patient);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: provider
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,66 +0,0 @@
|
|||
package example;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
|
||||
|
||||
public class SecurityInterceptors {
|
||||
|
||||
// START SNIPPET: basicAuthInterceptor
|
||||
public class BasicSecurityInterceptor extends InterceptorAdapter
|
||||
{
|
||||
|
||||
/**
|
||||
* This interceptor implements HTTP Basic Auth, which specifies that
|
||||
* a username and password are provided in a header called Authorization.
|
||||
*/
|
||||
@Override
|
||||
public boolean incomingRequestPostProcessed(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
|
||||
String authHeader = theRequest.getHeader("Authorization");
|
||||
|
||||
// The format of the header must be:
|
||||
// Authorization: Basic [base64 of username:password]
|
||||
if (authHeader == null || authHeader.startsWith("Basic ") == false) {
|
||||
throw new AuthenticationException("Missing or invalid Authorization header");
|
||||
}
|
||||
|
||||
String base64 = authHeader.substring("Basic ".length());
|
||||
String base64decoded = new String(Base64.decodeBase64(base64));
|
||||
String[] parts = base64decoded.split("\\:");
|
||||
|
||||
String username = parts[0];
|
||||
String password = parts[1];
|
||||
|
||||
/*
|
||||
* Here we test for a hardcoded username & password. This is
|
||||
* not typically how you would implement this in a production
|
||||
* system of course..
|
||||
*/
|
||||
if (!username.equals("someuser") || !password.equals("thepassword")) {
|
||||
throw new AuthenticationException("Invalid username or password");
|
||||
}
|
||||
|
||||
// Return true to allow the request to proceed
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//END SNIPPET: basicAuthInterceptor
|
||||
|
||||
|
||||
|
||||
public void basicAuthInterceptorRealm() {
|
||||
//START SNIPPET: basicAuthInterceptorRealm
|
||||
AuthenticationException ex = new AuthenticationException();
|
||||
ex.addAuthenticateHeaderForRealm("myRealm");
|
||||
throw ex;
|
||||
//END SNIPPET: basicAuthInterceptorRealm
|
||||
}
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package example;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
import ca.uhn.fhir.rest.server.ETagSupportEnum;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ServerETagExamples {
|
||||
|
||||
// START SNIPPET: disablingETags
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithLogging extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// ETag support is enabled by default
|
||||
setETagSupport(ETagSupportEnum.ENABLED);
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: disablingETags
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
||||
public abstract class ServerExceptionsExample implements IResourceProvider {
|
||||
|
||||
private boolean databaseIsDown;
|
||||
|
||||
//START SNIPPET: returnOO
|
||||
@Read
|
||||
public Patient read(@IdParam IdDt theId) {
|
||||
if (databaseIsDown) {
|
||||
OperationOutcome oo = new OperationOutcome();
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("Database is down");
|
||||
throw new InternalErrorException("Database is down", oo);
|
||||
}
|
||||
|
||||
Patient patient = new Patient(); // populate this
|
||||
return patient;
|
||||
}
|
||||
//END SNIPPET: returnOO
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
|
||||
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
public class ServerInterceptors {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
|
||||
|
||||
// START SNIPPET: resourceExtension
|
||||
// Create an example patient
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
|
||||
|
||||
// Create an extension
|
||||
ExtensionDt ext = new ExtensionDt();
|
||||
ext.setModifier(false);
|
||||
ext.setUrl("http://example.com/extensions#someext");
|
||||
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
|
||||
|
||||
// Add the extension to the resource
|
||||
patient.addUndeclaredExtension(ext);
|
||||
//END SNIPPET: resourceExtension
|
||||
|
||||
|
||||
//START SNIPPET: resourceStringExtension
|
||||
HumanNameDt name = patient.addName();
|
||||
name.addFamily().setValue("Shmoe");
|
||||
StringDt given = name.addGiven();
|
||||
given.setValue("Joe");
|
||||
ExtensionDt ext2 = new ExtensionDt(false, "http://examples.com#moreext", new StringDt("Hello"));
|
||||
given.addUndeclaredExtension(ext2);
|
||||
//END SNIPPET: resourceStringExtension
|
||||
|
||||
String output = FhirContext.forDstu2().newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
|
||||
System.out.println(output);
|
||||
|
||||
|
||||
//START SNIPPET: parseExtension
|
||||
// Get all extensions (modifier or not) for a given URL
|
||||
List<ExtensionDt> resourceExts = patient.getUndeclaredExtensionsByUrl("http://fooextensions.com#exts");
|
||||
|
||||
// Get all non-modifier extensions regardless of URL
|
||||
List<ExtensionDt> nonModExts = patient.getUndeclaredExtensions();
|
||||
|
||||
//Get all non-modifier extensions regardless of URL
|
||||
List<ExtensionDt> modExts = patient.getUndeclaredModifierExtensions();
|
||||
//END SNIPPET: parseExtension
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void foo() {
|
||||
//START SNIPPET: subExtension
|
||||
Patient patient = new Patient();
|
||||
|
||||
ExtensionDt parent = new ExtensionDt(false, "http://example.com#parent");
|
||||
patient.addUndeclaredExtension(parent);
|
||||
|
||||
ExtensionDt child1 = new ExtensionDt(false, "http://example.com#childOne", new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child1);
|
||||
|
||||
ExtensionDt child2 = new ExtensionDt(false, "http://example.com#childTwo", new StringDt("value1"));
|
||||
parent.addUndeclaredExtension(child2);
|
||||
//END SNIPPET: subExtension
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.model.api.Tag;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import org.hl7.fhir.r4.model.InstantType;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ServerMetadataExamples {
|
||||
|
||||
// START SNIPPET: serverMethod
|
||||
@Search
|
||||
public List<Patient> getAllPatients() {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
// Create a patient to return
|
||||
Patient patient = new Patient();
|
||||
retVal.add(patient);
|
||||
patient.setId("Patient/123");
|
||||
patient.addName().setFamily("Smith").addGiven("John");
|
||||
|
||||
// Add tags
|
||||
patient.getMeta().addTag()
|
||||
.setSystem(Tag.HL7_ORG_FHIR_TAG)
|
||||
.setCode("some_tag")
|
||||
.setDisplay("Some tag");
|
||||
patient.getMeta().addTag()
|
||||
.setSystem(Tag.HL7_ORG_FHIR_TAG)
|
||||
.setCode("another_tag")
|
||||
.setDisplay("Another tag");
|
||||
|
||||
// Set the last updated date
|
||||
patient.getMeta().setLastUpdatedElement(new InstantType("2011-02-22T11:22:00.0122Z"));
|
||||
|
||||
return retVal;
|
||||
}
|
||||
// END SNIPPET: serverMethod
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.dstu3.model.Parameters;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ConceptMap;
|
||||
import ca.uhn.fhir.model.primitive.DateDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Operation;
|
||||
import ca.uhn.fhir.rest.annotation.OperationParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
public class ServerOperations {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(ServerOperations.class);
|
||||
|
||||
|
||||
//START SNIPPET: manualInputAndOutput
|
||||
@Operation(name="$manualInputAndOutput", manualResponse=true, manualRequest=true)
|
||||
public void manualInputAndOutput(HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws IOException {
|
||||
String contentType = theServletRequest.getContentType();
|
||||
byte[] bytes = IOUtils.toByteArray(theServletRequest.getInputStream());
|
||||
ourLog.info("Received call with content type {} and {} bytes", contentType, bytes.length);
|
||||
|
||||
// In a real example we might do something more interesting with the received bytes,
|
||||
// here we'll just replace them with hardcoded ones
|
||||
bytes = new byte[] { 0, 1, 2, 3 };
|
||||
|
||||
theServletResponse.setContentType(contentType);
|
||||
theServletResponse.getOutputStream().write(bytes);
|
||||
theServletResponse.getOutputStream().close();
|
||||
}
|
||||
//END SNIPPET: manualInputAndOutput
|
||||
|
||||
|
||||
//START SNIPPET: searchParamBasic
|
||||
@Operation(name="$find-matches", idempotent=true)
|
||||
public Parameters findMatchesBasic(
|
||||
@OperationParam(name="date") DateParam theDate,
|
||||
@OperationParam(name="code") TokenParam theCode) {
|
||||
|
||||
Parameters retVal = new Parameters();
|
||||
// Populate bundle with matching resources
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: searchParamBasic
|
||||
|
||||
//START SNIPPET: searchParamAdvanced
|
||||
@Operation(name="$find-matches", idempotent=true)
|
||||
public Parameters findMatchesAdvanced(
|
||||
@OperationParam(name="dateRange") DateRangeParam theDate,
|
||||
@OperationParam(name="name") List<StringParam> theName,
|
||||
@OperationParam(name="code") TokenAndListParam theEnd) {
|
||||
|
||||
Parameters retVal = new Parameters();
|
||||
// Populate bundle with matching resources
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: searchParamAdvanced
|
||||
|
||||
//START SNIPPET: patientTypeOperation
|
||||
@Operation(name="$everything", idempotent=true)
|
||||
public Bundle patientTypeOperation(
|
||||
@OperationParam(name="start") DateDt theStart,
|
||||
@OperationParam(name="end") DateDt theEnd) {
|
||||
|
||||
Bundle retVal = new Bundle();
|
||||
// Populate bundle with matching resources
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: patientTypeOperation
|
||||
|
||||
//START SNIPPET: patientInstanceOperation
|
||||
@Operation(name="$everything", idempotent=true)
|
||||
public Bundle patientInstanceOperation(
|
||||
@IdParam IdDt thePatientId,
|
||||
@OperationParam(name="start") DateDt theStart,
|
||||
@OperationParam(name="end") DateDt theEnd) {
|
||||
|
||||
Bundle retVal = new Bundle();
|
||||
// Populate bundle with matching resources
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: patientInstanceOperation
|
||||
|
||||
//START SNIPPET: serverOperation
|
||||
@Operation(name="$closure")
|
||||
public ConceptMap closureOperation(
|
||||
@OperationParam(name="name") StringDt theStart,
|
||||
@OperationParam(name="concept") List<CodingDt> theEnd,
|
||||
@OperationParam(name="version") IdDt theVersion) {
|
||||
|
||||
ConceptMap retVal = new ConceptMap();
|
||||
// Populate bundle with matching resources
|
||||
return retVal;
|
||||
}
|
||||
//END SNIPPET: serverOperation
|
||||
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
import org.hl7.fhir.instance.hapi.validation.FhirInstanceValidator;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.interceptor.*;
|
||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ServletExamples {
|
||||
|
||||
// START SNIPPET: loggingInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithLogging extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Now register the logging interceptor
|
||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
||||
registerInterceptor(loggingInterceptor);
|
||||
|
||||
// The SLF4j logger "test.accesslog" will receive the logging events
|
||||
loggingInterceptor.setLoggerName("test.accesslog");
|
||||
|
||||
// This is the format for each line. A number of substitution variables may
|
||||
// be used here. See the JavaDoc for LoggingInterceptor for information on
|
||||
// what is available.
|
||||
loggingInterceptor.setMessageFormat("Source[${remoteAddr}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: loggingInterceptor
|
||||
|
||||
// START SNIPPET: validatingInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class ValidatingServerWithLogging extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Create an interceptor to validate incoming requests
|
||||
RequestValidatingInterceptor requestInterceptor = new RequestValidatingInterceptor();
|
||||
|
||||
// Register a validator module (you could also use SchemaBaseValidator and/or SchematronBaseValidator)
|
||||
requestInterceptor.addValidatorModule(new FhirInstanceValidator());
|
||||
|
||||
requestInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||
requestInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||
requestInterceptor.setResponseHeaderValue("Validation on ${line}: ${message} ${severity}");
|
||||
requestInterceptor.setResponseHeaderValueNoIssues("No issues detected");
|
||||
|
||||
// Now register the validating interceptor
|
||||
registerInterceptor(requestInterceptor);
|
||||
|
||||
// Create an interceptor to validate responses
|
||||
// This is configured in the same way as above
|
||||
ResponseValidatingInterceptor responseInterceptor = new ResponseValidatingInterceptor();
|
||||
responseInterceptor.addValidatorModule(new FhirInstanceValidator());
|
||||
responseInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
|
||||
responseInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
|
||||
responseInterceptor.setResponseHeaderValue("Validation on ${line}: ${message} ${severity}");
|
||||
responseInterceptor.setResponseHeaderValueNoIssues("No issues detected");
|
||||
registerInterceptor(responseInterceptor);
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: validatingInterceptor
|
||||
|
||||
// START SNIPPET: exceptionInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithExceptionHandling extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Now register the interceptor
|
||||
ExceptionHandlingInterceptor interceptor = new ExceptionHandlingInterceptor();
|
||||
registerInterceptor(interceptor);
|
||||
|
||||
// Return the stack trace to the client for the following exception types
|
||||
interceptor.setReturnStackTracesForExceptionTypes(InternalErrorException.class, NullPointerException.class);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: exceptionInterceptor
|
||||
|
||||
// START SNIPPET: responseHighlighterInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithResponseHighlighter extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Now register the interceptor
|
||||
ResponseHighlighterInterceptor interceptor = new ResponseHighlighterInterceptor();
|
||||
registerInterceptor(interceptor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: responseHighlighterInterceptor
|
||||
|
||||
// START SNIPPET: corsInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithCors extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Define your CORS configuration. This is an example
|
||||
// showing a typical setup. You should customize this
|
||||
// to your specific needs
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.addAllowedHeader("x-fhir-starter");
|
||||
config.addAllowedHeader("Origin");
|
||||
config.addAllowedHeader("Accept");
|
||||
config.addAllowedHeader("X-Requested-With");
|
||||
config.addAllowedHeader("Content-Type");
|
||||
|
||||
config.addAllowedOrigin("*");
|
||||
|
||||
config.addExposedHeader("Location");
|
||||
config.addExposedHeader("Content-Location");
|
||||
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
|
||||
|
||||
// Create the interceptor and register it
|
||||
CorsInterceptor interceptor = new CorsInterceptor(config);
|
||||
registerInterceptor(interceptor);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: corsInterceptor
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
||||
public class TagsExamples {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new TagsExamples().getResourceTags();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void getResourceTags() {
|
||||
// START SNIPPET: getResourceTags
|
||||
IGenericClient client = FhirContext.forDstu2().newRestfulGenericClient("http://fhir.healthintersections.com.au/open");
|
||||
Patient p = client.read(Patient.class, "1");
|
||||
|
||||
// Retrieve the list of tags from the resource metadata
|
||||
TagList tags = ResourceMetadataKeyEnum.TAG_LIST.get(p);
|
||||
|
||||
// tags may be null if no tags were read in
|
||||
if (tags == null) {
|
||||
System.out.println("No tags!");
|
||||
} else {
|
||||
|
||||
// You may iterate over all the tags
|
||||
for (Tag next : tags) {
|
||||
System.out.println(next.getScheme() + " - " + next.getTerm());
|
||||
}
|
||||
|
||||
// You may also get a list of tags matching a given scheme
|
||||
List<Tag> someTags = tags.getTagsWithScheme("http://hl7.org/fhir/tag");
|
||||
|
||||
// Or a specific tag (by scheme and term)
|
||||
Tag specificTag = tags.getTag("http://hl7.org/fhir/tag", "http://foo");
|
||||
|
||||
}
|
||||
// END SNIPPET: getResourceTags
|
||||
}
|
||||
|
||||
// START SNIPPET: serverMethod
|
||||
@Search
|
||||
public List<Patient> getAllPatients() {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
// Create a patient to return
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/123");
|
||||
patient.addName().addFamily("Smith").addGiven("John");
|
||||
|
||||
// Create a tag list and add it to the resource
|
||||
TagList tags = new TagList();
|
||||
ResourceMetadataKeyEnum.TAG_LIST.put(patient, tags);
|
||||
|
||||
// Add some tags to the list
|
||||
tags.addTag(Tag.HL7_ORG_FHIR_TAG, "http://foo/tag1.html", "Some tag");
|
||||
tags.addTag(Tag.HL7_ORG_FHIR_TAG, "http://foo/tag2.html", "Another tag");
|
||||
|
||||
return retVal;
|
||||
}
|
||||
// END SNIPPET: serverMethod
|
||||
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
package example;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.PrePopulatedValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
|
||||
public class ValidateDirectory {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateDirectory.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Load all profiles in this directory
|
||||
File profileDirectory = new File("/tmp/directory/with/profiles");
|
||||
|
||||
// Validate resources in this directory
|
||||
File resourceDirectory = new File("/tmp/directory/with/resources/to/validate");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
IParser xmlParser = ctx.newXmlParser();
|
||||
IParser jsonParser = ctx.newJsonParser();
|
||||
|
||||
Map<String, StructureDefinition> structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
Map<String, CodeSystem> codeSystems = new HashMap<String, CodeSystem>();
|
||||
Map<String, ValueSet> valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
// Load all profile files
|
||||
for (File nextFile : profileDirectory.listFiles()) {
|
||||
|
||||
IBaseResource parsedRes = null;
|
||||
if (nextFile.getAbsolutePath().toLowerCase().endsWith(".xml")) {
|
||||
parsedRes = xmlParser.parseResource(new FileReader(nextFile));
|
||||
} else if (nextFile.getAbsolutePath().toLowerCase().endsWith(".json")) {
|
||||
parsedRes = jsonParser.parseResource(new FileReader(nextFile));
|
||||
} else {
|
||||
ourLog.info("Ignoring file: {}", nextFile.getName());
|
||||
}
|
||||
|
||||
if (parsedRes instanceof StructureDefinition) {
|
||||
StructureDefinition res = (StructureDefinition) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
structureDefinitions.put(res.getUrl(), res);
|
||||
}
|
||||
} else if (parsedRes instanceof ValueSet) {
|
||||
ValueSet res = (ValueSet) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
valueSets.put(res.getUrl(), res);
|
||||
}
|
||||
} else if (parsedRes instanceof CodeSystem) {
|
||||
CodeSystem res = (CodeSystem) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
codeSystems.put(res.getUrl(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
|
||||
|
||||
ValidationSupportChain validationSupportChain = new ValidationSupportChain();
|
||||
validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport());
|
||||
validationSupportChain.addValidationSupport(new PrePopulatedValidationSupport(structureDefinitions, valueSets, codeSystems));
|
||||
|
||||
instanceValidator.setValidationSupport(validationSupportChain);
|
||||
|
||||
FhirValidator val = ctx.newValidator();
|
||||
val.registerValidatorModule(instanceValidator);
|
||||
|
||||
// Loop through the files in the validation directory and validate each one
|
||||
for (File nextFile : resourceDirectory.listFiles()) {
|
||||
|
||||
if (nextFile.getAbsolutePath().toLowerCase().endsWith(".xml")) {
|
||||
ourLog.info("Going to validate: {}", nextFile.getName());
|
||||
} else if (nextFile.getAbsolutePath().toLowerCase().endsWith(".json")) {
|
||||
ourLog.info("Going to validate: {}", nextFile.getName());
|
||||
} else {
|
||||
ourLog.info("Ignoring file: {}", nextFile.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
String input = IOUtils.toString(new FileReader(nextFile));
|
||||
ValidationResult result = val.validateWithResult(input);
|
||||
IBaseOperationOutcome oo = result.toOperationOutcome();
|
||||
ourLog.info("Result:\n{}", xmlParser.setPrettyPrint(true).encodeResourceToString(oo));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package example;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
|
||||
import java.io.FileReader;
|
||||
|
||||
public class ValidateSimple {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateSimple.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FhirContext ctx = FhirContext.forR4();
|
||||
|
||||
// Create a validator module
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
|
||||
|
||||
// We'll create a validation chain with only the DefaultProfileValidationupport registered
|
||||
ValidationSupportChain validationSupportChain = new ValidationSupportChain();
|
||||
validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport());
|
||||
instanceValidator.setValidationSupport(validationSupportChain);
|
||||
|
||||
// Create a validator and register the InstanceValidator module
|
||||
FhirValidator val = ctx.newValidator();
|
||||
val.registerValidatorModule(instanceValidator);
|
||||
|
||||
// Read in the file and validate it
|
||||
String nextFile = args[0];
|
||||
try (FileReader fileReader = new FileReader(nextFile)) {
|
||||
String input = IOUtils.toString(fileReader);
|
||||
ValidationResult result = val.validateWithResult(input);
|
||||
IBaseOperationOutcome oo = result.toOperationOutcome();
|
||||
ourLog.info("Result:\n{}", ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,331 +0,0 @@
|
|||
package example;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.filefilter.WildcardFileFilter;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.*;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.StrictErrorHandler;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.validation.*;
|
||||
import ca.uhn.fhir.validation.schematron.SchematronBaseValidator;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ValidatorExamples {
|
||||
|
||||
public void validationIntro() {
|
||||
// START SNIPPET: validationIntro
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Ask the context for a validator
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
|
||||
// Create some modules and register them
|
||||
IValidatorModule module1 = new SchemaBaseValidator(ctx);
|
||||
validator.registerValidatorModule(module1);
|
||||
IValidatorModule module2 = new SchematronBaseValidator(ctx);
|
||||
validator.registerValidatorModule(module2);
|
||||
|
||||
// Pass a resource in to be validated. The resource can
|
||||
// be an IBaseResource instance, or can be a raw String
|
||||
// containing a serialized resource as text.
|
||||
Patient resource = new Patient();
|
||||
ValidationResult result = validator.validateWithResult(resource);
|
||||
String resourceText = "<Patient.....>";
|
||||
ValidationResult result2 = validator.validateWithResult(resourceText);
|
||||
|
||||
// The result object now contains the validation results
|
||||
for (SingleValidationMessage next : result.getMessages()) {
|
||||
System.out.println(next.getLocationString() + " " + next.getMessage());
|
||||
}
|
||||
// END SNIPPET: validationIntro
|
||||
}
|
||||
|
||||
// START SNIPPET: serverValidation
|
||||
public class MyRestfulServer extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
// ...Configure resource providers, etc...
|
||||
|
||||
// Create a context, set the error handler and instruct
|
||||
// the server to use it
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
ctx.setParserErrorHandler(new StrictErrorHandler());
|
||||
setFhirContext(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: serverValidation
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void enableValidation() {
|
||||
// START SNIPPET: clientValidation
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
ctx.setParserErrorHandler(new StrictErrorHandler());
|
||||
|
||||
// This client will have strict parser validation enabled
|
||||
IGenericClient client = ctx.newRestfulGenericClient("http://fhirtest.uhn.ca/baseDstu3");
|
||||
// END SNIPPET: clientValidation
|
||||
|
||||
}
|
||||
|
||||
public void parserValidation() {
|
||||
// START SNIPPET: parserValidation
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create a parser and configure it to use the strict error handler
|
||||
IParser parser = ctx.newXmlParser();
|
||||
parser.setParserErrorHandler(new StrictErrorHandler());
|
||||
|
||||
// This example resource is invalid, as Patient.active can not repeat
|
||||
String input = "<Patient><active value=\"true\"/><active value=\"false\"/></Patient>";
|
||||
|
||||
// The following will throw a DataFormatException because of the StrictErrorHandler
|
||||
parser.parseResource(Patient.class, input);
|
||||
// END SNIPPET: parserValidation
|
||||
}
|
||||
|
||||
public void validateResource() {
|
||||
// START SNIPPET: basicValidation
|
||||
// As always, you need a context
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create and populate a new patient object
|
||||
Patient p = new Patient();
|
||||
p.addName().setFamily("Smith").addGiven("John").addGiven("Q");
|
||||
p.addIdentifier().setSystem("urn:foo:identifiers").setValue("12345");
|
||||
p.addTelecom().setSystem(ContactPointSystem.PHONE).setValue("416 123-4567");
|
||||
|
||||
// Request a validator and apply it
|
||||
FhirValidator val = ctx.newValidator();
|
||||
|
||||
// Create the Schema/Schematron modules and register them. Note that
|
||||
// you might want to consider keeping these modules around as long-term
|
||||
// objects: they parse and then store schemas, which can be an expensive
|
||||
// operation.
|
||||
IValidatorModule module1 = new SchemaBaseValidator(ctx);
|
||||
IValidatorModule module2 = new SchematronBaseValidator(ctx);
|
||||
val.registerValidatorModule(module1);
|
||||
val.registerValidatorModule(module2);
|
||||
|
||||
ValidationResult result = val.validateWithResult(p);
|
||||
if (result.isSuccessful()) {
|
||||
|
||||
System.out.println("Validation passed");
|
||||
|
||||
} else {
|
||||
// We failed validation!
|
||||
System.out.println("Validation failed");
|
||||
}
|
||||
|
||||
// The result contains a list of "messages"
|
||||
List<SingleValidationMessage> messages = result.getMessages();
|
||||
for (SingleValidationMessage next : messages) {
|
||||
System.out.println("Message:");
|
||||
System.out.println(" * Location: " + next.getLocationString());
|
||||
System.out.println(" * Severity: " + next.getSeverity());
|
||||
System.out.println(" * Message : " + next.getMessage());
|
||||
}
|
||||
|
||||
// You can also convert the results into an OperationOutcome resource
|
||||
OperationOutcome oo = (OperationOutcome) result.toOperationOutcome();
|
||||
String results = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(oo);
|
||||
System.out.println(results);
|
||||
// END SNIPPET: basicValidation
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
instanceValidator();
|
||||
|
||||
}
|
||||
|
||||
private static void instanceValidator() throws Exception {
|
||||
// START SNIPPET: instanceValidator
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create a FhirInstanceValidator and register it to a validator
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
|
||||
validator.registerValidatorModule(instanceValidator);
|
||||
|
||||
/*
|
||||
* If you want, you can configure settings on the validator to adjust
|
||||
* its behaviour during validation
|
||||
*/
|
||||
instanceValidator.setAnyExtensionsAllowed(true);
|
||||
|
||||
|
||||
/*
|
||||
* Let's create a resource to validate. This Observation has some fields
|
||||
* populated, but it is missing Observation.status, which is mandatory.
|
||||
*/
|
||||
Observation obs = new Observation();
|
||||
obs.getCode().addCoding().setSystem("http://loinc.org").setCode("12345-6");
|
||||
obs.setValue(new StringType("This is a value"));
|
||||
|
||||
// Validate
|
||||
ValidationResult result = validator.validateWithResult(obs);
|
||||
|
||||
/*
|
||||
* Note: You can also explicitly declare a profile to validate against
|
||||
* using the block below.
|
||||
*/
|
||||
// ValidationResult result = validator.validateWithResult(obs, new ValidationOptions().addProfile("http://myprofile.com"));
|
||||
|
||||
// Do we have any errors or fatal errors?
|
||||
System.out.println(result.isSuccessful()); // false
|
||||
|
||||
// Show the issues
|
||||
for (SingleValidationMessage next : result.getMessages()) {
|
||||
System.out.println(" Next issue " + next.getSeverity() + " - " + next.getLocationString() + " - " + next.getMessage());
|
||||
}
|
||||
// Prints:
|
||||
// Next issue ERROR - /f:Observation - Element '/f:Observation.status': minimum required = 1, but only found 0
|
||||
// Next issue WARNING - /f:Observation/f:code - Unable to validate code "12345-6" in code system "http://loinc.org"
|
||||
|
||||
// You can also convert the result into an operation outcome if you
|
||||
// need to return one from a server
|
||||
OperationOutcome oo = (OperationOutcome) result.toOperationOutcome();
|
||||
// END SNIPPET: instanceValidator
|
||||
}
|
||||
|
||||
private static void instanceValidatorCustom() throws Exception {
|
||||
// START SNIPPET: instanceValidatorCustom
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create a FhirInstanceValidator and register it to a validator
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
|
||||
validator.registerValidatorModule(instanceValidator);
|
||||
|
||||
IValidationSupport valSupport = new IValidationSupport() {
|
||||
|
||||
@Override
|
||||
public org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent expandValueSet(FhirContext theContext, org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent theInclude) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet fetchValueSet(FhirContext theContext, String theSystem) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
// TODO: implement
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay, String theValueSet) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupCodeResult lookupCode(FhirContext theContext, String theSystem, String theCode) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition generateSnapshot(StructureDefinition theInput, String theUrl, String theName) {
|
||||
// TODO: implement
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* ValidationSupportChain strings multiple instances of IValidationSupport together. The
|
||||
* code below is useful because it means that when the validator wants to load a
|
||||
* StructureDefinition or a ValueSet, it will first use DefaultProfileValidationSupport,
|
||||
* which loads the default HL7 versions. Any StructureDefinitions which are not found in
|
||||
* the built-in set are delegated to your custom implementation.
|
||||
*/
|
||||
ValidationSupportChain support = new ValidationSupportChain(new DefaultProfileValidationSupport(), valSupport);
|
||||
instanceValidator.setValidationSupport(support);
|
||||
|
||||
// END SNIPPET: instanceValidatorCustom
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void validateFiles() throws Exception {
|
||||
// START SNIPPET: validateFiles
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
|
||||
// Create a validator and configure it
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
validator.setValidateAgainstStandardSchema(true);
|
||||
validator.setValidateAgainstStandardSchematron(true);
|
||||
|
||||
// Get a list of files in a given directory
|
||||
String[] fileList = new File("/home/some/dir").list(new WildcardFileFilter("*.txt"));
|
||||
for (String nextFile : fileList) {
|
||||
|
||||
// For each file, load the contents into a string
|
||||
String nextFileContents = IOUtils.toString(new FileReader(nextFile));
|
||||
|
||||
// Parse that string (this example assumes JSON encoding)
|
||||
IBaseResource resource = ctx.newJsonParser().parseResource(nextFileContents);
|
||||
|
||||
// Apply the validation. This will throw an exception on the first
|
||||
// validation failure
|
||||
ValidationResult result = validator.validateWithResult(resource);
|
||||
if (result.isSuccessful() == false) {
|
||||
throw new Exception("We failed!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// END SNIPPET: validateFiles
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package example;
|
||||
|
||||
import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
|
||||
public class ValidatorExamplesDstu3 {
|
||||
|
||||
public void validateProfileDstu3() {
|
||||
// START SNIPPET: validateFiles
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
|
||||
// Typically if you are doing profile validation, you want to disable
|
||||
// the schema/schematron validation since the profile will specify
|
||||
// all the same rules (and more)
|
||||
validator.setValidateAgainstStandardSchema(false);
|
||||
validator.setValidateAgainstStandardSchematron(false);
|
||||
|
||||
// FhirInstanceValidator is the validation module that handles
|
||||
// profile validation. So, create an InstanceValidator module
|
||||
// and register it to the validator.
|
||||
FhirInstanceValidator instanceVal = new FhirInstanceValidator();
|
||||
validator.registerValidatorModule(instanceVal);
|
||||
|
||||
// FhirInstanceValidator requires an instance of "IValidationSupport" in
|
||||
// order to function. This module is used by the validator to actually obtain
|
||||
// all of the resources it needs in order to perform validation. Specifically,
|
||||
// the validator uses it to fetch StructureDefinitions, ValueSets, CodeSystems,
|
||||
// etc, as well as to perform terminology validation.
|
||||
//
|
||||
// The implementation used here (ValidationSupportChain) is allows for
|
||||
// multiple implementations to be used in a chain, where if a specific resource
|
||||
// is needed the whole chain is tried and the first module which is actually
|
||||
// able to answer is used. The first entry in the chain that we register is
|
||||
// the DefaultProfileValidationSupport, which supplies the "built-in" FHIR
|
||||
// StructureDefinitions and ValueSets
|
||||
ValidationSupportChain validationSupportChain = new ValidationSupportChain();
|
||||
validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport());
|
||||
instanceVal.setValidationSupport(validationSupportChain);
|
||||
|
||||
// END SNIPPET: validateFiles
|
||||
}
|
||||
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package example.customtype;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.BackboneElement;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Block;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Extension;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
//START SNIPPET: resource
|
||||
@ResourceDef(name = "Patient")
|
||||
public class CustomCompositeExtension extends Patient {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* A custom extension
|
||||
*/
|
||||
@Child(name = "foo")
|
||||
@Extension(url="http://acme.org/fooParent", definedLocally = false, isModifier = false)
|
||||
protected FooParentExtension fooParentExtension;
|
||||
|
||||
public FooParentExtension getFooParentExtension() {
|
||||
return fooParentExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(fooParentExtension);
|
||||
}
|
||||
|
||||
public void setFooParentExtension(FooParentExtension theFooParentExtension) {
|
||||
fooParentExtension = theFooParentExtension;
|
||||
}
|
||||
|
||||
@Block
|
||||
public static class FooParentExtension extends BackboneElement {
|
||||
|
||||
private static final long serialVersionUID = 4522090347756045145L;
|
||||
|
||||
@Child(name = "childA")
|
||||
@Extension(url = "http://acme.org/fooChildA", definedLocally = false, isModifier = false)
|
||||
private StringType myChildA;
|
||||
|
||||
@Child(name = "childB")
|
||||
@Extension(url = "http://acme.org/fooChildB", definedLocally = false, isModifier = false)
|
||||
private StringType myChildB;
|
||||
|
||||
@Override
|
||||
public FooParentExtension copy() {
|
||||
FooParentExtension copy = new FooParentExtension();
|
||||
copy.myChildA = myChildA;
|
||||
copy.myChildB = myChildB;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.isEmpty() && ElementUtil.isEmpty(myChildA, myChildB);
|
||||
}
|
||||
|
||||
public StringType getChildA() {
|
||||
return myChildA;
|
||||
}
|
||||
|
||||
public StringType getChildB() {
|
||||
return myChildB;
|
||||
}
|
||||
|
||||
public void setChildA(StringType theChildA) {
|
||||
myChildA = theChildA;
|
||||
}
|
||||
|
||||
public void setChildB(StringType theChildB) {
|
||||
myChildB = theChildB;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: resource
|
|
@ -1,63 +0,0 @@
|
|||
package example.customtype;
|
||||
|
||||
//START SNIPPET: datatype
|
||||
import org.hl7.fhir.dstu3.model.DateTimeType;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.dstu3.model.Type;
|
||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
* This is an example of a custom datatype.
|
||||
*
|
||||
* This is an STU3 example so it extends Type and implements ICompositeType. For
|
||||
* DSTU2 it would extend BaseIdentifiableElement and implement ICompositeDatatype.
|
||||
*/
|
||||
@DatatypeDef(name="CustomDatatype")
|
||||
public class CustomDatatype extends Type implements ICompositeType {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Child(name = "date", order = 0, min = 1, max = 1)
|
||||
private DateTimeType myDate;
|
||||
|
||||
@Child(name = "kittens", order = 1, min = 1, max = 1)
|
||||
private StringType myKittens;
|
||||
|
||||
public DateTimeType getDate() {
|
||||
if (myDate == null)
|
||||
myDate = new DateTimeType();
|
||||
return myDate;
|
||||
}
|
||||
|
||||
public StringType getKittens() {
|
||||
return myKittens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return ElementUtil.isEmpty(myDate, myKittens);
|
||||
}
|
||||
|
||||
public CustomDatatype setDate(DateTimeType theValue) {
|
||||
myDate = theValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CustomDatatype setKittens(StringType theKittens) {
|
||||
myKittens = theKittens;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CustomDatatype typedCopy() {
|
||||
CustomDatatype retVal = new CustomDatatype();
|
||||
super.copyValues(retVal);
|
||||
retVal.myDate = myDate;
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
//END SNIPPET: datatype
|
|
@ -1,86 +0,0 @@
|
|||
package example.customtype;
|
||||
|
||||
// START SNIPPET: resource
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.DomainResource;
|
||||
import org.hl7.fhir.dstu3.model.ResourceType;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.dstu3.model.Type;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
* This is an example of a custom resource that also uses a custom
|
||||
* datatype.
|
||||
*
|
||||
* Note that we are extensing DomainResource for an STU3
|
||||
* resource. For DSTU2 it would be BaseResource.
|
||||
*/
|
||||
@ResourceDef(name = "CustomResource", profile = "http://hl7.org/fhir/profiles/custom-resource")
|
||||
public class CustomResource extends DomainResource {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* We give the resource a field with name "television". This field has no
|
||||
* specific type, so it's a choice[x] field for any type.
|
||||
*/
|
||||
@Child(name="television", min=1, max=Child.MAX_UNLIMITED, order=0)
|
||||
private List<Type> myTelevision;
|
||||
|
||||
/**
|
||||
* We'll give it one more field called "dogs"
|
||||
*/
|
||||
@Child(name = "dogs", min=0, max=1, order=1)
|
||||
private StringType myDogs;
|
||||
|
||||
@Override
|
||||
public CustomResource copy() {
|
||||
CustomResource retVal = new CustomResource();
|
||||
super.copyValues(retVal);
|
||||
retVal.myTelevision = myTelevision;
|
||||
retVal.myDogs = myDogs;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public List<Type> getTelevision() {
|
||||
if (myTelevision == null) {
|
||||
myTelevision = new ArrayList<Type>();
|
||||
}
|
||||
return myTelevision;
|
||||
}
|
||||
|
||||
public StringType getDogs() {
|
||||
return myDogs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceType getResourceType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FhirVersionEnum getStructureFhirVersionEnum() {
|
||||
return FhirVersionEnum.DSTU3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return ElementUtil.isEmpty(myTelevision, myDogs);
|
||||
}
|
||||
|
||||
public void setTelevision(List<Type> theValue) {
|
||||
this.myTelevision = theValue;
|
||||
}
|
||||
|
||||
public void setDogs(StringType theDogs) {
|
||||
myDogs = theDogs;
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: resource
|
|
@ -1,44 +0,0 @@
|
|||
package example.customtype;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.DateTimeType;
|
||||
import org.hl7.fhir.dstu3.model.DateType;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
public class CustomUsage {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// START SNIPPET: usage
|
||||
// Create a context. Note that we declare the custom types we'll be using
|
||||
// on the context before actually using them
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
ctx.registerCustomType(CustomResource.class);
|
||||
ctx.registerCustomType(CustomDatatype.class);
|
||||
|
||||
// Now let's create an instance of our custom resource type
|
||||
// and populate it with some data
|
||||
CustomResource res = new CustomResource();
|
||||
|
||||
// Add some values, including our custom datatype
|
||||
DateType value0 = new DateType("2015-01-01");
|
||||
res.getTelevision().add(value0);
|
||||
|
||||
CustomDatatype value1 = new CustomDatatype();
|
||||
value1.setDate(new DateTimeType(new Date()));
|
||||
value1.setKittens(new StringType("FOO"));
|
||||
res.getTelevision().add(value1);
|
||||
|
||||
res.setDogs(new StringType("Some Dogs"));
|
||||
|
||||
// Now let's serialize our instance
|
||||
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(res);
|
||||
System.out.println(output);
|
||||
// END SNIPPET: usage
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package example.interceptor;
|
||||
|
||||
import ca.uhn.fhir.interceptor.api.Hook;
|
||||
import ca.uhn.fhir.interceptor.api.Interceptor;
|
||||
import ca.uhn.fhir.interceptor.api.Pointcut;
|
||||
import ca.uhn.fhir.jpa.subscription.module.CanonicalSubscription;
|
||||
import ca.uhn.fhir.jpa.subscription.module.subscriber.ResourceDeliveryMessage;
|
||||
|
||||
/**
|
||||
* Interceptor class
|
||||
*/
|
||||
@Interceptor
|
||||
public class MyTestInterceptor {
|
||||
|
||||
@Hook(Pointcut.SUBSCRIPTION_BEFORE_REST_HOOK_DELIVERY)
|
||||
public boolean beforeRestHookDelivery(ResourceDeliveryMessage theDeliveryMessage, CanonicalSubscription theSubscription) {
|
||||
|
||||
String header = "Authorization: Bearer 1234567";
|
||||
|
||||
theSubscription.addHeader(header);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<configuration scan="true" scanPeriod="30 seconds">
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -181,7 +181,16 @@
|
|||
</reports>
|
||||
<configuration>
|
||||
<links>
|
||||
<link>http://jamesagnew.github.io/hapi-fhir/apidocs/</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-base</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-dstu2</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-dstu3</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-r4</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-r5</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-client</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-server</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-jpaserver-base</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-converter</link>
|
||||
<link>https://hapifhir.io/hapi-fhir/apidocs/hapi-fhir-structures-validation</link>
|
||||
<link>https://docs.oracle.com/javaee/7/api/</link>
|
||||
</links>
|
||||
<additionalparam>-Xdoclint:none</additionalparam>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.android;
|
|||
* #%L
|
||||
* HAPI FHIR - Android
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-deployable-pom</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<version>5.0.0-SNAPSHOT</version>
|
||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
|||
|
||||
<!-- JSON -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- XML -->
|
||||
|
@ -206,65 +206,4 @@
|
|||
</resources>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>MINI</id>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>SITE</id>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<reportSets> <reportSet> <reports> <report>checkstyle</report> </reports>
|
||||
</reportSet> </reportSets> <configuration> <linkXRef>false</linkXRef> <sourceDirectories>
|
||||
<sourceDirectory>hapi-fhir-base/src/main/java</sourceDirectory> </sourceDirectories>
|
||||
</configuration> </plugin> -->
|
||||
<!--<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId>
|
||||
<version>3.0.0</version> <configuration> </configuration> </plugin> -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jxr-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<id>normal</id>
|
||||
<reports>
|
||||
<report>jxr</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
<!-- <reportSet> <id>restful-server-example</id> <reports> <report>jxr</report>
|
||||
</reports> <configuration> <sourcePath>../restful-server-example/src/main/java</sourcePath>
|
||||
<destDir>${project.reporting.outputDirectory}/rse-xref</destDir> <outputDirectory>tmp</outputDirectory>
|
||||
<reportOutputDirectory>rse-xref</reportOutputDirectory> </configuration>
|
||||
</reportSet> -->
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-linkcheck-plugin</artifactId>
|
||||
<version>1.1</version> <configuration> <forceSite>false</forceSite> </configuration>
|
||||
</plugin> -->
|
||||
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<report>checkstyle</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
<configuration>
|
||||
<linkXRef>false</linkXRef>
|
||||
<configLocation>${project.basedir}/../src/checkstyle/checkstyle.xml</configLocation>
|
||||
<!--<sourceDirectories> <sourceDirectory> ${project.basedir}/../hapi-fhir-base/src/main/java
|
||||
</sourceDirectory> </sourceDirectories> -->
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
</reporting>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -31,6 +31,8 @@ import org.hl7.fhir.instance.model.api.IBaseReference;
|
|||
|
||||
public abstract class BaseRuntimeChildDefinition {
|
||||
|
||||
private BaseRuntimeChildDefinition myReplacedParentDefinition;
|
||||
|
||||
public abstract IAccessor getAccessor();
|
||||
|
||||
public abstract BaseRuntimeElementDefinition<?> getChildByName(String theName);
|
||||
|
@ -66,6 +68,14 @@ public abstract class BaseRuntimeChildDefinition {
|
|||
return getClass().getSimpleName() + "[" + getElementName() + "]";
|
||||
}
|
||||
|
||||
public BaseRuntimeChildDefinition getReplacedParentDefinition() {
|
||||
return myReplacedParentDefinition;
|
||||
}
|
||||
|
||||
public void setReplacedParentDefinition(BaseRuntimeChildDefinition myReplacedParentDefinition) {
|
||||
this.myReplacedParentDefinition = myReplacedParentDefinition;
|
||||
}
|
||||
|
||||
public interface IAccessor {
|
||||
List<IBase> getValues(IBase theTarget);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.lang.reflect.Modifier;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -263,6 +263,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
int order = childAnnotation.order();
|
||||
boolean childIsChoiceType = false;
|
||||
boolean orderIsReplaceParent = false;
|
||||
BaseRuntimeChildDefinition replacedParent = null;
|
||||
|
||||
if (order == Child.REPLACE_PARENT) {
|
||||
|
||||
|
@ -274,7 +275,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
if (nextDef.getExtensionUrl().equals(extensionAttr.url())) {
|
||||
orderIsReplaceParent = true;
|
||||
order = nextEntry.getKey();
|
||||
orderMap.remove(nextEntry.getKey());
|
||||
replacedParent = orderMap.remove(nextEntry.getKey());
|
||||
elementNames.remove(elementName);
|
||||
break;
|
||||
}
|
||||
|
@ -293,6 +294,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
orderIsReplaceParent = true;
|
||||
order = nextEntry.getKey();
|
||||
BaseRuntimeDeclaredChildDefinition existing = orderMap.remove(nextEntry.getKey());
|
||||
replacedParent = existing;
|
||||
elementNames.remove(elementName);
|
||||
|
||||
/*
|
||||
|
@ -450,6 +452,7 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
|
|||
|
||||
}
|
||||
|
||||
def.setReplacedParentDefinition(replacedParent);
|
||||
orderMap.put(order, def);
|
||||
elementNames.add(elementName);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,8 +22,11 @@ package ca.uhn.fhir.context;
|
|||
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -33,11 +36,11 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
|||
private final Class<? extends T> myImplementingClass;
|
||||
private final String myName;
|
||||
private final boolean myStandardType;
|
||||
private Map<Class<?>, Constructor<T>> myConstructors = Collections.synchronizedMap(new HashMap<Class<?>, Constructor<T>>());
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensions = new ArrayList<RuntimeChildDeclaredExtensionDefinition>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsModifier = new ArrayList<RuntimeChildDeclaredExtensionDefinition>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsNonModifier = new ArrayList<RuntimeChildDeclaredExtensionDefinition>();
|
||||
private Map<String, RuntimeChildDeclaredExtensionDefinition> myUrlToExtension = new HashMap<String, RuntimeChildDeclaredExtensionDefinition>();
|
||||
private Map<Class<?>, Constructor<T>> myConstructors = Collections.synchronizedMap(new HashMap<>());
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensions = new ArrayList<>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsModifier = new ArrayList<>();
|
||||
private List<RuntimeChildDeclaredExtensionDefinition> myExtensionsNonModifier = new ArrayList<>();
|
||||
private Map<String, RuntimeChildDeclaredExtensionDefinition> myUrlToExtension = new HashMap<>();
|
||||
private BaseRuntimeElementDefinition<?> myRootParentDefinition;
|
||||
|
||||
public BaseRuntimeElementDefinition(String theName, Class<? extends T> theImplementingClass, boolean theStandardType) {
|
||||
|
@ -56,19 +59,17 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
|
|||
myImplementingClass = theImplementingClass;
|
||||
}
|
||||
|
||||
public void addExtension(RuntimeChildDeclaredExtensionDefinition theExtension) {
|
||||
if (theExtension == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
public void addExtension(@Nonnull RuntimeChildDeclaredExtensionDefinition theExtension) {
|
||||
Validate.notNull(theExtension, "theExtension must not be null");
|
||||
myExtensions.add(theExtension);
|
||||
}
|
||||
|
||||
public abstract ChildTypeEnum getChildType();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Constructor<T> getConstructor(Object theArgument) {
|
||||
private Constructor<T> getConstructor(@Nullable Object theArgument) {
|
||||
|
||||
Class<? extends Object> argumentType;
|
||||
Class<?> argumentType;
|
||||
if (theArgument == null) {
|
||||
argumentType = VOID_CLASS;
|
||||
} else {
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
import ca.uhn.fhir.context.api.AddProfileTagEnum;
|
||||
import ca.uhn.fhir.context.support.IContextValidationSupport;
|
||||
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.fluentpath.IFluentPath;
|
||||
import ca.uhn.fhir.i18n.HapiLocalizer;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
|
@ -9,7 +10,13 @@ import ca.uhn.fhir.model.api.IFhirVersion;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.view.ViewGenerator;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.parser.*;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler;
|
||||
import ca.uhn.fhir.parser.JsonParser;
|
||||
import ca.uhn.fhir.parser.LenientErrorHandler;
|
||||
import ca.uhn.fhir.parser.RDFParser;
|
||||
import ca.uhn.fhir.parser.XmlParser;
|
||||
import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
@ -20,7 +27,6 @@ import ca.uhn.fhir.util.ReflectionUtil;
|
|||
import ca.uhn.fhir.util.VersionUtil;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.jena.riot.Lang;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
|
@ -37,7 +43,7 @@ import java.util.Map.Entry;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -97,7 +103,7 @@ public class FhirContext {
|
|||
private Collection<Class<? extends IBaseResource>> myResourceTypesToScan;
|
||||
private volatile IRestfulClientFactory myRestfulClientFactory;
|
||||
private volatile RuntimeChildUndeclaredExtensionDefinition myRuntimeChildUndeclaredExtensionDefinition;
|
||||
private IContextValidationSupport<?, ?, ?, ?, ?, ?> myValidationSupport;
|
||||
private IValidationSupport myValidationSupport;
|
||||
private Map<FhirVersionEnum, Map<String, Class<? extends IBaseResource>>> myVersionToNameToResourceType = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
|
@ -371,15 +377,27 @@ public class FhirContext {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configured performance options
|
||||
*
|
||||
* @see PerformanceOptionsEnum for a list of available options
|
||||
*/
|
||||
public void setPerformanceOptions(final PerformanceOptionsEnum... thePerformanceOptions) {
|
||||
Collection<PerformanceOptionsEnum> asList = null;
|
||||
if (thePerformanceOptions != null) {
|
||||
asList = Arrays.asList(thePerformanceOptions);
|
||||
}
|
||||
setPerformanceOptions(asList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
|
||||
* for extending the core library.
|
||||
*/
|
||||
public RuntimeResourceDefinition getResourceDefinition(final Class<? extends IBaseResource> theResourceType) {
|
||||
validateInitialized();
|
||||
if (theResourceType == null) {
|
||||
throw new NullPointerException("theResourceType can not be null");
|
||||
}
|
||||
Validate.notNull(theResourceType, "theResourceType can not be null");
|
||||
|
||||
if (Modifier.isAbstract(theResourceType.getModifiers())) {
|
||||
throw new IllegalArgumentException("Can not scan abstract or interface class (resource definitions must be concrete classes): " + theResourceType.getName());
|
||||
}
|
||||
|
@ -544,16 +562,37 @@ public class FhirContext {
|
|||
|
||||
/**
|
||||
* Returns the validation support module configured for this context, creating a default
|
||||
* implementation if no module has been passed in via the {@link #setValidationSupport(IContextValidationSupport)}
|
||||
* implementation if no module has been passed in via the {@link #setValidationSupport(IValidationSupport)}
|
||||
* method
|
||||
*
|
||||
* @see #setValidationSupport(IContextValidationSupport)
|
||||
* @see #setValidationSupport(IValidationSupport)
|
||||
*/
|
||||
public IContextValidationSupport<?, ?, ?, ?, ?, ?> getValidationSupport() {
|
||||
if (myValidationSupport == null) {
|
||||
myValidationSupport = myVersion.createValidationSupport();
|
||||
public IValidationSupport getValidationSupport() {
|
||||
IValidationSupport retVal = myValidationSupport;
|
||||
if (retVal == null) {
|
||||
retVal = new DefaultProfileValidationSupport(this);
|
||||
|
||||
/*
|
||||
* If hapi-fhir-validation is on the classpath, we can create a much more robust
|
||||
* validation chain using the classes found in that package
|
||||
*/
|
||||
String inMemoryTermSvcType = "org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport";
|
||||
String commonCodeSystemsSupportType = "org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService";
|
||||
if (ReflectionUtil.typeExists(inMemoryTermSvcType)) {
|
||||
IValidationSupport inMemoryTermSvc = ReflectionUtil.newInstanceOrReturnNull(inMemoryTermSvcType, IValidationSupport.class, new Class<?>[]{FhirContext.class}, new Object[]{this});
|
||||
IValidationSupport commonCodeSystemsSupport = ReflectionUtil.newInstanceOrReturnNull(commonCodeSystemsSupportType, IValidationSupport.class, new Class<?>[]{FhirContext.class}, new Object[]{this});
|
||||
retVal = ReflectionUtil.newInstanceOrReturnNull("org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain", IValidationSupport.class, new Class<?>[]{IValidationSupport[].class}, new Object[]{new IValidationSupport[]{
|
||||
retVal,
|
||||
inMemoryTermSvc,
|
||||
commonCodeSystemsSupport
|
||||
}});
|
||||
assert retVal != null : "Failed to instantiate " + "org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain";
|
||||
}
|
||||
|
||||
|
||||
myValidationSupport = retVal;
|
||||
}
|
||||
return myValidationSupport;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -561,7 +600,7 @@ public class FhirContext {
|
|||
* is used to supply underlying infrastructure such as conformance resources (StructureDefinition, ValueSet, etc)
|
||||
* as well as to provide terminology services to modules such as the validator and FluentPath executor
|
||||
*/
|
||||
public void setValidationSupport(IContextValidationSupport<?, ?, ?, ?, ?, ?> theValidationSupport) {
|
||||
public void setValidationSupport(IValidationSupport theValidationSupport) {
|
||||
myValidationSupport = theValidationSupport;
|
||||
}
|
||||
|
||||
|
@ -588,10 +627,10 @@ public class FhirContext {
|
|||
/**
|
||||
* Creates a new FluentPath engine which can be used to exvaluate
|
||||
* path expressions over FHIR resources. Note that this engine will use the
|
||||
* {@link IContextValidationSupport context validation support} module which is
|
||||
* {@link IValidationSupport context validation support} module which is
|
||||
* configured on the context at the time this method is called.
|
||||
* <p>
|
||||
* In other words, call {@link #setValidationSupport(IContextValidationSupport)} before
|
||||
* In other words, call {@link #setValidationSupport(IValidationSupport)} before
|
||||
* calling {@link #newFluentPath()}
|
||||
* </p>
|
||||
* <p>
|
||||
|
@ -642,7 +681,6 @@ public class FhirContext {
|
|||
return new RDFParser(this, myParserErrorHandler, Lang.TURTLE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new client instance. This method requires an interface which is defined specifically for your use
|
||||
* cases to contain methods for each of the RESTful operations you wish to implement (e.g. "read ImagingStudy",
|
||||
|
@ -862,19 +900,6 @@ public class FhirContext {
|
|||
myParserErrorHandler = theParserErrorHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configured performance options
|
||||
*
|
||||
* @see PerformanceOptionsEnum for a list of available options
|
||||
*/
|
||||
public void setPerformanceOptions(final PerformanceOptionsEnum... thePerformanceOptions) {
|
||||
Collection<PerformanceOptionsEnum> asList = null;
|
||||
if (thePerformanceOptions != null) {
|
||||
asList = Arrays.asList(thePerformanceOptions);
|
||||
}
|
||||
setPerformanceOptions(asList);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"cast"})
|
||||
private List<Class<? extends IElement>> toElementList(final Collection<Class<? extends IBaseResource>> theResourceTypes) {
|
||||
if (theResourceTypes == null) {
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -190,7 +190,7 @@ public enum FhirVersionEnum {
|
|||
Class<?> c = Class.forName("org.hl7.fhir.dstu3.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
} catch (Exception e) {
|
||||
myVersion = "3.0.1";
|
||||
myVersion = "3.0.2";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ public enum FhirVersionEnum {
|
|||
Class<?> c = Class.forName("org.hl7.fhir.r4.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
} catch (Exception e) {
|
||||
myVersion = "4.0.0";
|
||||
myVersion = "4.0.2";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -4,7 +4,7 @@ package ca.uhn.fhir.context;
|
|||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2019 University Health Network
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue